Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2098 } | 2098 } |
| 2099 // Optionally parse a (possibly named) constructor name or factory. | 2099 // Optionally parse a (possibly named) constructor name or factory. |
| 2100 if ((CurrentToken() == Token::kIDENT) && | 2100 if ((CurrentToken() == Token::kIDENT) && |
| 2101 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 2101 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 2102 member.name = CurrentLiteral(); | 2102 member.name = CurrentLiteral(); |
| 2103 member.name_pos = this->token_index_; | 2103 member.name_pos = this->token_index_; |
| 2104 // Factory result type is the same as the type name of the factory. | 2104 // Factory result type is the same as the type name of the factory. |
| 2105 // TODO(srdjan): Implement checks in class finalization when all types have | 2105 // TODO(srdjan): Implement checks in class finalization when all types have |
| 2106 // been resolved. | 2106 // been resolved. |
| 2107 if (member.has_factory && !member.name->Equals(members->class_name())) { | 2107 if (member.has_factory && !member.name->Equals(members->class_name())) { |
| 2108 const TypeArguments& arguments = TypeArguments::Handle(); | 2108 const UnresolvedClass& type = |
| 2109 member.type = &Type::ZoneHandle( | 2109 UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos, |
| 2110 Type::NewParameterizedType(*member.name, arguments)); | 2110 String::Handle(), |
| 2111 *(member.name))); | |
| 2112 const TypeArguments& args = TypeArguments::Handle(); | |
| 2113 member.type = &Type::ZoneHandle(Type::NewParameterizedType(type, args)); | |
| 2111 } | 2114 } |
| 2112 ConsumeToken(); | 2115 ConsumeToken(); |
| 2113 // We must be dealing with a constructor or named constructor. | 2116 // We must be dealing with a constructor or named constructor. |
| 2114 member.kind = RawFunction::kConstructor; | 2117 member.kind = RawFunction::kConstructor; |
| 2115 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); | 2118 String& ctor_suffix = String::ZoneHandle(String::NewSymbol(".")); |
| 2116 if (CurrentToken() == Token::kPERIOD) { | 2119 if (CurrentToken() == Token::kPERIOD) { |
| 2117 // Named constructor. | 2120 // Named constructor. |
| 2118 ConsumeToken(); | 2121 ConsumeToken(); |
| 2119 const String* name = ExpectIdentifier("identifier expected"); | 2122 const String* name = ExpectIdentifier("identifier expected"); |
| 2120 ctor_suffix = String::Concat(ctor_suffix, *name); | 2123 ctor_suffix = String::Concat(ctor_suffix, *name); |
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3479 int nesting_level = 0; | 3482 int nesting_level = 0; |
| 3480 do { | 3483 do { |
| 3481 if (CurrentToken() == Token::kLT) { | 3484 if (CurrentToken() == Token::kLT) { |
| 3482 nesting_level++; | 3485 nesting_level++; |
| 3483 } else if (CurrentToken() == Token::kGT) { | 3486 } else if (CurrentToken() == Token::kGT) { |
| 3484 nesting_level--; | 3487 nesting_level--; |
| 3485 } else if (CurrentToken() == Token::kSAR) { | 3488 } else if (CurrentToken() == Token::kSAR) { |
| 3486 nesting_level -= 2; | 3489 nesting_level -= 2; |
| 3487 } else if (CurrentToken() == Token::kSHR) { | 3490 } else if (CurrentToken() == Token::kSHR) { |
| 3488 nesting_level -= 3; | 3491 nesting_level -= 3; |
| 3492 } else if (CurrentToken() == Token::kIDENT) { | |
| 3493 // Check to see if it is a qualified identifier. | |
| 3494 if (LookaheadToken(1) == Token::kPERIOD) { | |
| 3495 // Consume the identifier, the period will be consumed below. | |
| 3496 ConsumeToken(); | |
| 3497 } | |
| 3489 } else if (CurrentToken() != Token::kCOMMA && | 3498 } else if (CurrentToken() != Token::kCOMMA && |
| 3490 CurrentToken() != Token::kIDENT && | |
| 3491 CurrentToken() != Token::kEXTENDS) { | 3499 CurrentToken() != Token::kEXTENDS) { |
| 3492 // We are looking at something other than type parameters. | 3500 // We are looking at something other than type parameters. |
| 3493 return false; | 3501 return false; |
| 3494 } | 3502 } |
| 3495 ConsumeToken(); | 3503 ConsumeToken(); |
| 3496 } while (nesting_level > 0); | 3504 } while (nesting_level > 0); |
| 3497 if (nesting_level < 0) { | 3505 if (nesting_level < 0) { |
| 3498 return false; | 3506 return false; |
| 3499 } | 3507 } |
| 3500 } | 3508 } |
| (...skipping 2062 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5563 return postfix_expr; | 5571 return postfix_expr; |
| 5564 } | 5572 } |
| 5565 | 5573 |
| 5566 | 5574 |
| 5567 bool Parser::ResolveTypeFromClass(intptr_t type_pos, | 5575 bool Parser::ResolveTypeFromClass(intptr_t type_pos, |
| 5568 const Class& cls, | 5576 const Class& cls, |
| 5569 Type* type) { | 5577 Type* type) { |
| 5570 ASSERT(type != NULL); | 5578 ASSERT(type != NULL); |
| 5571 // Resolve class. | 5579 // Resolve class. |
| 5572 if (!type->HasResolvedTypeClass()) { | 5580 if (!type->HasResolvedTypeClass()) { |
| 5573 const String& unresolved_type_class = | 5581 const UnresolvedClass& unresolved_class = |
| 5574 String::Handle(type->unresolved_type_class()); | 5582 UnresolvedClass::Handle(type->unresolved_class()); |
| 5583 const String& unresolved_class_name = | |
| 5584 String::Handle(unresolved_class.ident()); | |
| 5575 // First check if the type is a type parameter of the given class. | 5585 // First check if the type is a type parameter of the given class. |
| 5576 const TypeParameter& type_parameter = TypeParameter::Handle( | 5586 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 5577 cls.LookupTypeParameter(unresolved_type_class)); | 5587 cls.LookupTypeParameter(unresolved_class_name)); |
| 5578 if (!type_parameter.IsNull()) { | 5588 if (!type_parameter.IsNull()) { |
| 5579 CheckTypeParameterReference(type_pos, unresolved_type_class); | 5589 CheckTypeParameterReference(type_pos, unresolved_class_name); |
| 5580 // A type parameter cannot be parameterized, so report an error if type | 5590 // A type parameter cannot be parameterized, so report an error if type |
| 5581 // arguments have previously been parsed. | 5591 // arguments have previously been parsed. |
| 5582 if (type->arguments() != TypeArguments::null()) { | 5592 if (type->arguments() != TypeArguments::null()) { |
| 5583 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", | 5593 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", |
| 5584 type_parameter.ToCString()); | 5594 type_parameter.ToCString()); |
| 5585 return false; | 5595 return false; |
| 5586 } | 5596 } |
| 5587 *type = type_parameter.raw(); | 5597 *type = type_parameter.raw(); |
| 5588 return true; | 5598 return true; |
| 5589 } | 5599 } |
| 5590 const Class& resolved_type_class = | 5600 const Class& resolved_type_class = |
| 5591 Class::Handle(LookupClass(unresolved_type_class)); | 5601 Class::Handle(LookupClass(unresolved_class_name)); |
| 5592 if (resolved_type_class.IsNull()) { | 5602 if (resolved_type_class.IsNull()) { |
| 5593 return false; | 5603 return false; |
| 5594 } | 5604 } |
| 5595 Object& type_class = Object::Handle(resolved_type_class.raw()); | 5605 Object& type_class = Object::Handle(resolved_type_class.raw()); |
| 5596 ASSERT(type->IsParameterizedType()); | 5606 ASSERT(type->IsParameterizedType()); |
| 5597 // Replace unresolved type class with resolved type class. | 5607 // Replace unresolved class with resolved type class. |
| 5598 ParameterizedType& parameterized_type = ParameterizedType::Handle(); | 5608 ParameterizedType& parameterized_type = ParameterizedType::Handle(); |
| 5599 parameterized_type ^= type->raw(); | 5609 parameterized_type ^= type->raw(); |
| 5600 parameterized_type.set_type_class(type_class); | 5610 parameterized_type.set_type_class(type_class); |
| 5601 } | 5611 } |
| 5602 // Resolve type arguments, if any. | 5612 // Resolve type arguments, if any. |
| 5603 const TypeArguments& arguments = TypeArguments::Handle(type->arguments()); | 5613 const TypeArguments& arguments = TypeArguments::Handle(type->arguments()); |
| 5604 if (!arguments.IsNull()) { | 5614 if (!arguments.IsNull()) { |
| 5605 intptr_t num_arguments = arguments.Length(); | 5615 intptr_t num_arguments = arguments.Length(); |
| 5606 for (intptr_t i = 0; i < num_arguments; i++) { | 5616 for (intptr_t i = 0; i < num_arguments; i++) { |
| 5607 Type& type_argument = Type::Handle(arguments.TypeAt(i)); | 5617 Type& type_argument = Type::Handle(arguments.TypeAt(i)); |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6009 ErrorMsg("type name expected"); | 6019 ErrorMsg("type name expected"); |
| 6010 } | 6020 } |
| 6011 QualIdent type_name; | 6021 QualIdent type_name; |
| 6012 intptr_t type_pos = token_index_; | 6022 intptr_t type_pos = token_index_; |
| 6013 ParseQualIdent(&type_name); | 6023 ParseQualIdent(&type_name); |
| 6014 if (type_name.local_scope_ident) { | 6024 if (type_name.local_scope_ident) { |
| 6015 ErrorMsg(type_pos, "Using '%s' in this context is invalid", | 6025 ErrorMsg(type_pos, "Using '%s' in this context is invalid", |
| 6016 type_name.ident->ToCString()); | 6026 type_name.ident->ToCString()); |
| 6017 } | 6027 } |
| 6018 Object& type_class = Object::Handle(); | 6028 Object& type_class = Object::Handle(); |
| 6029 String& qualifier = String::Handle(); | |
| 6030 if (type_name.qualifier != NULL) { | |
| 6031 qualifier ^= type_name.qualifier->raw(); | |
| 6032 } | |
| 6019 if (type_resolution == kDoNotResolve) { | 6033 if (type_resolution == kDoNotResolve) { |
| 6020 // TODO(5072252): Figure out what should be done in this case. | 6034 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); |
| 6021 if (type_name.qualifier != NULL) { | |
| 6022 Unimplemented("cannot handle qualified type names yet"); | |
| 6023 } | |
| 6024 type_class = type_name.ident->raw(); | |
| 6025 } else { | 6035 } else { |
| 6026 TypeParameter& type_parameter = TypeParameter::Handle(); | 6036 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 6027 // Check if qualifier is a type parameter of the class we are parsing. | 6037 // Check if qualifier is a type parameter of the class we are parsing. |
| 6028 if (type_name.qualifier != NULL) { | 6038 if (type_name.qualifier != NULL) { |
| 6029 type_parameter = | 6039 type_parameter = |
| 6030 current_class().LookupTypeParameter(*type_name.qualifier); | 6040 current_class().LookupTypeParameter(*type_name.qualifier); |
| 6031 if (!type_parameter.IsNull()) { | 6041 if (!type_parameter.IsNull()) { |
| 6032 ErrorMsg(type_pos, "Use of '%s' in this context is invalid", | 6042 ErrorMsg(type_pos, "Use of '%s' in this context is invalid", |
| 6033 type_name.qualifier->ToCString()); | 6043 type_name.qualifier->ToCString()); |
| 6034 } | 6044 } |
| 6035 } else { | 6045 } else { |
| 6036 // Check if ident is a type parameter of the class we are parsing. | 6046 // Check if ident is a type parameter of the class we are parsing. |
| 6037 type_parameter = current_class().LookupTypeParameter(*type_name.ident); | 6047 type_parameter = current_class().LookupTypeParameter(*type_name.ident); |
| 6038 if (!type_parameter.IsNull()) { | 6048 if (!type_parameter.IsNull()) { |
| 6039 CheckTypeParameterReference(type_name.ident_pos, *type_name.ident); | 6049 CheckTypeParameterReference(type_name.ident_pos, *type_name.ident); |
| 6040 if (CurrentToken() == Token::kLT) { | 6050 if (CurrentToken() == Token::kLT) { |
| 6041 // A type parameter cannot be parameterized. | 6051 // A type parameter cannot be parameterized. |
| 6042 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", | 6052 ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized", |
| 6043 String::Handle(type_parameter.Name()).ToCString()); | 6053 String::Handle(type_parameter.Name()).ToCString()); |
| 6044 } | 6054 } |
| 6045 return type_parameter.raw(); | 6055 return type_parameter.raw(); |
| 6046 } | 6056 } |
| 6047 } | 6057 } |
| 6048 // Try to resolve the type class. | 6058 // Try to resolve the type class. |
| 6049 type_class = LookupTypeClass(type_name, type_resolution); | 6059 type_class = LookupTypeClass(type_name, type_resolution); |
| 6060 if (!type_class.IsClass()) { | |
| 6061 // We have an unresolved name, create an UnresolvedClass object | |
| 6062 // for this case. | |
| 6063 type_class = UnresolvedClass::New(type_pos, | |
| 6064 qualifier, | |
| 6065 *(type_name.ident)); | |
| 6066 } | |
|
regis
2011/10/13 17:23:03
Why not move the creation of the unresolved class
siva
2011/10/13 20:06:39
Good idea, Done.
On 2011/10/13 17:23:03, regis wr
| |
| 6050 } | 6067 } |
| 6051 TypeArguments& type_arguments = | 6068 TypeArguments& type_arguments = |
| 6052 TypeArguments::Handle(ParseTypeArguments(type_resolution)); | 6069 TypeArguments::Handle(ParseTypeArguments(type_resolution)); |
| 6053 const Type& type = Type::Handle( | 6070 const Type& type = Type::Handle( |
| 6054 Type::NewParameterizedType(type_class, type_arguments)); | 6071 Type::NewParameterizedType(type_class, type_arguments)); |
| 6055 if (type_resolution == kMustResolve) { | 6072 if (type_resolution == kMustResolve) { |
| 6073 ASSERT(type_class.IsClass()); // Must be resolved. | |
| 6056 const String& errmsg = String::Handle( | 6074 const String& errmsg = String::Handle( |
| 6057 ClassFinalizer::FinalizeTypeWhileParsing(type)); | 6075 ClassFinalizer::FinalizeTypeWhileParsing(type)); |
| 6058 if (!errmsg.IsNull()) { | 6076 if (!errmsg.IsNull()) { |
| 6059 ErrorMsg(errmsg.ToCString()); | 6077 ErrorMsg(errmsg.ToCString()); |
| 6060 } | 6078 } |
| 6061 } | 6079 } |
| 6062 return type.raw(); | 6080 return type.raw(); |
| 6063 } | 6081 } |
| 6064 | 6082 |
| 6065 | 6083 |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6420 | 6438 |
| 6421 // TODO(srdjan): Evaluate if the mapping should occur during code | 6439 // TODO(srdjan): Evaluate if the mapping should occur during code |
| 6422 // generation or here in the parser. | 6440 // generation or here in the parser. |
| 6423 const Type& factory_type = Type::Handle(type_class.factory_type()); | 6441 const Type& factory_type = Type::Handle(type_class.factory_type()); |
| 6424 if (factory_type.IsNull()) { | 6442 if (factory_type.IsNull()) { |
| 6425 ErrorMsg("cannot allocate interface '%s' without factory class", | 6443 ErrorMsg("cannot allocate interface '%s' without factory class", |
| 6426 type_class_name.ToCString()); | 6444 type_class_name.ToCString()); |
| 6427 } | 6445 } |
| 6428 if (!factory_type.HasResolvedTypeClass()) { | 6446 if (!factory_type.HasResolvedTypeClass()) { |
| 6429 // This error can occur only with bootstrap classes. | 6447 // This error can occur only with bootstrap classes. |
| 6430 const String& missing_class_name = | 6448 const UnresolvedClass& unresolved = |
| 6431 String::Handle(factory_type.unresolved_type_class()); | 6449 UnresolvedClass::Handle(factory_type.unresolved_class()); |
| 6432 ErrorMsg("Unresolved factory class '%s'", | 6450 const String& missing_class_name = String::Handle(unresolved.ident()); |
| 6433 missing_class_name.ToCString()); | 6451 ErrorMsg("Unresolved factory class '%s'", missing_class_name.ToCString()); |
| 6434 } | 6452 } |
| 6435 | 6453 |
| 6436 // Only change the class of the constructor to the factory class if the | 6454 // Only change the class of the constructor to the factory class if the |
| 6437 // factory class implements the interface 'type'. | 6455 // factory class implements the interface 'type'. |
| 6438 Class& factory_type_class = Class::Handle(factory_type.type_class()); | 6456 Class& factory_type_class = Class::Handle(factory_type.type_class()); |
| 6439 // TODO(regis): Verify in the guide/spec that a factory class must have | 6457 // TODO(regis): Verify in the guide/spec that a factory class must have |
| 6440 // identical type parameters as the interface. | 6458 // identical type parameters as the interface. |
| 6441 // TODO(regis): Do we check that in the parser? | 6459 // TODO(regis): Do we check that in the parser? |
| 6442 // Assuming that it has been checked, it is sufficient to test if the | 6460 // Assuming that it has been checked, it is sufficient to test if the |
| 6443 // raw factory type implements the raw interface type. | 6461 // raw factory type implements the raw interface type. |
| (...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6982 } | 7000 } |
| 6983 | 7001 |
| 6984 | 7002 |
| 6985 void Parser::SkipNestedExpr() { | 7003 void Parser::SkipNestedExpr() { |
| 6986 const bool saved_mode = SetAllowFunctionLiterals(true); | 7004 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6987 SkipExpr(); | 7005 SkipExpr(); |
| 6988 SetAllowFunctionLiterals(saved_mode); | 7006 SetAllowFunctionLiterals(saved_mode); |
| 6989 } | 7007 } |
| 6990 | 7008 |
| 6991 } // namespace dart | 7009 } // namespace dart |
| OLD | NEW |