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

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

Powered by Google App Engine
This is Rietveld 408576698