Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 3278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3289 library = Library::LookupLibrary(canon_url); | 3289 library = Library::LookupLibrary(canon_url); |
| 3290 if (library.IsNull()) { | 3290 if (library.IsNull()) { |
| 3291 library = Library::New(canon_url); | 3291 library = Library::New(canon_url); |
| 3292 library.Register(); | 3292 library.Register(); |
| 3293 } | 3293 } |
| 3294 } | 3294 } |
| 3295 // Add the import to the library. | 3295 // Add the import to the library. |
| 3296 if (prefix.IsNull() || (prefix.Length() == 0)) { | 3296 if (prefix.IsNull() || (prefix.Length() == 0)) { |
| 3297 library_.AddImport(library); | 3297 library_.AddImport(library); |
| 3298 } else { | 3298 } else { |
| 3299 if (library_.LookupLocalObject(prefix) != Object::null()) { | 3299 LibraryPrefix& library_prefix = LibraryPrefix::Handle(); |
| 3300 ErrorMsg(token_index_, "'%s' is already defined", prefix.ToCString()); | 3300 library_prefix = library_.LookupLocalLibraryPrefix(prefix); |
| 3301 if (!library_prefix.IsNull()) { | |
| 3302 library_prefix.AddLibrary(library); | |
| 3303 } else { | |
| 3304 library_prefix = LibraryPrefix::New(prefix, library); | |
| 3305 library_.AddObject(library_prefix, prefix); | |
| 3301 } | 3306 } |
| 3302 const LibraryPrefix& library_prefix = | |
| 3303 LibraryPrefix::Handle(LibraryPrefix::New(prefix, library)); | |
| 3304 library_.AddObject(library_prefix, prefix); | |
| 3305 } | 3307 } |
| 3306 } | 3308 } |
| 3307 } | 3309 } |
| 3308 | 3310 |
| 3309 | 3311 |
| 3310 void Parser::ParseLibraryInclude() { | 3312 void Parser::ParseLibraryInclude() { |
| 3311 const Array& import_map = Array::Handle(library_.import_map()); | 3313 const Array& import_map = Array::Handle(library_.import_map()); |
| 3312 while (CurrentToken() == Token::kSOURCE) { | 3314 while (CurrentToken() == Token::kSOURCE) { |
| 3313 const intptr_t source_pos = token_index_; | 3315 const intptr_t source_pos = token_index_; |
| 3314 ConsumeToken(); | 3316 ConsumeToken(); |
| (...skipping 2842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6157 ASSERT(type != NULL); | 6159 ASSERT(type != NULL); |
| 6158 if (type->IsResolved()) { | 6160 if (type->IsResolved()) { |
| 6159 return; | 6161 return; |
| 6160 } | 6162 } |
| 6161 // Resolve class. | 6163 // Resolve class. |
| 6162 if (!type->HasResolvedTypeClass()) { | 6164 if (!type->HasResolvedTypeClass()) { |
| 6163 const UnresolvedClass& unresolved_class = | 6165 const UnresolvedClass& unresolved_class = |
| 6164 UnresolvedClass::Handle(type->unresolved_class()); | 6166 UnresolvedClass::Handle(type->unresolved_class()); |
| 6165 const String& unresolved_class_name = | 6167 const String& unresolved_class_name = |
| 6166 String::Handle(unresolved_class.ident()); | 6168 String::Handle(unresolved_class.ident()); |
| 6167 Library& lib = Library::Handle(); | 6169 Class& resolved_type_class = Class::Handle(); |
| 6168 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 6170 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 6169 if (!scope_class.IsNull()) { | 6171 if (!scope_class.IsNull()) { |
| 6170 // First check if the type is a type parameter of the given scope class. | 6172 // First check if the type is a type parameter of the given scope class. |
| 6171 const TypeParameter& type_parameter = TypeParameter::Handle( | 6173 const TypeParameter& type_parameter = TypeParameter::Handle( |
| 6172 scope_class.LookupTypeParameter(unresolved_class_name, | 6174 scope_class.LookupTypeParameter(unresolved_class_name, |
| 6173 type->token_index())); | 6175 type->token_index())); |
| 6174 if (!type_parameter.IsNull()) { | 6176 if (!type_parameter.IsNull()) { |
| 6175 // A type parameter cannot be parameterized, so report an error if | 6177 // A type parameter cannot be parameterized, so report an error if |
| 6176 // type arguments have previously been parsed. | 6178 // type arguments have previously been parsed. |
| 6177 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { | 6179 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { |
| 6178 ErrorMsg(type_parameter.token_index(), | 6180 ErrorMsg(type_parameter.token_index(), |
| 6179 "type parameter '%s' cannot be parameterized", | 6181 "type parameter '%s' cannot be parameterized", |
| 6180 String::Handle(type_parameter.Name()).ToCString()); | 6182 String::Handle(type_parameter.Name()).ToCString()); |
| 6181 } | 6183 } |
| 6182 *type = type_parameter.raw(); | 6184 *type = type_parameter.raw(); |
| 6183 return; | 6185 return; |
| 6184 } | 6186 } |
| 6185 } | 6187 } |
| 6188 // Global lookup in current library. | |
| 6189 resolved_type_class = library_.LookupClass(unresolved_class_name); | |
| 6186 } else { | 6190 } else { |
| 6187 LibraryPrefix& lib_prefix = | 6191 LibraryPrefix& lib_prefix = |
| 6188 LibraryPrefix::Handle(unresolved_class.library_prefix()); | 6192 LibraryPrefix::Handle(unresolved_class.library_prefix()); |
| 6189 lib = lib_prefix.library(); | 6193 // Local lookup in library prefix scope. |
| 6190 } | 6194 resolved_type_class = lib_prefix.LookupLocalClass(unresolved_class_name); |
|
regis
2012/02/15 18:39:48
Nice cleanup!
siva
2012/02/15 20:52:47
Thanks.
| |
| 6191 Class& resolved_type_class = Class::Handle(); | |
| 6192 if (lib.IsNull()) { | |
| 6193 // Global lookup in current library. | |
| 6194 resolved_type_class = library_.LookupClass(unresolved_class_name); | |
| 6195 } else { | |
| 6196 // Local lookup in imported library. | |
| 6197 resolved_type_class = lib.LookupLocalClass(unresolved_class_name); | |
| 6198 } | 6195 } |
| 6199 if (!resolved_type_class.IsNull()) { | 6196 if (!resolved_type_class.IsNull()) { |
| 6200 Object& type_class = Object::Handle(resolved_type_class.raw()); | 6197 Object& type_class = Object::Handle(resolved_type_class.raw()); |
| 6201 ASSERT(type->IsType()); | 6198 ASSERT(type->IsType()); |
| 6202 // Replace unresolved class with resolved type class. | 6199 // Replace unresolved class with resolved type class. |
| 6203 Type& parameterized_type = Type::Handle(); | 6200 Type& parameterized_type = Type::Handle(); |
| 6204 parameterized_type ^= type->raw(); | 6201 parameterized_type ^= type->raw(); |
| 6205 parameterized_type.set_type_class(type_class); | 6202 parameterized_type.set_type_class(type_class); |
| 6206 } else if (type_resolution == kMustResolve) { | 6203 } else if (type_resolution == kMustResolve) { |
| 6207 ErrorMsg(type->token_index(), "type '%s' is not loaded", | 6204 ErrorMsg(type->token_index(), "type '%s' is not loaded", |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6512 Class& cls = Class::Handle(); | 6509 Class& cls = Class::Handle(); |
| 6513 cls ^= obj.raw(); | 6510 cls ^= obj.raw(); |
| 6514 return new PrimaryNode(qual_ident.ident_pos, Class::ZoneHandle(cls.raw())); | 6511 return new PrimaryNode(qual_ident.ident_pos, Class::ZoneHandle(cls.raw())); |
| 6515 } | 6512 } |
| 6516 if (obj.IsField()) { | 6513 if (obj.IsField()) { |
| 6517 Field& field = Field::Handle(); | 6514 Field& field = Field::Handle(); |
| 6518 field ^= obj.raw(); | 6515 field ^= obj.raw(); |
| 6519 ASSERT(field.is_static()); | 6516 ASSERT(field.is_static()); |
| 6520 return GenerateStaticFieldLookup(field, qual_ident.ident_pos); | 6517 return GenerateStaticFieldLookup(field, qual_ident.ident_pos); |
| 6521 } | 6518 } |
| 6522 Function& func = Function::Handle(); | |
| 6523 if (obj.IsFunction()) { | 6519 if (obj.IsFunction()) { |
| 6520 Function& func = Function::Handle(); | |
|
hausner
2012/02/15 18:04:27
Why not allocate a ZoneHandle here instead of allo
siva
2012/02/15 20:52:47
Hoisted the Handle allocation outside the 'if stat
| |
| 6524 func ^= obj.raw(); | 6521 func ^= obj.raw(); |
| 6525 ASSERT(func.is_static()); | 6522 ASSERT(func.is_static()); |
| 6526 return new PrimaryNode(qual_ident.ident_pos, | 6523 return new PrimaryNode(qual_ident.ident_pos, |
| 6527 Function::ZoneHandle(func.raw())); | 6524 Function::ZoneHandle(func.raw())); |
| 6528 } else { | 6525 } else { |
| 6529 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); | 6526 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); |
| 6530 } | 6527 } |
| 6531 | 6528 |
| 6532 // Check if there is a global getter or setter for qual_ident. | 6529 // Check if there is a global getter or setter for qual_ident. |
| 6533 // We create a getter node even if a getter doesn't exist since | 6530 // We create a getter node even if a getter doesn't exist since |
| 6534 // qual_ident could be followed by an assignment which will convert it | 6531 // qual_ident could be followed by an assignment which will convert it |
| 6535 // to a setter node. If there is no assignment we will get an error | 6532 // to a setter node. If there is no assignment we will get an error |
| 6536 // when we try to invoke the getter. | 6533 // when we try to invoke the getter. |
| 6537 String& accessor_name = String::Handle(Field::GetterName(*qual_ident.ident)); | 6534 String& accessor_name = String::Handle(Field::GetterName(*qual_ident.ident)); |
| 6538 if (resolve_locally) { | 6535 if (resolve_locally) { |
| 6539 obj = lib.LookupLocalObject(accessor_name); | 6536 obj = lib.LookupLocalObject(accessor_name); |
| 6540 } else { | 6537 } else { |
| 6541 obj = lib.LookupObject(accessor_name); | 6538 obj = lib.LookupObject(accessor_name); |
| 6542 } | 6539 } |
| 6543 if (obj.IsNull()) { | 6540 if (obj.IsNull()) { |
| 6544 accessor_name = Field::SetterName(*qual_ident.ident); | 6541 accessor_name = Field::SetterName(*qual_ident.ident); |
| 6545 if (resolve_locally) { | 6542 if (resolve_locally) { |
| 6546 obj = lib.LookupLocalObject(accessor_name); | 6543 obj = lib.LookupLocalObject(accessor_name); |
| 6547 } else { | 6544 } else { |
| 6548 obj = lib.LookupObject(accessor_name); | 6545 obj = lib.LookupObject(accessor_name); |
| 6549 } | 6546 } |
| 6550 } | 6547 } |
| 6551 if (!obj.IsNull()) { | 6548 if (!obj.IsNull()) { |
| 6549 Function& func = Function::Handle(); | |
| 6552 ASSERT(obj.IsFunction()); | 6550 ASSERT(obj.IsFunction()); |
| 6553 func ^= obj.raw(); | 6551 func ^= obj.raw(); |
| 6554 ASSERT(func.is_static()); | 6552 ASSERT(func.is_static()); |
| 6555 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 6553 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 6556 return new StaticGetterNode(qual_ident.ident_pos, | 6554 return new StaticGetterNode(qual_ident.ident_pos, |
| 6557 Class::ZoneHandle(func.owner()), | 6555 Class::ZoneHandle(func.owner()), |
| 6558 *qual_ident.ident); | 6556 *qual_ident.ident); |
| 6559 } | 6557 } |
| 6560 if (qual_ident.lib_prefix != NULL) { | 6558 if (qual_ident.lib_prefix != NULL) { |
| 6559 return NULL; | |
| 6560 } | |
| 6561 // Lexically unresolved primary identifiers are referenced by their name. | |
| 6562 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident); | |
| 6563 } | |
| 6564 | |
| 6565 | |
| 6566 // Do a lookup for the identifier in the library prefix scope of the specified | |
| 6567 // library prefix. This would mean trying to resolve it locally in any of the | |
| 6568 // libraries present in the library prefix. | |
| 6569 AstNode* Parser::ResolveIdentInLibraryPrefixScope(const LibraryPrefix& prefix, | |
| 6570 const QualIdent& qual_ident) { | |
| 6571 TRACE_PARSER("ResolveIdentInLibraryPrefixScope"); | |
| 6572 Library& lib = Library::Handle(); | |
| 6573 AstNode* result = NULL; | |
| 6574 for (intptr_t i = 0; ((i < prefix.num_libs()) && (result == NULL)); i++) { | |
| 6575 lib = prefix.GetLibrary(i); | |
| 6576 ASSERT(!lib.IsNull()); | |
| 6577 result = ResolveIdentInLibraryScope(lib, qual_ident, kResolveLocally); | |
| 6578 } | |
| 6579 if (result == NULL) { | |
| 6561 // This is an unresolved prefixed primary identifier, need to report | 6580 // This is an unresolved prefixed primary identifier, need to report |
| 6562 // an error. | 6581 // an error. |
| 6563 ErrorMsg(qual_ident.ident_pos, "identifier '%s.%s' cannot be resolved", | 6582 ErrorMsg(qual_ident.ident_pos, "identifier '%s.%s' cannot be resolved", |
| 6564 String::Handle(qual_ident.lib_prefix->name()).ToCString(), | 6583 String::Handle(qual_ident.lib_prefix->name()).ToCString(), |
| 6565 qual_ident.ident->ToCString()); | 6584 qual_ident.ident->ToCString()); |
| 6566 } | 6585 } |
| 6567 // Lexically unresolved primary identifiers are referenced by their name. | 6586 return result; |
| 6568 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident); | |
| 6569 } | 6587 } |
| 6570 | 6588 |
| 6571 | 6589 |
| 6572 // Resolve identifier, issue an error message if the name refers to | 6590 // Resolve identifier, issue an error message if the name refers to |
| 6573 // a method or a class/interface. | 6591 // a method or a class/interface. |
| 6574 // If the name cannot be resolved, turn it into an instance field access | 6592 // If the name cannot be resolved, turn it into an instance field access |
| 6575 // if we're compiling an instance method, or issue an error message | 6593 // if we're compiling an instance method, or issue an error message |
| 6576 // if we're compiling a static method. | 6594 // if we're compiling a static method. |
| 6577 AstNode* Parser::ResolveVarOrField(intptr_t ident_pos, const String& ident) { | 6595 AstNode* Parser::ResolveVarOrField(intptr_t ident_pos, const String& ident) { |
| 6578 TRACE_PARSER("ResolveVarOrField"); | 6596 TRACE_PARSER("ResolveVarOrField"); |
| (...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7392 // This is a non-local unqualified identifier so resolve the identifier | 7410 // This is a non-local unqualified identifier so resolve the identifier |
| 7393 // locally in the main app library and all libraries imported by it. | 7411 // locally in the main app library and all libraries imported by it. |
| 7394 primary = ResolveIdentInLibraryScope(library_, | 7412 primary = ResolveIdentInLibraryScope(library_, |
| 7395 qual_ident, | 7413 qual_ident, |
| 7396 kResolveIncludingImports); | 7414 kResolveIncludingImports); |
| 7397 } | 7415 } |
| 7398 } else { | 7416 } else { |
| 7399 // This is a qualified identifier with a library prefix so resolve | 7417 // This is a qualified identifier with a library prefix so resolve |
| 7400 // the identifier locally in that library (we do not include the | 7418 // the identifier locally in that library (we do not include the |
| 7401 // libraries imported by that library). | 7419 // libraries imported by that library). |
| 7402 const Library& lib = Library::Handle(qual_ident.lib_prefix->library()); | 7420 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), |
| 7403 primary = ResolveIdentInLibraryScope(lib, | 7421 qual_ident); |
| 7404 qual_ident, | |
| 7405 kResolveLocally); | |
| 7406 } | 7422 } |
| 7407 ASSERT(primary != NULL); | 7423 ASSERT(primary != NULL); |
| 7408 } else if (CurrentToken() == Token::kTHIS) { | 7424 } else if (CurrentToken() == Token::kTHIS) { |
| 7409 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 7425 const String& this_name = String::Handle(String::NewSymbol(kThisName)); |
| 7410 LocalVariable* local = LookupLocalScope(this_name); | 7426 LocalVariable* local = LookupLocalScope(this_name); |
| 7411 if (local == NULL) { | 7427 if (local == NULL) { |
| 7412 ErrorMsg("unexpected use of 'this' in primary expression"); | 7428 ErrorMsg("unexpected use of 'this' in primary expression"); |
| 7413 } | 7429 } |
| 7414 primary = new LoadLocalNode(token_index_, *local); | 7430 primary = new LoadLocalNode(token_index_, *local); |
| 7415 ConsumeToken(); | 7431 ConsumeToken(); |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7773 void Parser::SkipQualIdent() { | 7789 void Parser::SkipQualIdent() { |
| 7774 ASSERT(IsIdentifier()); | 7790 ASSERT(IsIdentifier()); |
| 7775 ConsumeToken(); | 7791 ConsumeToken(); |
| 7776 if (CurrentToken() == Token::kPERIOD) { | 7792 if (CurrentToken() == Token::kPERIOD) { |
| 7777 ConsumeToken(); // Consume the kPERIOD token. | 7793 ConsumeToken(); // Consume the kPERIOD token. |
| 7778 ExpectIdentifier("identifier expected after '.'"); | 7794 ExpectIdentifier("identifier expected after '.'"); |
| 7779 } | 7795 } |
| 7780 } | 7796 } |
| 7781 | 7797 |
| 7782 } // namespace dart | 7798 } // namespace dart |
| OLD | NEW |