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

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

Issue 352523002: Fix parsing and resolving of prefixed names (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 5 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 "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 if (i.CheckJavascriptIntegerOverflow()) { 425 if (i.CheckJavascriptIntegerOverflow()) {
426 ReportError(TokenPos(), 426 ReportError(TokenPos(),
427 "Integer literal does not fit in a Javascript integer: %s.", 427 "Integer literal does not fit in a Javascript integer: %s.",
428 i.ToCString()); 428 i.ToCString());
429 } 429 }
430 } 430 }
431 return ri; 431 return ri;
432 } 432 }
433 433
434 434
435 // A QualIdent is an optionally qualified identifier.
436 struct QualIdent {
437 QualIdent() {
438 Clear();
439 }
440 void Clear() {
441 lib_prefix = NULL;
442 ident_pos = 0;
443 ident = NULL;
444 }
445 LibraryPrefix* lib_prefix;
446 intptr_t ident_pos;
447 String* ident;
448 };
449
450
451 struct ParamDesc { 435 struct ParamDesc {
452 ParamDesc() 436 ParamDesc()
453 : type(NULL), 437 : type(NULL),
454 name_pos(0), 438 name_pos(0),
455 name(NULL), 439 name(NULL),
456 default_value(NULL), 440 default_value(NULL),
457 metadata(NULL), 441 metadata(NULL),
458 var(NULL), 442 var(NULL),
459 is_final(false), 443 is_final(false),
460 is_field_initializer(false), 444 is_field_initializer(false),
(...skipping 2662 matching lines...) Expand 10 before | Expand all | Expand 10 after
3123 ExpectIdentifier("identifier expected"); 3107 ExpectIdentifier("identifier expected");
3124 ExpectToken(Token::kASSIGN); 3108 ExpectToken(Token::kASSIGN);
3125 SetAllowFunctionLiterals(false); 3109 SetAllowFunctionLiterals(false);
3126 SkipExpr(); 3110 SkipExpr();
3127 SetAllowFunctionLiterals(true); 3111 SetAllowFunctionLiterals(true);
3128 } 3112 }
3129 } while (CurrentToken() == Token::kCOMMA); 3113 } while (CurrentToken() == Token::kCOMMA);
3130 } 3114 }
3131 3115
3132 3116
3133 void Parser::ParseQualIdent(QualIdent* qual_ident) { 3117 // If the current identifier is a library prefix followed by a period,
3134 TRACE_PARSER("ParseQualIdent"); 3118 // consume the identifier and period, and return the resolved library
3119 // prefix.
3120 RawLibraryPrefix* Parser::ParsePrefix() {
3135 ASSERT(IsIdentifier()); 3121 ASSERT(IsIdentifier());
3122 // A library prefix can never stand by itself. It must be followed by
3123 // a period.
3124 if (LookaheadToken(1) != Token::kPERIOD) {
3125 return LibraryPrefix::null();
3126 }
3127 const String& ident = *CurrentLiteral();
3128 // If the identifier is shadowed by a local definition, it cannot be
3129 // a library prefix.
3130 if (!is_top_level_ &&
3131 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) {
3132 return LibraryPrefix::null();
3133 }
3134 // If the identifier is shadowed by a type parameter, it cannot be
3135 // a library prefix.
3136 ASSERT(!current_class().IsNull()); 3136 ASSERT(!current_class().IsNull());
3137 qual_ident->ident_pos = TokenPos(); 3137 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) {
3138 qual_ident->ident = CurrentLiteral(); 3138 return LibraryPrefix::null();
3139 qual_ident->lib_prefix = NULL;
3140 ConsumeToken();
3141 if (CurrentToken() == Token::kPERIOD) {
3142 // An identifier cannot be resolved in a local scope when top level parsing.
3143 if (is_top_level_ ||
3144 !ResolveIdentInLocalScope(qual_ident->ident_pos,
3145 *(qual_ident->ident),
3146 NULL)) {
3147 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(I);
3148 if (!current_class().IsMixinApplication()) {
3149 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
3150 } else {
3151 // TODO(hausner): Should we resolve the prefix via the library scope
3152 // rather than via the class?
3153 Class& cls = Class::Handle(I, parsed_function()->function().origin());
3154 lib_prefix = cls.LookupLibraryPrefix(*(qual_ident->ident));
3155 }
3156 if (!lib_prefix.IsNull()) {
3157 // We have a library prefix qualified identifier, unless the prefix is
3158 // shadowed by a type parameter in scope.
3159 if (current_class().IsNull() ||
3160 (current_class().LookupTypeParameter(*(qual_ident->ident)) ==
3161 TypeParameter::null())) {
3162 ConsumeToken(); // Consume the kPERIOD token.
3163 qual_ident->lib_prefix = &lib_prefix;
3164 qual_ident->ident_pos = TokenPos();
3165 qual_ident->ident =
3166 ExpectIdentifier("identifier expected after '.'");
3167 }
3168 }
3169 }
3170 } 3139 }
3140 // We have a name that is not shadowed, followed by a period.
3141 // Look in the library name space of the class whether there is a
3142 // prefix with this name.
3143 LibraryPrefix& prefix = LibraryPrefix::Handle(I);
3144 if (!current_class().IsMixinApplication()) {
3145 prefix = current_class().LookupLibraryPrefix(ident);
3146 } else {
3147 // TODO(hausner): Should we resolve the prefix via the library scope
3148 // rather than via the class?
regis 2014/06/23 17:32:36 Isn't it a good time to remove this TODO?
hausner 2014/06/23 23:27:15 It is. As it turns out, the library_ field cached
3149 Class& cls = Class::Handle(I, parsed_function()->function().origin());
3150 prefix = cls.LookupLibraryPrefix(ident);
3151 }
3152 // If the identifier is a prefix, consume it and the following period.
3153 if (!prefix.IsNull()) {
3154 ConsumeToken();
3155 ASSERT(CurrentToken() == Token::kPERIOD); // We checked above.
3156 ConsumeToken();
3157 }
3158 return prefix.raw();
3171 } 3159 }
3172 3160
3173 3161
3174 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { 3162 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
3175 TRACE_PARSER("ParseMethodOrConstructor"); 3163 TRACE_PARSER("ParseMethodOrConstructor");
3176 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); 3164 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter());
3177 ASSERT(method->type != NULL); 3165 ASSERT(method->type != NULL);
3178 ASSERT(method->name_pos > 0); 3166 ASSERT(method->name_pos > 0);
3179 ASSERT(current_member_ == method); 3167 ASSERT(current_member_ == method);
3180 3168
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3279 } 3267 }
3280 if (method->has_external) { 3268 if (method->has_external) {
3281 ReportError(TokenPos(), 3269 ReportError(TokenPos(),
3282 "external factory constructor '%s' may not have redirection", 3270 "external factory constructor '%s' may not have redirection",
3283 method->name->ToCString()); 3271 method->name->ToCString());
3284 } 3272 }
3285 ConsumeToken(); 3273 ConsumeToken();
3286 const intptr_t type_pos = TokenPos(); 3274 const intptr_t type_pos = TokenPos();
3287 is_redirecting = true; 3275 is_redirecting = true;
3288 const AbstractType& type = AbstractType::Handle(I, 3276 const AbstractType& type = AbstractType::Handle(I,
3289 ParseType(ClassFinalizer::kResolveTypeParameters)); 3277 ParseType(ClassFinalizer::kResolveTypeParameters,
3278 false, // Deferred types not allowed.
3279 false)); // Do not consume prefix if unresolved.
3290 if (!type.IsMalformed() && type.IsTypeParameter()) { 3280 if (!type.IsMalformed() && type.IsTypeParameter()) {
3291 // Replace the type with a malformed type and compile a throw when called. 3281 // Replace the type with a malformed type and compile a throw when called.
3292 redirection_type = ClassFinalizer::NewFinalizedMalformedType( 3282 redirection_type = ClassFinalizer::NewFinalizedMalformedType(
3293 Error::Handle(I), // No previous error. 3283 Error::Handle(I), // No previous error.
3294 script_, 3284 script_,
3295 type_pos, 3285 type_pos,
3296 "factory '%s' may not redirect to type parameter '%s'", 3286 "factory '%s' may not redirect to type parameter '%s'",
3297 method->name->ToCString(), 3287 method->name->ToCString(),
3298 String::Handle(I, type.UserVisibleName()).ToCString()); 3288 String::Handle(I, type.UserVisibleName()).ToCString());
3299 } else { 3289 } else {
(...skipping 2763 matching lines...) Expand 10 before | Expand all | Expand 10 after
6063 return false; 6053 return false;
6064 } 6054 }
6065 6055
6066 6056
6067 // Returns true if the current token is kIDENT or a pseudo-keyword. 6057 // Returns true if the current token is kIDENT or a pseudo-keyword.
6068 bool Parser::IsIdentifier() { 6058 bool Parser::IsIdentifier() {
6069 return Token::IsIdentifier(CurrentToken()); 6059 return Token::IsIdentifier(CurrentToken());
6070 } 6060 }
6071 6061
6072 6062
6063 // Returns true if the next tokens can be parsed as a an optionally
6064 // qualified identifier: [ident '.'] ident.
6065 // Current token position is not restored.
6066 bool Parser::TryParseQualIdent() {
6067 if (CurrentToken() != Token::kIDENT) {
6068 return false;
6069 }
6070 ConsumeToken();
6071 if (CurrentToken() == Token::kPERIOD) {
6072 ConsumeToken();
6073 if (CurrentToken() != Token::kIDENT) {
6074 return false;
6075 }
6076 ConsumeToken();
6077 }
6078 return true;
6079 }
6080
6081
6073 // Returns true if the next tokens can be parsed as a type with optional 6082 // Returns true if the next tokens can be parsed as a type with optional
6074 // type parameters. Current token position is not restored. 6083 // type parameters. Current token position is not restored.
6075 bool Parser::TryParseOptionalType() { 6084 bool Parser::TryParseOptionalType() {
6076 if (CurrentToken() == Token::kIDENT) { 6085 if (CurrentToken() == Token::kIDENT) {
6077 QualIdent type_name; 6086 if (!TryParseQualIdent()) {
6078 ParseQualIdent(&type_name); 6087 return false;
6088 }
6079 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) { 6089 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) {
6080 return false; 6090 return false;
6081 } 6091 }
6082 } 6092 }
6083 return true; 6093 return true;
6084 } 6094 }
6085 6095
6086 6096
6087 // Returns true if the next tokens can be parsed as a type with optional 6097 // Returns true if the next tokens can be parsed as a type with optional
6088 // type parameters, or keyword "void". 6098 // type parameters, or keyword "void".
(...skipping 3397 matching lines...) Expand 10 before | Expand all | Expand 10 after
9486 } 9496 }
9487 } 9497 }
9488 return resolved; 9498 return resolved;
9489 } 9499 }
9490 9500
9491 9501
9492 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and 9502 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and
9493 // finalize it according to the given type finalization mode. 9503 // finalize it according to the given type finalization mode.
9494 RawAbstractType* Parser::ParseType( 9504 RawAbstractType* Parser::ParseType(
9495 ClassFinalizer::FinalizationKind finalization, 9505 ClassFinalizer::FinalizationKind finalization,
9496 bool allow_deferred_type) { 9506 bool allow_deferred_type,
9507 bool consume_unresolved_prefix) {
9497 TRACE_PARSER("ParseType"); 9508 TRACE_PARSER("ParseType");
9498 CheckToken(Token::kIDENT, "type name expected"); 9509 CheckToken(Token::kIDENT, "type name expected");
9499 QualIdent type_name; 9510 intptr_t ident_pos = TokenPos();
9511 LibraryPrefix& prefix = LibraryPrefix::Handle(I);
9512 String& type_name = String::Handle(I);;
9513
9500 if (finalization == ClassFinalizer::kIgnore) { 9514 if (finalization == ClassFinalizer::kIgnore) {
9501 if (!is_top_level_ && (current_block_ != NULL)) { 9515 if (!is_top_level_ && (current_block_ != NULL)) {
9502 // Add the library prefix or type class name to the list of referenced 9516 // Add the library prefix or type class name to the list of referenced
9503 // names of this scope, even if the type is ignored. 9517 // names of this scope, even if the type is ignored.
9504 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); 9518 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral());
9505 } 9519 }
9506 SkipQualIdent(); 9520 SkipQualIdent();
9507 } else { 9521 } else {
9508 ParseQualIdent(&type_name); 9522 prefix = ParsePrefix();
9509 // An identifier cannot be resolved in a local scope when top level parsing. 9523 type_name = CurrentLiteral()->raw();
9510 if (!is_top_level_ && 9524 ConsumeToken();
9511 (type_name.lib_prefix == NULL) && 9525
9512 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { 9526 // Check whether we have a malformed qualified type name if the caller
9527 // requests to consume unresolved prefix names:
9528 // If we didn't see a valid prefix but the identifier is followed by
9529 // a period and another identifier, consume the qualified identifier
9530 // and create a malformed type.
9531 if (consume_unresolved_prefix &&
9532 prefix.IsNull() &&
9533 (CurrentToken() == Token::kPERIOD) &&
9534 (Token::IsIdentifier(LookaheadToken(1)))) {
9535 if (!is_top_level_ && (current_block_ != NULL)) {
9536 // Add the unresolved prefix name to the list of referenced
9537 // names of this scope.
9538 current_block_->scope->AddReferencedName(TokenPos(), type_name);
9539 }
9540 ConsumeToken(); // Period token.
9541 ASSERT(IsIdentifier());
9542 String& qualified_name = String::Handle(I, type_name.raw());
9543 qualified_name = String::Concat(qualified_name, Symbols::Dot());
9544 qualified_name = String::Concat(qualified_name, *CurrentLiteral());
9545 ConsumeToken();
9513 // The type is malformed. Skip over its type arguments. 9546 // The type is malformed. Skip over its type arguments.
9514 ParseTypeArguments(ClassFinalizer::kIgnore); 9547 ParseTypeArguments(ClassFinalizer::kIgnore);
9515 return ClassFinalizer::NewFinalizedMalformedType( 9548 return ClassFinalizer::NewFinalizedMalformedType(
9516 Error::Handle(I), // No previous error. 9549 Error::Handle(I), // No previous error.
9517 script_, 9550 script_,
9518 type_name.ident_pos, 9551 ident_pos,
9519 "using '%s' in this context is invalid", 9552 "qualified name '%s' does not refer to a type",
9520 type_name.ident->ToCString()); 9553 qualified_name.ToCString());
9521 } 9554 }
9522 if ((type_name.lib_prefix != NULL) && 9555
9523 type_name.lib_prefix->is_deferred_load() && 9556 // If parsing inside a local scope, check whether the type name
9524 !allow_deferred_type) { 9557 // is shadowed by a local declaration.
9558 if (!is_top_level_ &&
9559 (prefix.IsNull()) &&
9560 ResolveIdentInLocalScope(ident_pos, type_name, NULL)) {
9561 // The type is malformed. Skip over its type arguments.
9525 ParseTypeArguments(ClassFinalizer::kIgnore); 9562 ParseTypeArguments(ClassFinalizer::kIgnore);
9526 return ClassFinalizer::NewFinalizedMalformedType( 9563 return ClassFinalizer::NewFinalizedMalformedType(
9527 Error::Handle(I), // No previous error. 9564 Error::Handle(I), // No previous error.
9528 script_, 9565 script_,
9529 type_name.ident_pos, 9566 ident_pos,
9567 "using '%s' in this context is invalid",
9568 type_name.ToCString());
9569 }
9570 if (!prefix.IsNull() && prefix.is_deferred_load() && !allow_deferred_type) {
9571 ParseTypeArguments(ClassFinalizer::kIgnore);
9572 return ClassFinalizer::NewFinalizedMalformedType(
9573 Error::Handle(I), // No previous error.
9574 script_,
9575 ident_pos,
9530 "using deferred type '%s.%s' is invalid", 9576 "using deferred type '%s.%s' is invalid",
9531 String::Handle(I, type_name.lib_prefix->name()).ToCString(), 9577 String::Handle(I, prefix.name()).ToCString(),
9532 type_name.ident->ToCString()); 9578 type_name.ToCString());
9533 } 9579 }
9534 } 9580 }
9535 Object& type_class = Object::Handle(I); 9581 Object& type_class = Object::Handle(I);
9536 // Leave type_class as null if type finalization mode is kIgnore. 9582 // Leave type_class as null if type finalization mode is kIgnore.
9537 if (finalization != ClassFinalizer::kIgnore) { 9583 if (finalization != ClassFinalizer::kIgnore) {
9538 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(I); 9584 type_class = UnresolvedClass::New(prefix, type_name, ident_pos);
9539 if (type_name.lib_prefix != NULL) {
9540 lib_prefix = type_name.lib_prefix->raw();
9541 }
9542 type_class = UnresolvedClass::New(lib_prefix,
9543 *type_name.ident,
9544 type_name.ident_pos);
9545 } 9585 }
9546 TypeArguments& type_arguments = TypeArguments::Handle( 9586 TypeArguments& type_arguments = TypeArguments::Handle(
9547 I, ParseTypeArguments(finalization)); 9587 I, ParseTypeArguments(finalization));
9548 if (finalization == ClassFinalizer::kIgnore) { 9588 if (finalization == ClassFinalizer::kIgnore) {
9549 return Type::DynamicType(); 9589 return Type::DynamicType();
9550 } 9590 }
9551 AbstractType& type = AbstractType::Handle( 9591 AbstractType& type = AbstractType::Handle(
9552 I, Type::New(type_class, type_arguments, type_name.ident_pos)); 9592 I, Type::New(type_class, type_arguments, ident_pos));
9553 if (finalization >= ClassFinalizer::kResolveTypeParameters) { 9593 if (finalization >= ClassFinalizer::kResolveTypeParameters) {
9554 ResolveTypeFromClass(current_class(), finalization, &type); 9594 ResolveTypeFromClass(current_class(), finalization, &type);
9555 if (finalization >= ClassFinalizer::kCanonicalize) { 9595 if (finalization >= ClassFinalizer::kCanonicalize) {
9556 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); 9596 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization);
9557 } 9597 }
9558 } 9598 }
9559 return type.raw(); 9599 return type.raw();
9560 } 9600 }
9561 9601
9562 9602
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
10084 TRACE_PARSER("ParseNewOperator"); 10124 TRACE_PARSER("ParseNewOperator");
10085 const intptr_t new_pos = TokenPos(); 10125 const intptr_t new_pos = TokenPos();
10086 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); 10126 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
10087 bool is_const = (op_kind == Token::kCONST); 10127 bool is_const = (op_kind == Token::kCONST);
10088 if (!IsIdentifier()) { 10128 if (!IsIdentifier()) {
10089 ReportError("type name expected"); 10129 ReportError("type name expected");
10090 } 10130 }
10091 intptr_t type_pos = TokenPos(); 10131 intptr_t type_pos = TokenPos();
10092 // Can't allocate const objects of a deferred type. 10132 // Can't allocate const objects of a deferred type.
10093 const bool allow_deferred_type = !is_const; 10133 const bool allow_deferred_type = !is_const;
10134 const bool consume_unresolved_prefix = false;
10094 AbstractType& type = AbstractType::Handle(I, 10135 AbstractType& type = AbstractType::Handle(I,
10095 ParseType(ClassFinalizer::kCanonicalizeWellFormed, allow_deferred_type)); 10136 ParseType(ClassFinalizer::kCanonicalizeWellFormed,
10137 allow_deferred_type,
10138 consume_unresolved_prefix));
10096 // In case the type is malformed, throw a dynamic type error after finishing 10139 // In case the type is malformed, throw a dynamic type error after finishing
10097 // parsing the instance creation expression. 10140 // parsing the instance creation expression.
10098 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { 10141 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) {
10099 // Replace the type with a malformed type. 10142 // Replace the type with a malformed type.
10100 type = ClassFinalizer::NewFinalizedMalformedType( 10143 type = ClassFinalizer::NewFinalizedMalformedType(
10101 Error::Handle(I), // No previous error. 10144 Error::Handle(I), // No previous error.
10102 script_, 10145 script_,
10103 type_pos, 10146 type_pos,
10104 "%s'%s' cannot be instantiated", 10147 "%s'%s' cannot be instantiated",
10105 type.IsTypeParameter() ? "type parameter " : "", 10148 type.IsTypeParameter() ? "type parameter " : "",
10106 type.IsTypeParameter() ? 10149 type.IsTypeParameter() ?
10107 String::Handle(I, type.UserVisibleName()).ToCString() : 10150 String::Handle(I, type.UserVisibleName()).ToCString() :
10108 "dynamic"); 10151 "dynamic");
10109 } 10152 }
10110 10153
10111 // The grammar allows for an optional ('.' identifier)? after the type, which 10154 // The grammar allows for an optional ('.' identifier)? after the type, which
10112 // is a named constructor. Note that ParseType() above will not consume it as 10155 // is a named constructor. Note that we tell ParseType() above not to
10113 // part of a misinterpreted qualified identifier, because only a valid library 10156 // consume it as part of a misinterpreted qualified identifier. Only a
10114 // prefix is accepted as qualifier. 10157 // valid library prefix is accepted as qualifier.
10115 String* named_constructor = NULL; 10158 String* named_constructor = NULL;
10116 if (CurrentToken() == Token::kPERIOD) { 10159 if (CurrentToken() == Token::kPERIOD) {
10117 ConsumeToken(); 10160 ConsumeToken();
10118 named_constructor = ExpectIdentifier("name of constructor expected"); 10161 named_constructor = ExpectIdentifier("name of constructor expected");
10119 } 10162 }
10120 10163
10121 // Parse constructor parameters. 10164 // Parse constructor parameters.
10122 CheckToken(Token::kLPAREN); 10165 CheckToken(Token::kLPAREN);
10123 intptr_t call_pos = TokenPos(); 10166 intptr_t call_pos = TokenPos();
10124 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); 10167 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
10475 ASSERT(!is_top_level_); 10518 ASSERT(!is_top_level_);
10476 AstNode* primary = NULL; 10519 AstNode* primary = NULL;
10477 const Token::Kind token = CurrentToken(); 10520 const Token::Kind token = CurrentToken();
10478 if (IsFunctionLiteral()) { 10521 if (IsFunctionLiteral()) {
10479 // The name of a literal function is visible from inside the function, but 10522 // The name of a literal function is visible from inside the function, but
10480 // must not collide with names in the scope declaring the literal. 10523 // must not collide with names in the scope declaring the literal.
10481 OpenBlock(); 10524 OpenBlock();
10482 primary = ParseFunctionStatement(true); 10525 primary = ParseFunctionStatement(true);
10483 CloseBlock(); 10526 CloseBlock();
10484 } else if (IsIdentifier()) { 10527 } else if (IsIdentifier()) {
10485 QualIdent qual_ident;
10486 intptr_t qual_ident_pos = TokenPos(); 10528 intptr_t qual_ident_pos = TokenPos();
10487 ParseQualIdent(&qual_ident); 10529 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(I, ParsePrefix());
10488 if (qual_ident.lib_prefix == NULL) { 10530 String& ident = *CurrentLiteral();
10489 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, 10531 ConsumeToken();
10490 *qual_ident.ident, 10532 if (prefix.IsNull()) {
10491 &primary)) { 10533 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) {
10492 // Check whether the identifier is a type parameter. 10534 // Check whether the identifier is a type parameter.
10493 if (!current_class().IsNull()) { 10535 if (!current_class().IsNull()) {
10494 TypeParameter& type_param = TypeParameter::ZoneHandle(I, 10536 TypeParameter& type_param = TypeParameter::ZoneHandle(I,
10495 current_class().LookupTypeParameter(*(qual_ident.ident))); 10537 current_class().LookupTypeParameter(ident));
10496 if (!type_param.IsNull()) { 10538 if (!type_param.IsNull()) {
10497 return new(I) PrimaryNode(qual_ident.ident_pos, type_param); 10539 return new(I) PrimaryNode(qual_ident_pos, type_param);
10498 } 10540 }
10499 } 10541 }
10500 // This is a non-local unqualified identifier so resolve the 10542 // This is a non-local unqualified identifier so resolve the
10501 // identifier locally in the main app library and all libraries 10543 // identifier locally in the main app library and all libraries
10502 // imported by it. 10544 // imported by it.
10503 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos, 10545 primary = ResolveIdentInCurrentLibraryScope(qual_ident_pos, ident);
10504 *qual_ident.ident);
10505 } 10546 }
10506 } else { 10547 } else {
10507 // This is a qualified identifier with a library prefix so resolve 10548 // This is a qualified identifier with a library prefix so resolve
10508 // the identifier locally in that library (we do not include the 10549 // the identifier locally in that library (we do not include the
10509 // libraries imported by that library). 10550 // libraries imported by that library).
10510 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos, 10551 primary = ResolveIdentInPrefixScope(qual_ident_pos, prefix, ident);
10511 *qual_ident.lib_prefix, 10552
10512 *qual_ident.ident);
10513 // If the identifier could not be resolved, throw a NoSuchMethodError. 10553 // If the identifier could not be resolved, throw a NoSuchMethodError.
10514 // Note: unlike in the case of an unqualified identifier, do not 10554 // Note: unlike in the case of an unqualified identifier, do not
10515 // interpret the unresolved identifier as an instance method or 10555 // interpret the unresolved identifier as an instance method or
10516 // instance getter call when compiling an instance method. 10556 // instance getter call when compiling an instance method.
10517 if (primary == NULL) { 10557 if (primary == NULL) {
10518 if (qual_ident.lib_prefix->is_deferred_load() && 10558 if (prefix.is_deferred_load() &&
10519 qual_ident.ident->Equals(Symbols::LoadLibrary())) { 10559 ident.Equals(Symbols::LoadLibrary())) {
10520 // Hack Alert: recognize special 'loadLibrary' call on the 10560 // Hack Alert: recognize special 'loadLibrary' call on the
10521 // prefix object. The prefix is the primary. Rewind parser and 10561 // prefix object. The prefix is the primary. Rewind parser and
10522 // let ParseSelectors() handle the loadLibrary call. 10562 // let ParseSelectors() handle the loadLibrary call.
10523 SetPosition(qual_ident_pos); 10563 SetPosition(qual_ident_pos);
10524 ConsumeToken(); // Prefix name. 10564 ConsumeToken(); // Prefix name.
10525 primary = new(I) LiteralNode(qual_ident_pos, *qual_ident.lib_prefix); 10565 primary = new(I) LiteralNode(qual_ident_pos, prefix);
10526 } else { 10566 } else {
10527 // TODO(hausner): Ideally we should generate the NoSuchMethodError 10567 // TODO(hausner): Ideally we should generate the NoSuchMethodError
10528 // later, when we know more about how the unresolved name is used. 10568 // later, when we know more about how the unresolved name is used.
10529 // For example, we don't know yet whether the unresolved name 10569 // For example, we don't know yet whether the unresolved name
10530 // refers to a getter or a setter. However, it is more awkward 10570 // refers to a getter or a setter. However, it is more awkward
10531 // to distinuish four NoSuchMethodError cases all over the place 10571 // to distinuish four NoSuchMethodError cases all over the place
10532 // in the parser. The four cases are: prefixed vs non-prefixed 10572 // in the parser. The four cases are: prefixed vs non-prefixed
10533 // name, static vs dynamic context in which the unresolved name 10573 // name, static vs dynamic context in which the unresolved name
10534 // is used. We cheat a little here by looking at the next token 10574 // is used. We cheat a little here by looking at the next token
10535 // to determine whether we have an unresolved method call or 10575 // to determine whether we have an unresolved method call or
10536 // field access. 10576 // field access.
10537 String& qualified_name = 10577 String& qualified_name = String::ZoneHandle(I, prefix.name());
10538 String::ZoneHandle(I, qual_ident.lib_prefix->name());
10539 qualified_name = String::Concat(qualified_name, Symbols::Dot()); 10578 qualified_name = String::Concat(qualified_name, Symbols::Dot());
10540 qualified_name = String::Concat(qualified_name, *qual_ident.ident); 10579 qualified_name = String::Concat(qualified_name, ident);
10541 qualified_name = Symbols::New(qualified_name); 10580 qualified_name = Symbols::New(qualified_name);
10542 InvocationMirror::Type call_type = 10581 InvocationMirror::Type call_type =
10543 CurrentToken() == Token::kLPAREN ? 10582 CurrentToken() == Token::kLPAREN ?
10544 InvocationMirror::kMethod : InvocationMirror::kGetter; 10583 InvocationMirror::kMethod : InvocationMirror::kGetter;
10545 primary = ThrowNoSuchMethodError(qual_ident_pos, 10584 primary = ThrowNoSuchMethodError(qual_ident_pos,
10546 current_class(), 10585 current_class(),
10547 qualified_name, 10586 qualified_name,
10548 NULL, // No arguments. 10587 NULL, // No arguments.
10549 InvocationMirror::kTopLevel, 10588 InvocationMirror::kTopLevel,
10550 call_type, 10589 call_type,
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
11016 void Parser::SkipQualIdent() { 11055 void Parser::SkipQualIdent() {
11017 ASSERT(IsIdentifier()); 11056 ASSERT(IsIdentifier());
11018 ConsumeToken(); 11057 ConsumeToken();
11019 if (CurrentToken() == Token::kPERIOD) { 11058 if (CurrentToken() == Token::kPERIOD) {
11020 ConsumeToken(); // Consume the kPERIOD token. 11059 ConsumeToken(); // Consume the kPERIOD token.
11021 ExpectIdentifier("identifier expected after '.'"); 11060 ExpectIdentifier("identifier expected after '.'");
11022 } 11061 }
11023 } 11062 }
11024 11063
11025 } // namespace dart 11064 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698