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

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
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/co19/co19-runtime.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2906 matching lines...) Expand 10 before | Expand all | Expand 10 after
2917 const intptr_t class_pos = TokenPos(); 2917 const intptr_t class_pos = TokenPos();
2918 bool is_patch = false; 2918 bool is_patch = false;
2919 if (is_patch_source() && 2919 if (is_patch_source() &&
2920 (CurrentToken() == Token::kIDENT) && 2920 (CurrentToken() == Token::kIDENT) &&
2921 CurrentLiteral()->Equals("patch")) { 2921 CurrentLiteral()->Equals("patch")) {
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 = *ExpectClassIdentifier("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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3142 ConsumeToken(); 3142 ConsumeToken();
3143 result_type = Type::VoidType(); 3143 result_type = Type::VoidType();
3144 } else if (!IsFunctionTypeAliasName()) { 3144 } else if (!IsFunctionTypeAliasName()) {
3145 // Type annotations in typedef are never ignored, even in unchecked mode. 3145 // Type annotations in typedef are never ignored, even in unchecked mode.
3146 // Wait until we have an owner class before resolving the result type. 3146 // Wait until we have an owner class before resolving the result type.
3147 result_type = ParseType(ClassFinalizer::kDoNotResolve); 3147 result_type = ParseType(ClassFinalizer::kDoNotResolve);
3148 } 3148 }
3149 3149
3150 const intptr_t alias_name_pos = TokenPos(); 3150 const intptr_t alias_name_pos = TokenPos();
3151 const String* alias_name = 3151 const String* alias_name =
3152 ExpectTypeIdentifier("function alias name expected"); 3152 ExpectClassIdentifier("function alias name expected");
3153 3153
3154 // Parse the type parameters of the function type. 3154 // Parse the type parameters of the function type.
3155 ParseTypeParameters(alias_owner); 3155 ParseTypeParameters(alias_owner);
3156 // At this point, the type parameters have been parsed, so we can resolve the 3156 // At this point, the type parameters have been parsed, so we can resolve the
3157 // result type. 3157 // result type.
3158 if (!result_type.IsNull()) { 3158 if (!result_type.IsNull()) {
3159 ResolveTypeFromClass(alias_owner, 3159 ResolveTypeFromClass(alias_owner,
3160 ClassFinalizer::kTryResolve, 3160 ClassFinalizer::kTryResolve,
3161 &result_type); 3161 &result_type);
3162 } 3162 }
(...skipping 33 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,
3217 script_)); 3217 script_));
3218 // This alias should not be marked as finalized yet, since it needs to be 3218 // This alias should not be marked as finalized yet, since it needs to be
3219 // checked in the class finalizer for illegal self references. 3219 // checked in the class finalizer for illegal self references.
3220 ASSERT(!function_type_alias.IsCanonicalSignatureClass()); 3220 ASSERT(!function_type_alias.IsCanonicalSignatureClass());
3221 ASSERT(!function_type_alias.is_finalized()); 3221 ASSERT(!function_type_alias.is_finalized());
3222 library_.AddClass(function_type_alias); 3222 library_.AddClass(function_type_alias);
3223 ExpectSemicolon(); 3223 ExpectSemicolon();
3224 pending_classes.Add(function_type_alias, Heap::kOld); 3224 pending_classes.Add(function_type_alias, Heap::kOld);
3225 } 3225 }
3226 3226
3227 3227
3228 void Parser::ParseInterfaceDefinition( 3228 void Parser::ParseInterfaceDefinition(
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 = *ExpectClassIdentifier("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::ExpectClassIdentifier(const char* msg) {
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(msg);
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()) {
7633 } else { 7634 return obj.raw();
7634 obj = lib.LookupObject(*qual_ident.ident); 7635 }
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 a name by checking the global scope of the current
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 TRACE_PARSER("ResolveNameInCurrentLibraryScope");
7656 Object& obj = Object::Handle(LookupNameInLibrary(library_, name));
7657 if (obj.IsNull()) {
7658 // Name is not found in current library. Check scope of all
7659 // imported libraries.
7660 String& first_lib_url = String::Handle();
7661 Library& lib = Library::Handle();
7662 intptr_t num_imports = library_.num_imports();
7663 Object& resolved_obj = Object::Handle();
7664 for (int i = 0; i < num_imports; i++) {
7665 lib ^= library_.ImportAt(i);
7666 resolved_obj = LookupNameInLibrary(lib, name);
7667 if (!resolved_obj.IsNull()) {
7668 if (!first_lib_url.IsNull()) {
7669 // Found duplicate definition.
7670 ErrorMsg(ident_pos,
7671 "ambiguous reference: "
7672 "'%s' is defined in library '%s' and also in '%s'",
7673 name.ToCString(),
7674 first_lib_url.ToCString(),
7675 String::Handle(lib.url()).ToCString());
7676 } else {
7677 first_lib_url = lib.url();
7678 obj = resolved_obj.raw();
7679 }
7680 }
7681 }
7682 }
7683 return obj.raw();
7684 }
7685
7686
7687 RawClass* Parser::ResolveClassInCurrentLibraryScope(intptr_t ident_pos,
7688 const String& name) {
7689 const Object& obj =
7690 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, name));
7691 if (obj.IsClass()) {
7692 return Class::Cast(obj).raw();
7693 }
7694 return Class::null();
7695 }
7696
7697
7698 // Resolve an identifier by checking the global scope of the current
7699 // library. If not found in the current library, then look in the scopes
7700 // of all libraries that are imported without a library prefix.
7701 // Issue an error if the identifier is not found in the global scope
7702 // of the current library, but is defined in more than one imported
7703 // library, i.e. if the identifier cannot be resolved unambiguously.
7704 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos,
7705 const String& ident) {
7706 TRACE_PARSER("ResolveIdentInCurrentLibraryScope");
7707 const Object& obj =
7708 Object::Handle(ResolveNameInCurrentLibraryScope(ident_pos, ident));
7636 if (obj.IsClass()) { 7709 if (obj.IsClass()) {
7637 const Class& cls = Class::Cast(obj); 7710 const Class& cls = Class::Cast(obj);
7638 return new PrimaryNode(qual_ident.ident_pos, Class::ZoneHandle(cls.raw())); 7711 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw()));
7639 } 7712 } else if (obj.IsField()) {
7640 if (obj.IsField()) {
7641 const Field& field = Field::Cast(obj); 7713 const Field& field = Field::Cast(obj);
7642 ASSERT(field.is_static()); 7714 ASSERT(field.is_static());
7643 return GenerateStaticFieldLookup(field, qual_ident.ident_pos); 7715 return GenerateStaticFieldLookup(field, ident_pos);
7644 } 7716 } else if (obj.IsFunction()) {
7645 if (obj.IsFunction()) {
7646 const Function& func = Function::Cast(obj); 7717 const Function& func = Function::Cast(obj);
7647 ASSERT(func.is_static()); 7718 ASSERT(func.is_static());
7648 return new PrimaryNode(qual_ident.ident_pos, 7719 if (func.IsGetterFunction() || func.IsSetterFunction()) {
7649 Function::ZoneHandle(func.raw())); 7720 return new StaticGetterNode(ident_pos,
7721 /* receiver */ NULL,
7722 /* is_super_getter */ false,
7723 Class::ZoneHandle(func.Owner()),
7724 ident);
7725
7726 } else {
7727 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw()));
7728 }
7650 } else { 7729 } else {
7651 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); 7730 ASSERT(obj.IsNull() || obj.IsLibraryPrefix());
7652 } 7731 }
7653 7732 // Lexically unresolved primary identifiers are referenced by their name.
7654 // Check if there is a global getter or setter for qual_ident. 7733 return new PrimaryNode(ident_pos, ident);
7655 // We create a getter node even if a getter doesn't exist since 7734 }
7656 // qual_ident could be followed by an assignment which will convert it 7735
7657 // to a setter node. If there is no assignment we will get an error 7736
7658 // when we try to invoke the getter. 7737 RawObject* Parser::ResolveNameInPrefixScope(intptr_t ident_pos,
7659 String& accessor_name = String::Handle(Field::GetterName(*qual_ident.ident)); 7738 const LibraryPrefix& prefix,
7660 if (resolve_locally) { 7739 const String& name) {
7661 obj = lib.LookupLocalObject(accessor_name); 7740 TRACE_PARSER("ResolveNameInPrefixScope");
7662 } else { 7741 Library& lib = Library::Handle();
7663 obj = lib.LookupObject(accessor_name); 7742 String& first_lib_url = String::Handle();
7664 } 7743 Object& obj = Object::Handle();
7744 Object& resolved_obj = Object::Handle();
7745 for (intptr_t i = 0; i < prefix.num_libs(); i++) {
7746 lib = prefix.GetLibrary(i);
7747 ASSERT(!lib.IsNull());
7748 resolved_obj = LookupNameInLibrary(lib, name);
7749 if (!resolved_obj.IsNull()) {
7750 obj = resolved_obj.raw();
7751 if (first_lib_url.IsNull()) {
7752 first_lib_url = lib.url();
7753 } else {
7754 ErrorMsg(ident_pos,
7755 "ambiguous reference: '%s.%s' is defined in '%s' and '%s'",
7756 String::Handle(prefix.name()).ToCString(),
7757 name.ToCString(),
7758 first_lib_url.ToCString(),
7759 String::Handle(lib.url()).ToCString());
7760 }
7761 }
7762 }
7763 return obj.raw();
7764 }
7765
7766
7767 RawClass* Parser::ResolveClassInPrefixScope(intptr_t ident_pos,
7768 const LibraryPrefix& prefix,
7769 const String& name) {
7770 const Object& obj =
7771 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, name));
7772 if (obj.IsClass()) {
7773 return Class::Cast(obj).raw();
7774 }
7775 return Class::null();
7776 }
7777
7778
7779 // Do a lookup for the identifier in the scope of the specified
7780 // library prefix. This means trying to resolve it locally in all of the
7781 // libraries present in the library prefix. If there are multiple libraries
7782 // with the name, issue an ambiguous reference error.
7783 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos,
7784 const LibraryPrefix& prefix,
7785 const String& ident) {
7786 TRACE_PARSER("ResolveIdentInPrefixScope");
7787 Object& obj =
7788 Object::Handle(ResolveNameInPrefixScope(ident_pos, prefix, ident));
7665 if (obj.IsNull()) { 7789 if (obj.IsNull()) {
7666 accessor_name = Field::SetterName(*qual_ident.ident); 7790 // Unresolved prefixed primary identifier.
7667 if (resolve_locally) { 7791 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved",
7668 obj = lib.LookupLocalObject(accessor_name); 7792 String::Handle(prefix.name()).ToCString(),
7669 } else { 7793 ident.ToCString());
7670 obj = lib.LookupObject(accessor_name); 7794 }
7671 } 7795 if (obj.IsClass()) {
7672 } 7796 const Class& cls = Class::Cast(obj);
7673 if (!obj.IsNull()) { 7797 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw()));
7674 ASSERT(obj.IsFunction()); 7798 } else if (obj.IsField()) {
7799 const Field& field = Field::Cast(obj);
7800 ASSERT(field.is_static());
7801 return GenerateStaticFieldLookup(field, ident_pos);
7802 } else if (obj.IsFunction()) {
7675 const Function& func = Function::Cast(obj); 7803 const Function& func = Function::Cast(obj);
7676 ASSERT(func.is_static()); 7804 ASSERT(func.is_static());
7677 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); 7805 if (func.IsGetterFunction() || func.IsSetterFunction()) {
7678 return new StaticGetterNode(qual_ident.ident_pos, 7806 return new StaticGetterNode(ident_pos,
7679 NULL, 7807 /* receiver */ NULL,
7680 false, 7808 /* is_super_getter */ false,
7681 Class::ZoneHandle(func.Owner()), 7809 Class::ZoneHandle(func.Owner()),
7682 *qual_ident.ident); 7810 ident);
7683 } 7811
7684 if (qual_ident.lib_prefix != NULL) { 7812 } else {
7685 return NULL; 7813 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw()));
7814 }
7815 } else {
7816 // TODO(hausner): Should this be an error? It is not meaningful to
7817 // reference a library prefix defined in an imported library.
7818 ASSERT(obj.IsLibraryPrefix());
7686 } 7819 }
7687 // Lexically unresolved primary identifiers are referenced by their name. 7820 // Lexically unresolved primary identifiers are referenced by their name.
7688 return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident); 7821 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 } 7822 }
7714 7823
7715 7824
7716 // Resolve identifier, issue an error message if the name refers to 7825 // Resolve identifier, issue an error message if the name refers to
7717 // a class/interface or a type parameter. Issue an error message if 7826 // 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. 7827 // 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 7828 // 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 7829 // if we're compiling an instance method, or issue an error message
7721 // if we're compiling a static method. 7830 // if we're compiling a static method.
7722 AstNode* Parser::ResolveIdent(intptr_t ident_pos, 7831 AstNode* Parser::ResolveIdent(intptr_t ident_pos,
(...skipping 12 matching lines...) Expand all
7735 TypeParameter& type_param = TypeParameter::Handle( 7844 TypeParameter& type_param = TypeParameter::Handle(
7736 scope_class.LookupTypeParameter(ident, ident_pos)); 7845 scope_class.LookupTypeParameter(ident, ident_pos));
7737 if (!type_param.IsNull()) { 7846 if (!type_param.IsNull()) {
7738 String& type_param_name = String::Handle(type_param.name()); 7847 String& type_param_name = String::Handle(type_param.name());
7739 ErrorMsg(ident_pos, "illegal use of type parameter %s", 7848 ErrorMsg(ident_pos, "illegal use of type parameter %s",
7740 type_param_name.ToCString()); 7849 type_param_name.ToCString());
7741 } 7850 }
7742 } 7851 }
7743 // Not found in the local scope, and the name is not a type parameter. 7852 // 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 7853 // Try finding the variable in the library scope (current library
7745 // and all libraries imported by it). 7854 // and all libraries imported by it without a library prefix).
7746 QualIdent qual_ident; 7855 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 } 7856 }
7754 if (resolved->IsPrimaryNode()) { 7857 if (resolved->IsPrimaryNode()) {
7755 PrimaryNode* primary = resolved->AsPrimaryNode(); 7858 PrimaryNode* primary = resolved->AsPrimaryNode();
7756 if (primary->primary().IsString()) { 7859 if (primary->primary().IsString()) {
7757 // We got an unresolved name. If we are compiling a static 7860 // We got an unresolved name. If we are compiling a static
7758 // method, this is an error. In an instance method, we convert 7861 // method, this is an error. In an instance method, we convert
7759 // the unresolved name to an instance field access, since a 7862 // the unresolved name to an instance field access, since a
7760 // subclass might define a field with this name. 7863 // subclass might define a field with this name.
7761 if (current_function().is_static()) { 7864 if (current_function().is_static()) {
7762 ErrorMsg(ident_pos, "identifier '%s' is not declared in this scope", 7865 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()) { 8803 if (!type_param.IsNull()) {
8701 const String& type_param_name = String::Handle(type_param.name()); 8804 const String& type_param_name = String::Handle(type_param.name());
8702 ErrorMsg(qual_ident.ident_pos, 8805 ErrorMsg(qual_ident.ident_pos,
8703 "illegal use of type parameter %s", 8806 "illegal use of type parameter %s",
8704 type_param_name.ToCString()); 8807 type_param_name.ToCString());
8705 } 8808 }
8706 } 8809 }
8707 // This is a non-local unqualified identifier so resolve the 8810 // This is a non-local unqualified identifier so resolve the
8708 // identifier locally in the main app library and all libraries 8811 // identifier locally in the main app library and all libraries
8709 // imported by it. 8812 // imported by it.
8710 primary = ResolveIdentInLibraryScope(library_, 8813 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos,
8711 qual_ident, 8814 *qual_ident.ident);
8712 kResolveIncludingImports);
8713 } 8815 }
8714 } else { 8816 } else {
8715 // This is a qualified identifier with a library prefix so resolve 8817 // This is a qualified identifier with a library prefix so resolve
8716 // the identifier locally in that library (we do not include the 8818 // the identifier locally in that library (we do not include the
8717 // libraries imported by that library). 8819 // libraries imported by that library).
8718 primary = ResolveIdentInLibraryPrefixScope(*(qual_ident.lib_prefix), 8820 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos,
8719 qual_ident); 8821 *qual_ident.lib_prefix,
8822 *qual_ident.ident);
8720 } 8823 }
8721 ASSERT(primary != NULL); 8824 ASSERT(primary != NULL);
8722 } else if (CurrentToken() == Token::kTHIS) { 8825 } else if (CurrentToken() == Token::kTHIS) {
8723 const String& this_name = String::Handle(Symbols::This()); 8826 const String& this_name = String::Handle(Symbols::This());
8724 LocalVariable* local = LookupLocalScope(this_name); 8827 LocalVariable* local = LookupLocalScope(this_name);
8725 if (local == NULL) { 8828 if (local == NULL) {
8726 ErrorMsg("receiver 'this' is not in scope"); 8829 ErrorMsg("receiver 'this' is not in scope");
8727 } 8830 }
8728 primary = new LoadLocalNode(TokenPos(), local); 8831 primary = new LoadLocalNode(TokenPos(), local);
8729 ConsumeToken(); 8832 ConsumeToken();
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
9085 void Parser::SkipQualIdent() { 9188 void Parser::SkipQualIdent() {
9086 ASSERT(IsIdentifier()); 9189 ASSERT(IsIdentifier());
9087 ConsumeToken(); 9190 ConsumeToken();
9088 if (CurrentToken() == Token::kPERIOD) { 9191 if (CurrentToken() == Token::kPERIOD) {
9089 ConsumeToken(); // Consume the kPERIOD token. 9192 ConsumeToken(); // Consume the kPERIOD token.
9090 ExpectIdentifier("identifier expected after '.'"); 9193 ExpectIdentifier("identifier expected after '.'");
9091 } 9194 }
9092 } 9195 }
9093 9196
9094 } // namespace dart 9197 } // namespace dart
OLDNEW
« no previous file with comments | « 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