Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: runtime/vm/parser.cc

Issue 10823396: Implement import scope (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 2911 matching lines...) Expand 10 before | Expand all | Expand 10 after
2922 ConsumeToken(); 2922 ConsumeToken();
2923 is_patch = true; 2923 is_patch = true;
2924 } 2924 }
2925 ExpectToken(Token::kCLASS); 2925 ExpectToken(Token::kCLASS);
2926 const intptr_t classname_pos = TokenPos(); 2926 const intptr_t classname_pos = TokenPos();
2927 String& class_name = *ExpectTypeIdentifier("class name expected"); 2927 String& class_name = *ExpectTypeIdentifier("class name expected");
2928 if (FLAG_trace_parser) { 2928 if (FLAG_trace_parser) {
2929 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); 2929 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString());
2930 } 2930 }
2931 Class& cls = Class::Handle(); 2931 Class& cls = Class::Handle();
2932 Object& obj = Object::Handle(library_.LookupObject(class_name)); 2932 Object& obj = Object::Handle(library_.LookupLocalObject(class_name));
2933 if (obj.IsNull()) { 2933 if (obj.IsNull()) {
2934 if (is_patch) { 2934 if (is_patch) {
2935 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", 2935 ErrorMsg(classname_pos, "missing class '%s' cannot be patched",
2936 class_name.ToCString()); 2936 class_name.ToCString());
2937 } 2937 }
2938 cls = Class::New(class_name, script_, classname_pos); 2938 cls = Class::New(class_name, script_, classname_pos);
2939 library_.AddClass(cls); 2939 library_.AddClass(cls);
2940 } else { 2940 } else {
2941 if (!obj.IsClass()) { 2941 if (!obj.IsClass()) {
2942 ErrorMsg(classname_pos, "'%s' is already defined", 2942 ErrorMsg(classname_pos, "'%s' is already defined",
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
3021 cls.SetFields(array); 3021 cls.SetFields(array);
3022 3022
3023 // Creating a new array for functions marks the class as parsed. 3023 // Creating a new array for functions marks the class as parsed.
3024 array = Array::MakeArray(members.functions()); 3024 array = Array::MakeArray(members.functions());
3025 cls.SetFunctions(array); 3025 cls.SetFunctions(array);
3026 3026
3027 if (!is_patch) { 3027 if (!is_patch) {
3028 pending_classes.Add(cls, Heap::kOld); 3028 pending_classes.Add(cls, Heap::kOld);
3029 } else { 3029 } else {
3030 // Lookup the patched class and apply the changes. 3030 // Lookup the patched class and apply the changes.
3031 obj = library_.LookupObject(class_name); 3031 obj = library_.LookupLocalObject(class_name);
3032 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); 3032 const char* err_msg = Class::Cast(obj).ApplyPatch(cls);
3033 if (err_msg != NULL) { 3033 if (err_msg != NULL) {
3034 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); 3034 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg);
3035 } 3035 }
3036 } 3036 }
3037 } 3037 }
3038 3038
3039 3039
3040 // Add an implicit constructor if no explicit constructor is present. 3040 // Add an implicit constructor if no explicit constructor is present.
3041 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { 3041 void Parser::AddImplicitConstructor(ClassDesc* class_desc) {
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
3196 // Record the function signature class in the current library. 3196 // Record the function signature class in the current library.
3197 library_.AddClass(signature_class); 3197 library_.AddClass(signature_class);
3198 } else { 3198 } else {
3199 // Forget the just created signature function and use the existing one. 3199 // Forget the just created signature function and use the existing one.
3200 signature_function = signature_class.signature_function(); 3200 signature_function = signature_class.signature_function();
3201 } 3201 }
3202 ASSERT(signature_function.signature_class() == signature_class.raw()); 3202 ASSERT(signature_function.signature_class() == signature_class.raw());
3203 3203
3204 // Lookup alias name and report an error if it is already defined in 3204 // Lookup alias name and report an error if it is already defined in
3205 // the library scope. 3205 // the library scope.
3206 const Object& obj = Object::Handle(library_.LookupObject(*alias_name)); 3206 const Object& obj = Object::Handle(library_.LookupLocalObject(*alias_name));
3207 if (!obj.IsNull()) { 3207 if (!obj.IsNull()) {
3208 ErrorMsg(alias_name_pos, 3208 ErrorMsg(alias_name_pos,
3209 "'%s' is already defined", alias_name->ToCString()); 3209 "'%s' is already defined", alias_name->ToCString());
3210 } 3210 }
3211 3211
3212 // Create the function type alias, but share the signature function of the 3212 // Create the function type alias, but share the signature function of the
3213 // canonical signature class. 3213 // canonical signature class.
3214 Class& function_type_alias = Class::Handle( 3214 Class& function_type_alias = Class::Handle(
3215 Class::NewSignatureClass(*alias_name, 3215 Class::NewSignatureClass(*alias_name,
3216 signature_function, 3216 signature_function,
(...skipping 12 matching lines...) Expand all
3229 const GrowableObjectArray& pending_classes) { 3229 const GrowableObjectArray& pending_classes) {
3230 TRACE_PARSER("ParseInterfaceDefinition"); 3230 TRACE_PARSER("ParseInterfaceDefinition");
3231 const intptr_t interface_pos = TokenPos(); 3231 const intptr_t interface_pos = TokenPos();
3232 ExpectToken(Token::kINTERFACE); 3232 ExpectToken(Token::kINTERFACE);
3233 const intptr_t interfacename_pos = TokenPos(); 3233 const intptr_t interfacename_pos = TokenPos();
3234 String& interface_name = *ExpectTypeIdentifier("interface name expected"); 3234 String& interface_name = *ExpectTypeIdentifier("interface name expected");
3235 if (FLAG_trace_parser) { 3235 if (FLAG_trace_parser) {
3236 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); 3236 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString());
3237 } 3237 }
3238 Class& interface = Class::Handle(); 3238 Class& interface = Class::Handle();
3239 Object& obj = Object::Handle(library_.LookupObject(interface_name)); 3239 Object& obj = Object::Handle(library_.LookupLocalObject(interface_name));
3240 if (obj.IsNull()) { 3240 if (obj.IsNull()) {
3241 interface = Class::NewInterface(interface_name, script_, interfacename_pos); 3241 interface = Class::NewInterface(interface_name, script_, interfacename_pos);
3242 library_.AddClass(interface); 3242 library_.AddClass(interface);
3243 } else { 3243 } else {
3244 if (!obj.IsClass()) { 3244 if (!obj.IsClass()) {
3245 ErrorMsg(interfacename_pos, "'%s' is already defined", 3245 ErrorMsg(interfacename_pos, "'%s' is already defined",
3246 interface_name.ToCString()); 3246 interface_name.ToCString());
3247 } 3247 }
3248 interface ^= obj.raw(); 3248 interface ^= obj.raw();
3249 if (!interface.is_interface()) { 3249 if (!interface.is_interface()) {
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
3573 const AbstractType& type = 3573 const AbstractType& type =
3574 AbstractType::ZoneHandle(ParseConstFinalVarOrType( 3574 AbstractType::ZoneHandle(ParseConstFinalVarOrType(
3575 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : 3575 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve :
3576 ClassFinalizer::kIgnore)); 3576 ClassFinalizer::kIgnore));
3577 Field& field = Field::Handle(); 3577 Field& field = Field::Handle();
3578 Function& getter = Function::Handle(); 3578 Function& getter = Function::Handle();
3579 while (true) { 3579 while (true) {
3580 const intptr_t name_pos = TokenPos(); 3580 const intptr_t name_pos = TokenPos();
3581 String& var_name = *ExpectIdentifier("variable name expected"); 3581 String& var_name = *ExpectIdentifier("variable name expected");
3582 3582
3583 if (library_.LookupObject(var_name) != Object::null()) { 3583 if (library_.LookupLocalObject(var_name) != Object::null()) {
3584 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); 3584 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString());
3585 } 3585 }
3586 String& accessor_name = String::Handle(Field::GetterName(var_name)); 3586 String& accessor_name = String::Handle(Field::GetterName(var_name));
3587 if (library_.LookupObject(accessor_name) != Object::null()) { 3587 if (library_.LookupLocalObject(accessor_name) != Object::null()) {
3588 ErrorMsg(name_pos, "getter for '%s' is already defined", 3588 ErrorMsg(name_pos, "getter for '%s' is already defined",
3589 var_name.ToCString()); 3589 var_name.ToCString());
3590 } 3590 }
3591 accessor_name = Field::SetterName(var_name); 3591 accessor_name = Field::SetterName(var_name);
3592 if (library_.LookupObject(accessor_name) != Object::null()) { 3592 if (library_.LookupLocalObject(accessor_name) != Object::null()) {
3593 ErrorMsg(name_pos, "setter for '%s' is already defined", 3593 ErrorMsg(name_pos, "setter for '%s' is already defined",
3594 var_name.ToCString()); 3594 var_name.ToCString());
3595 } 3595 }
3596 3596
3597 field = Field::New( 3597 field = Field::New(
3598 var_name, is_static, is_final, is_const, current_class(), name_pos); 3598 var_name, is_static, is_final, is_const, current_class(), name_pos);
3599 field.set_type(type); 3599 field.set_type(type);
3600 field.set_value(Instance::Handle(Instance::null())); 3600 field.set_value(Instance::Handle(Instance::null()));
3601 top_level->fields.Add(field); 3601 top_level->fields.Add(field);
3602 library_.AddObject(field, var_name); 3602 library_.AddObject(field, var_name);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3662 } else { 3662 } else {
3663 // Parse optional type. 3663 // Parse optional type.
3664 if ((CurrentToken() == Token::kIDENT) && 3664 if ((CurrentToken() == Token::kIDENT) &&
3665 (LookaheadToken(1) != Token::kLPAREN)) { 3665 (LookaheadToken(1) != Token::kLPAREN)) {
3666 result_type = ParseType(ClassFinalizer::kTryResolve); 3666 result_type = ParseType(ClassFinalizer::kTryResolve);
3667 } 3667 }
3668 } 3668 }
3669 const intptr_t name_pos = TokenPos(); 3669 const intptr_t name_pos = TokenPos();
3670 const String& func_name = *ExpectIdentifier("function name expected"); 3670 const String& func_name = *ExpectIdentifier("function name expected");
3671 3671
3672 bool found = library_.LookupObject(func_name) != Object::null(); 3672 bool found = library_.LookupLocalObject(func_name) != Object::null();
3673 if (found && !is_patch) { 3673 if (found && !is_patch) {
3674 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); 3674 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString());
3675 } else if (!found && is_patch) { 3675 } else if (!found && is_patch) {
3676 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); 3676 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString());
3677 } 3677 }
3678 String& accessor_name = String::Handle(Field::GetterName(func_name)); 3678 String& accessor_name = String::Handle(Field::GetterName(func_name));
3679 if (library_.LookupObject(accessor_name) != Object::null()) { 3679 if (library_.LookupLocalObject(accessor_name) != Object::null()) {
3680 ErrorMsg(name_pos, "'%s' is already defined as getter", 3680 ErrorMsg(name_pos, "'%s' is already defined as getter",
3681 func_name.ToCString()); 3681 func_name.ToCString());
3682 } 3682 }
3683 accessor_name = Field::SetterName(func_name); 3683 accessor_name = Field::SetterName(func_name);
3684 if (library_.LookupObject(accessor_name) != Object::null()) { 3684 if (library_.LookupLocalObject(accessor_name) != Object::null()) {
3685 ErrorMsg(name_pos, "'%s' is already defined as setter", 3685 ErrorMsg(name_pos, "'%s' is already defined as setter",
3686 func_name.ToCString()); 3686 func_name.ToCString());
3687 } 3687 }
3688 3688
3689 if (CurrentToken() != Token::kLPAREN) { 3689 if (CurrentToken() != Token::kLPAREN) {
3690 ErrorMsg("'(' expected"); 3690 ErrorMsg("'(' expected");
3691 } 3691 }
3692 const intptr_t function_pos = TokenPos(); 3692 const intptr_t function_pos = TokenPos();
3693 ParamList params; 3693 ParamList params;
3694 const bool allow_explicit_default_values = true; 3694 const bool allow_explicit_default_values = true;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3783 } else { 3783 } else {
3784 expected_num_parameters = 1; 3784 expected_num_parameters = 1;
3785 accessor_name = Field::SetterSymbol(*field_name); 3785 accessor_name = Field::SetterSymbol(*field_name);
3786 } 3786 }
3787 if ((params.num_fixed_parameters != expected_num_parameters) || 3787 if ((params.num_fixed_parameters != expected_num_parameters) ||
3788 (params.num_optional_parameters != 0)) { 3788 (params.num_optional_parameters != 0)) {
3789 ErrorMsg(name_pos, "illegal %s parameters", 3789 ErrorMsg(name_pos, "illegal %s parameters",
3790 is_getter ? "getter" : "setter"); 3790 is_getter ? "getter" : "setter");
3791 } 3791 }
3792 3792
3793 if (library_.LookupObject(*field_name) != Object::null()) { 3793 if (library_.LookupLocalObject(*field_name) != Object::null()) {
3794 ErrorMsg(name_pos, "'%s' is already defined in this library", 3794 ErrorMsg(name_pos, "'%s' is already defined in this library",
3795 field_name->ToCString()); 3795 field_name->ToCString());
3796 } 3796 }
3797 bool found = library_.LookupObject(accessor_name) != Object::null(); 3797 bool found = library_.LookupLocalObject(accessor_name) != Object::null();
3798 if (found && !is_patch) { 3798 if (found && !is_patch) {
3799 ErrorMsg(name_pos, "%s for '%s' is already defined", 3799 ErrorMsg(name_pos, "%s for '%s' is already defined",
3800 is_getter ? "getter" : "setter", 3800 is_getter ? "getter" : "setter",
3801 field_name->ToCString()); 3801 field_name->ToCString());
3802 } else if (!found && is_patch) { 3802 } else if (!found && is_patch) {
3803 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", 3803 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched",
3804 is_getter ? "getter" : "setter", 3804 is_getter ? "getter" : "setter",
3805 field_name->ToCString()); 3805 field_name->ToCString());
3806 } 3806 }
3807 3807
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
4024 ParseClassDefinition(pending_classes); 4024 ParseClassDefinition(pending_classes);
4025 } else if ((CurrentToken() == Token::kTYPEDEF) && 4025 } else if ((CurrentToken() == Token::kTYPEDEF) &&
4026 (LookaheadToken(1) != Token::kLPAREN)) { 4026 (LookaheadToken(1) != Token::kLPAREN)) {
4027 ParseFunctionTypeAlias(pending_classes); 4027 ParseFunctionTypeAlias(pending_classes);
4028 } else if (CurrentToken() == Token::kINTERFACE) { 4028 } else if (CurrentToken() == Token::kINTERFACE) {
4029 ParseInterfaceDefinition(pending_classes); 4029 ParseInterfaceDefinition(pending_classes);
4030 } else if ((CurrentToken() == Token::kABSTRACT) && 4030 } else if ((CurrentToken() == Token::kABSTRACT) &&
4031 (LookaheadToken(1) == Token::kCLASS)) { 4031 (LookaheadToken(1) == Token::kCLASS)) {
4032 ConsumeToken(); // Consume and ignore 'abstract'. 4032 ConsumeToken(); // Consume and ignore 'abstract'.
4033 ParseClassDefinition(pending_classes); 4033 ParseClassDefinition(pending_classes);
4034 } else if (is_patch_source() && 4034 } else if (is_patch_source() && IsLiteral("patch") &&
4035 (CurrentToken() == Token::kIDENT) &&
4036 CurrentLiteral()->Equals("patch") &&
4037 (LookaheadToken(1) == Token::kCLASS)) { 4035 (LookaheadToken(1) == Token::kCLASS)) {
4038 ParseClassDefinition(pending_classes); 4036 ParseClassDefinition(pending_classes);
4039 } else { 4037 } else {
4040 set_current_class(toplevel_class); 4038 set_current_class(toplevel_class);
4041 if (IsVariableDeclaration()) { 4039 if (IsVariableDeclaration()) {
4042 ParseTopLevelVariable(&top_level); 4040 ParseTopLevelVariable(&top_level);
4043 } else if (IsFunctionDeclaration()) { 4041 } else if (IsFunctionDeclaration()) {
4044 ParseTopLevelFunction(&top_level); 4042 ParseTopLevelFunction(&top_level);
4045 } else if (IsTopLevelAccessor()) { 4043 } else if (IsTopLevelAccessor()) {
4046 ParseTopLevelAccessor(&top_level); 4044 ParseTopLevelAccessor(&top_level);
(...skipping 2182 matching lines...) Expand 10 before | Expand all | Expand 10 after
6229 } 6227 }
6230 6228
6231 6229
6232 void Parser::UnexpectedToken() { 6230 void Parser::UnexpectedToken() {
6233 ErrorMsg("unexpected token '%s'", 6231 ErrorMsg("unexpected token '%s'",
6234 CurrentToken() == Token::kIDENT ? 6232 CurrentToken() == Token::kIDENT ?
6235 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); 6233 CurrentLiteral()->ToCString() : Token::Str(CurrentToken()));
6236 } 6234 }
6237 6235
6238 6236
6239 String* Parser::ExpectTypeIdentifier(const char* msg) { 6237 String* Parser::ExpectTypeIdentifier(const char* msg) {
regis 2012/08/17 20:23:07 This should be called ExpectClassIdentifier.
hausner 2012/08/17 21:05:52 Done.
6240 if (CurrentToken() != Token::kIDENT) { 6238 if (CurrentToken() != Token::kIDENT) {
6241 ErrorMsg(msg); 6239 ErrorMsg(msg);
6242 } 6240 }
6243 String* ident = CurrentLiteral(); 6241 String* ident = CurrentLiteral();
6242 if (ident->Equals("Dynamic")) {
6243 ErrorMsg("illegal type name '%s'", ident->ToCString());
regis 2012/08/17 20:23:07 "illegal class name"
hausner 2012/08/17 21:05:52 Re-used the error message defined by the caller, s
6244 }
6244 ConsumeToken(); 6245 ConsumeToken();
6245 return ident; 6246 return ident;
6246 } 6247 }
6247 6248
6249
6248 // Check whether current token is an identifier or a built-in identifier. 6250 // Check whether current token is an identifier or a built-in identifier.
6249 String* Parser::ExpectIdentifier(const char* msg) { 6251 String* Parser::ExpectIdentifier(const char* msg) {
6250 if (!IsIdentifier()) { 6252 if (!IsIdentifier()) {
6251 ErrorMsg(msg); 6253 ErrorMsg(msg);
6252 } 6254 }
6253 String* ident = CurrentLiteral(); 6255 String* ident = CurrentLiteral();
6254 ConsumeToken(); 6256 ConsumeToken();
6255 return ident; 6257 return ident;
6256 } 6258 }
6257 6259
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
7251 // type arguments have previously been parsed. 7253 // type arguments have previously been parsed.
7252 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) { 7254 if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) {
7253 ErrorMsg(type_parameter.token_pos(), 7255 ErrorMsg(type_parameter.token_pos(),
7254 "type parameter '%s' cannot be parameterized", 7256 "type parameter '%s' cannot be parameterized",
7255 String::Handle(type_parameter.name()).ToCString()); 7257 String::Handle(type_parameter.name()).ToCString());
7256 } 7258 }
7257 *type = type_parameter.raw(); 7259 *type = type_parameter.raw();
7258 return; 7260 return;
7259 } 7261 }
7260 } 7262 }
7261 // Global lookup in current library. 7263 // Resolve classname in the scope of the current library.
7262 resolved_type_class = library_.LookupClass(unresolved_class_name); 7264 resolved_type_class =
7265 ResolveClassInCurrentLibraryScope(unresolved_class.token_pos(),
7266 unresolved_class_name);
7263 } else { 7267 } else {
7264 LibraryPrefix& lib_prefix = 7268 LibraryPrefix& lib_prefix =
7265 LibraryPrefix::Handle(unresolved_class.library_prefix()); 7269 LibraryPrefix::Handle(unresolved_class.library_prefix());
7266 // Local lookup in library prefix scope. 7270 // Resolve class name in the scope of the library prefix.
7267 resolved_type_class = lib_prefix.LookupLocalClass(unresolved_class_name); 7271 resolved_type_class =
7272 ResolveClassInPrefixScope(unresolved_class.token_pos(),
7273 lib_prefix,
7274 unresolved_class_name);
7268 } 7275 }
7269 // At this point, we can only have a parameterized_type. 7276 // At this point, we can only have a parameterized_type.
7270 Type& parameterized_type = Type::Handle(); 7277 Type& parameterized_type = Type::Handle();
7271 parameterized_type ^= type->raw(); 7278 parameterized_type ^= type->raw();
7272 if (!resolved_type_class.IsNull()) { 7279 if (!resolved_type_class.IsNull()) {
7273 // Replace unresolved class with resolved type class. 7280 // Replace unresolved class with resolved type class.
7274 parameterized_type.set_type_class(resolved_type_class); 7281 parameterized_type.set_type_class(resolved_type_class);
7275 } else if (finalization >= ClassFinalizer::kCanonicalize) { 7282 } else if (finalization >= ClassFinalizer::kCanonicalize) {
7276 // The type is malformed. 7283 // The type is malformed.
7277 ClassFinalizer::FinalizeMalformedType( 7284 ClassFinalizer::FinalizeMalformedType(
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
7613 } 7620 }
7614 7621
7615 // Nothing found in scope of current class. 7622 // Nothing found in scope of current class.
7616 if (node != NULL) { 7623 if (node != NULL) {
7617 *node = NULL; 7624 *node = NULL;
7618 } 7625 }
7619 return false; // Not an unqualified identifier. 7626 return false; // Not an unqualified identifier.
7620 } 7627 }
7621 7628
7622 7629
7623 // Do a lookup for the identifier in the library scope of the specified 7630 static RawObject* LookupNameInLibrary(const Library& lib, const String& name) {
7624 // library. If resolve_locally is true the lookup does not consider
7625 // the libraries imported by it for the lookup.
7626 AstNode* Parser::ResolveIdentInLibraryScope(const Library& lib,
7627 const QualIdent& qual_ident,
7628 bool resolve_locally) {
7629 TRACE_PARSER("ResolveIdentInLibraryScope");
7630 Object& obj = Object::Handle(); 7631 Object& obj = Object::Handle();
7631 if (resolve_locally) { 7632 obj = lib.LookupLocalObject(name);
7632 obj = lib.LookupLocalObject(*qual_ident.ident); 7633 if (!obj.IsNull()) {
7634 return obj.raw();
7635 }
7636 String& accessor_name = String::Handle(Field::GetterName(name));
7637 obj = lib.LookupLocalObject(accessor_name);
7638 if (!obj.IsNull()) {
7639 return obj.raw();
7640 }
7641 accessor_name = Field::SetterName(name);
7642 obj = lib.LookupLocalObject(accessor_name);
7643 return obj.raw();
7644 }
7645
7646
7647 // Resolve an name by checking the global scope of the current
regis 2012/08/17 20:23:07 s/an/a/
hausner 2012/08/17 21:05:52 Done.
7648 // library. If not found in the current library, then look in the scopes
7649 // of all libraries that are imported without a library prefix.
7650 // Issue an error if the name is not found in the global scope
7651 // of the current library, but is defined in more than one imported
7652 // library, i.e. if the name cannot be resolved unambiguously.
7653 RawObject* Parser::ResolveNameInCurrentLibraryScope(intptr_t ident_pos,
7654 const String& name) {
7655 Object& obj = Object::Handle(LookupNameInLibrary(library_, name));
7656 if (obj.IsNull()) {
7657 // Name is not found in current library. Check scope of all
7658 // imported libraries.
7659 String& first_lib_url = String::Handle();
7660 Library& lib = Library::Handle();
7661 intptr_t num_imports = library_.num_imports();
7662 Object& resolved_obj = Object::Handle();
7663 for (int i = 0; i < num_imports; i++) {
7664 lib ^= library_.ImportAt(i);
7665 resolved_obj = LookupNameInLibrary(lib, name);
7666 if (!resolved_obj.IsNull()) {
7667 if (!first_lib_url.IsNull()) {
7668 // Found duplicate definition.
7669 ErrorMsg(ident_pos,
7670 "ambiguous reference: "
7671 "'%s' is defined in library '%s' and also in '%s'.",
regis 2012/08/17 20:23:07 We usually do not terminate error messages with a
hausner 2012/08/17 21:05:52 Done.
7672 name.ToCString(),
7673 first_lib_url.ToCString(),
7674 String::Handle(lib.url()).ToCString());
7675 } else {
7676 first_lib_url = lib.url();
7677 obj = resolved_obj.raw();
7678 }
7679 }
7680 }
7681 }
7682 return obj.raw();
7683 }
7684
7685
7686 RawClass* Parser::ResolveClassInCurrentLibraryScope(intptr_t ident_pos,
7687 const String& name) {
7688 const Object& obj =
7689 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name));
7690 if (obj.IsClass()) {
7691 return Class::Cast(obj).raw();
7692 }
7693 return Class::null();
7694 }
7695
7696
7697 // Resolve an identifier by checking the global scope of the current
7698 // library. If not found in the current library, then look in the scopes
7699 // of all libraries that are imported without a library prefix.
7700 // Issue an error if the identifier is not found in the global scope
7701 // of the current library, but is defined in more than one imported
7702 // library, i.e. if the identifier cannot be resolved unambiguously.
7703 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos,
7704 const String& ident) {
7705 const Object& obj =
7706 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident));
7707 if (obj.IsClass()) {
7708 const Class& cls = Class::Cast(obj);
7709 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw()));
7710 } else if (obj.IsField()) {
7711 const Field& field = Field::Cast(obj);
7712 ASSERT(field.is_static());
7713 return GenerateStaticFieldLookup(field, ident_pos);
7714 } else if (obj.IsFunction()) {
7715 const Function& func = Function::Cast(obj);
7716 ASSERT(func.is_static());
7717 if (func.IsGetterFunction() || func.IsSetterFunction()) {
7718 return new StaticGetterNode(ident_pos,
7719 /* receiver */ NULL,
7720 /* is_super_getter */ false,
7721 Class::ZoneHandle(func.Owner()),
7722 ident);
7723
7724 } else {
7725 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw()));
7726 }
7633 } else { 7727 } else {
7634 obj = lib.LookupObject(*qual_ident.ident); 7728 ASSERT(obj.IsNull() || obj.IsLibraryPrefix());
7729 }
7730 // Lexically unresolved primary identifiers are referenced by their name.
7731 return new PrimaryNode(ident_pos, ident);
7732 }
7733
7734
7735 RawObject* Parser::ResolveNameInPrefixScope(intptr_t ident_pos,
7736 const LibraryPrefix& prefix,
7737 const String& name) {
7738 Library& lib = Library::Handle();
7739 String& first_lib_url = String::Handle();
7740 Object& obj = Object::Handle();
7741 Object& resolved_obj = Object::Handle();
7742 for (intptr_t i = 0; i < prefix.num_libs(); i++) {
7743 lib = prefix.GetLibrary(i);
7744 ASSERT(!lib.IsNull());
7745 resolved_obj = LookupNameInLibrary(lib, name);
7746 if (!resolved_obj.IsNull()) {
7747 obj = resolved_obj.raw();
7748 if (first_lib_url.IsNull()) {
7749 first_lib_url = lib.url();
7750 } else {
7751 ErrorMsg(ident_pos,
7752 "ambiguous reference: '%s.%s' is defined in '%s' and '%s'",
7753 String::Handle(prefix.name()).ToCString(),
7754 name.ToCString(),
7755 first_lib_url.ToCString(),
7756 String::Handle(lib.url()).ToCString());
7757 }
7758 }
7759 }
7760 return obj.raw();
7761 }
7762
7763
7764 RawClass* Parser::ResolveClassInPrefixScope(intptr_t ident_pos,
7765 const LibraryPrefix& prefix,
7766 const String& name) {
7767 const Object& obj =
7768 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name));
7769 if (obj.IsClass()) {
7770 return Class::Cast(obj).raw();
7771 }
7772 return Class::null();
7773 }
7774
7775
7776 // Do a lookup for the identifier in the scope of the specified
7777 // library prefix. This means trying to resolve it locally in all of the
7778 // libraries present in the library prefix. If there are multiple libraries
7779 // with the name, issue an ambiguous reference error.
7780 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos,
7781 const LibraryPrefix& prefix,
7782 const String& ident) {
7783 TRACE_PARSER("ResolveIdentInPrefixScope");
regis 2012/08/17 20:23:07 No TRACE_PARSER in other calls. On purpose?
hausner 2012/08/17 21:05:52 No on purpose. We have lots of functions that don'
7784 Object& obj =
7785 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident));
7786 if (obj.IsNull()) {
7787 // Unresolved prefixed primary identifier.
7788 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved",
7789 String::Handle(prefix.name()).ToCString(),
7790 ident.ToCString());
7635 } 7791 }
7636 if (obj.IsClass()) { 7792 if (obj.IsClass()) {
7637 const Class& cls = Class::Cast(obj); 7793 const Class& cls = Class::Cast(obj);
7638 return new PrimaryNode(qual_ident.ident_pos, Class::ZoneHandle(cls.raw())); 7794 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw()));
7639 } 7795 } else if (obj.IsField()) {
7640 if (obj.IsField()) {
7641 const Field& field = Field::Cast(obj); 7796 const Field& field = Field::Cast(obj);
7642 ASSERT(field.is_static()); 7797 ASSERT(field.is_static());
7643 return GenerateStaticFieldLookup(field, qual_ident.ident_pos); 7798 return GenerateStaticFieldLookup(field, ident_pos);
7644 } 7799 } else if (obj.IsFunction()) {
7645 if (obj.IsFunction()) {
7646 const Function& func = Function::Cast(obj); 7800 const Function& func = Function::Cast(obj);
7647 ASSERT(func.is_static()); 7801 ASSERT(func.is_static());
7648 return new PrimaryNode(qual_ident.ident_pos, 7802 if (func.IsGetterFunction() || func.IsSetterFunction()) {
7649 Function::ZoneHandle(func.raw())); 7803 return new StaticGetterNode(ident_pos,
7804 /* receiver */ NULL,
7805 /* is_super_getter */ false,
7806 Class::ZoneHandle(func.Owner()),
7807 ident);
7808
7809 } else {
7810 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw()));
7811 }
7650 } else { 7812 } else {
7651 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); 7813 // TODO(hausner): Should this be an error? It is not meaningful to
7652 } 7814 // reference a library prefix defined in an imported library.
7653 7815 ASSERT(obj.IsLibraryPrefix());
7654 // Check if there is a global getter or setter for qual_ident.
7655 // We create a getter node even if a getter doesn't exist since
7656 // qual_ident could be followed by an assignment which will convert it
7657 // to a setter node. If there is no assignment we will get an error
7658 // when we try to invoke the getter.
7659 String& accessor_name = String::Handle(Field::GetterName(*qual_ident.ident));
7660 if (resolve_locally) {
7661 obj = lib.LookupLocalObject(accessor_name);
7662 } else {
7663 obj = lib.LookupObject(accessor_name);
7664 }
7665 if (obj.IsNull()) {
7666 accessor_name = Field::SetterName(*qual_ident.ident);
7667 if (resolve_locally) {
7668 obj = lib.LookupLocalObject(accessor_name);
7669 } else {
7670 obj = lib.LookupObject(accessor_name);
7671 }
7672 }
7673 if (!obj.IsNull()) {
7674 ASSERT(obj.IsFunction());
7675 const Function& func = Function::Cast(obj);
7676 ASSERT(func.is_static());
7677 ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
7678 return new StaticGetterNode(qual_ident.ident_pos,
7679 NULL,
7680 false,
7681 Class::ZoneHandle(func.Owner()),
7682 *qual_ident.ident);
7683 }
7684 if (qual_ident.lib_prefix != NULL) {
7685 return NULL;
7686 } 7816 }
7687 // Lexically unresolved primary identifiers are referenced by their name. 7817 // Lexically unresolved primary identifiers are referenced by their name.
7688 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident); 7818 return new PrimaryNode(ident_pos, ident);
7689 }
7690
7691
7692 // Do a lookup for the identifier in the library prefix scope of the specified
7693 // library prefix. This would mean trying to resolve it locally in any of the
7694 // libraries present in the library prefix.
7695 AstNode* Parser::ResolveIdentInLibraryPrefixScope(const LibraryPrefix& prefix,
7696 const QualIdent& qual_ident) {
7697 TRACE_PARSER("ResolveIdentInLibraryPrefixScope");
7698 Library& lib = Library::Handle();
7699 AstNode* result = NULL;
7700 for (intptr_t i = 0; ((i < prefix.num_libs()) && (result == NULL)); i++) {
7701 lib = prefix.GetLibrary(i);
7702 ASSERT(!lib.IsNull());
7703 result = ResolveIdentInLibraryScope(lib, qual_ident, kResolveLocally);
7704 }
7705 if (result == NULL) {
7706 // This is an unresolved prefixed primary identifier, need to report
7707 // an error.
7708 ErrorMsg(qual_ident.ident_pos, "identifier '%s.%s' cannot be resolved",
7709 String::Handle(qual_ident.lib_prefix->name()).ToCString(),
7710 qual_ident.ident->ToCString());
7711 }
7712 return result;
7713 } 7819 }
7714 7820
7715 7821
7716 // Resolve identifier, issue an error message if the name refers to 7822 // Resolve identifier, issue an error message if the name refers to
7717 // a class/interface or a type parameter. Issue an error message if 7823 // a class/interface or a type parameter. Issue an error message if
7718 // the ident refers to a method and allow_closure_names is false. 7824 // the ident refers to a method and allow_closure_names is false.
7719 // If the name cannot be resolved, turn it into an instance field access 7825 // If the name cannot be resolved, turn it into an instance field access
7720 // if we're compiling an instance method, or issue an error message 7826 // if we're compiling an instance method, or issue an error message
7721 // if we're compiling a static method. 7827 // if we're compiling a static method.
7722 AstNode* Parser::ResolveIdent(intptr_t ident_pos, 7828 AstNode* Parser::ResolveIdent(intptr_t ident_pos,
(...skipping 12 matching lines...) Expand all
7735 TypeParameter& type_param = TypeParameter::Handle( 7841 TypeParameter& type_param = TypeParameter::Handle(
7736 scope_class.LookupTypeParameter(ident, ident_pos)); 7842 scope_class.LookupTypeParameter(ident, ident_pos));
7737 if (!type_param.IsNull()) { 7843 if (!type_param.IsNull()) {
7738 String& type_param_name = String::Handle(type_param.name()); 7844 String& type_param_name = String::Handle(type_param.name());
7739 ErrorMsg(ident_pos, "illegal use of type parameter %s", 7845 ErrorMsg(ident_pos, "illegal use of type parameter %s",
7740 type_param_name.ToCString()); 7846 type_param_name.ToCString());
7741 } 7847 }
7742 } 7848 }
7743 // Not found in the local scope, and the name is not a type parameter. 7849 // Not found in the local scope, and the name is not a type parameter.
7744 // Try finding the variable in the library scope (current library 7850 // Try finding the variable in the library scope (current library
7745 // and all libraries imported by it). 7851 // and all libraries imported by it without a library prefix).
7746 QualIdent qual_ident; 7852 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident);
7747 qual_ident.lib_prefix = NULL;
7748 qual_ident.ident_pos = ident_pos;
7749 qual_ident.ident = &(String::ZoneHandle(ident.raw()));
7750 resolved = ResolveIdentInLibraryScope(library_,
7751 qual_ident,
7752 kResolveIncludingImports);
7753 } 7853 }
7754 if (resolved->IsPrimaryNode()) { 7854 if (resolved->IsPrimaryNode()) {
7755 PrimaryNode* primary = resolved->AsPrimaryNode(); 7855 PrimaryNode* primary = resolved->AsPrimaryNode();
7756 if (primary->primary().IsString()) { 7856 if (primary->primary().IsString()) {
7757 // We got an unresolved name. If we are compiling a static 7857 // We got an unresolved name. If we are compiling a static
7758 // method, this is an error. In an instance method, we convert 7858 // method, this is an error. In an instance method, we convert
7759 // the unresolved name to an instance field access, since a 7859 // the unresolved name to an instance field access, since a
7760 // subclass might define a field with this name. 7860 // subclass might define a field with this name.
7761 if (current_function().is_static()) { 7861 if (current_function().is_static()) {
7762 ErrorMsg(ident_pos, "identifier '%s' is not declared in this scope", 7862 ErrorMsg(ident_pos, "identifier '%s' is not declared in this scope",
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
8700 if (!type_param.IsNull()) { 8800 if (!type_param.IsNull()) {
8701 const String& type_param_name = String::Handle(type_param.name()); 8801 const String& type_param_name = String::Handle(type_param.name());
8702 ErrorMsg(qual_ident.ident_pos, 8802 ErrorMsg(qual_ident.ident_pos,
8703 "illegal use of type parameter %s", 8803 "illegal use of type parameter %s",
8704 type_param_name.ToCString()); 8804 type_param_name.ToCString());
8705 } 8805 }
8706 } 8806 }
8707 // This is a non-local unqualified identifier so resolve the 8807 // This is a non-local unqualified identifier so resolve the
8708 // identifier locally in the main app library and all libraries 8808 // identifier locally in the main app library and all libraries
8709 // imported by it. 8809 // imported by it.
8710 primary = ResolveIdentInLibraryScope(library_, 8810 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos,
8711 qual_ident, 8811 *qual_ident.ident);
8712 kResolveIncludingImports);
8713 } 8812 }
8714 } else { 8813 } else {
8715 // This is a qualified identifier with a library prefix so resolve 8814 // This is a qualified identifier with a library prefix so resolve
8716 // the identifier locally in that library (we do not include the 8815 // the identifier locally in that library (we do not include the
8717 // libraries imported by that library). 8816 // libraries imported by that library).
8718 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), 8817 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos,
8719 qual_ident); 8818 *qual_ident.lib_prefix,
8819 *qual_ident.ident);
regis 2012/08/17 20:23:07 indentation
hausner 2012/08/17 21:05:52 Done.
8720 } 8820 }
8721 ASSERT(primary != NULL); 8821 ASSERT(primary != NULL);
8722 } else if (CurrentToken() == Token::kTHIS) { 8822 } else if (CurrentToken() == Token::kTHIS) {
8723 const String& this_name = String::Handle(Symbols::This()); 8823 const String& this_name = String::Handle(Symbols::This());
8724 LocalVariable* local = LookupLocalScope(this_name); 8824 LocalVariable* local = LookupLocalScope(this_name);
8725 if (local == NULL) { 8825 if (local == NULL) {
8726 ErrorMsg("receiver 'this' is not in scope"); 8826 ErrorMsg("receiver 'this' is not in scope");
8727 } 8827 }
8728 primary = new LoadLocalNode(TokenPos(), local); 8828 primary = new LoadLocalNode(TokenPos(), local);
8729 ConsumeToken(); 8829 ConsumeToken();
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
9085 void Parser::SkipQualIdent() { 9185 void Parser::SkipQualIdent() {
9086 ASSERT(IsIdentifier()); 9186 ASSERT(IsIdentifier());
9087 ConsumeToken(); 9187 ConsumeToken();
9088 if (CurrentToken() == Token::kPERIOD) { 9188 if (CurrentToken() == Token::kPERIOD) {
9089 ConsumeToken(); // Consume the kPERIOD token. 9189 ConsumeToken(); // Consume the kPERIOD token.
9090 ExpectIdentifier("identifier expected after '.'"); 9190 ExpectIdentifier("identifier expected after '.'");
9091 } 9191 }
9092 } 9192 }
9093 9193
9094 } // namespace dart 9194 } // namespace dart
OLDNEW
« runtime/vm/parser.h ('K') | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698