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

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

Issue 1234883005: Implement tear-off closure operator # (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 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
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/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 ASSERT(isolate->long_jump_base()->IsSafeToJump()); 831 ASSERT(isolate->long_jump_base()->IsSafeToJump());
832 ASSERT(parsed_function != NULL); 832 ASSERT(parsed_function != NULL);
833 const Function& func = parsed_function->function(); 833 const Function& func = parsed_function->function();
834 const Script& script = Script::Handle(zone, func.script()); 834 const Script& script = Script::Handle(zone, func.script());
835 Parser parser(script, parsed_function, func.token_pos()); 835 Parser parser(script, parsed_function, func.token_pos());
836 SequenceNode* node_sequence = NULL; 836 SequenceNode* node_sequence = NULL;
837 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); 837 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null());
838 switch (func.kind()) { 838 switch (func.kind()) {
839 case RawFunction::kClosureFunction: 839 case RawFunction::kClosureFunction:
840 if (func.IsImplicitClosureFunction()) { 840 if (func.IsImplicitClosureFunction()) {
841 parser.SkipFunctionPreamble();
842 node_sequence = 841 node_sequence =
843 parser.ParseImplicitClosure(func, &default_parameter_values); 842 parser.ParseImplicitClosure(func, &default_parameter_values);
844 break; 843 break;
845 } 844 }
846 // Fall-through: Handle non-implicit closures. 845 // Fall-through: Handle non-implicit closures.
847 case RawFunction::kRegularFunction: 846 case RawFunction::kRegularFunction:
848 case RawFunction::kGetterFunction: 847 case RawFunction::kGetterFunction:
849 case RawFunction::kSetterFunction: 848 case RawFunction::kSetterFunction:
850 case RawFunction::kConstructor: 849 case RawFunction::kConstructor:
851 // The call to a redirecting factory is redirected. 850 // The call to a redirecting factory is redirected.
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 new StoreInstanceFieldNode(ident_pos, receiver, field, value); 1271 new StoreInstanceFieldNode(ident_pos, receiver, field, value);
1273 current_block_->statements->Add(store_field); 1272 current_block_->statements->Add(store_field);
1274 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); 1273 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
1275 return CloseBlock(); 1274 return CloseBlock();
1276 } 1275 }
1277 1276
1278 1277
1279 SequenceNode* Parser::ParseImplicitClosure(const Function& func, 1278 SequenceNode* Parser::ParseImplicitClosure(const Function& func,
1280 Array* default_values) { 1279 Array* default_values) {
1281 TRACE_PARSER("ParseImplicitClosure"); 1280 TRACE_PARSER("ParseImplicitClosure");
1282
1283 intptr_t token_pos = func.token_pos(); 1281 intptr_t token_pos = func.token_pos();
1284 1282
1285 OpenFunctionBlock(func); 1283 OpenFunctionBlock(func);
1286 1284
1287 ParamList params; 1285 ParamList params;
1288
1289 params.AddFinalParameter( 1286 params.AddFinalParameter(
1290 token_pos, 1287 token_pos,
1291 &Symbols::ClosureParameter(), 1288 &Symbols::ClosureParameter(),
1292 &Type::ZoneHandle(Type::DynamicType())); 1289 &Type::ZoneHandle(Type::DynamicType()));
1293 1290
1294 const bool allow_explicit_default_values = true;
1295 ParseFormalParameterList(allow_explicit_default_values, false, &params);
1296 SetupDefaultsForOptionalParams(&params, default_values);
1297
1298 // Getters can't be closurized. If supported, they need special
1299 // handling of the parameters as in ParseFunc.
1300 const Function& parent = Function::ZoneHandle(func.parent_function()); 1291 const Function& parent = Function::ZoneHandle(func.parent_function());
1301 ASSERT(!parent.IsGetterFunction()); 1292 if (parent.IsImplicitSetterFunction()) {
1293 const intptr_t ident_pos = func.token_pos();
1294 ASSERT(IsIdentifier());
1295 const String& field_name = *CurrentLiteral();
1296 const Class& field_class = Class::ZoneHandle(Z, parent.Owner());
1297 const Field& field =
1298 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name));
1299 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type());
1300 params.AddFinalParameter(ident_pos,
1301 &Symbols::Value(),
1302 &field_type);
1303 ASSERT(func.num_fixed_parameters() == 2); // closure, value.
1304 } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) {
1305 const bool allow_explicit_default_values = true;
1306 SkipFunctionPreamble();
1307 ParseFormalParameterList(allow_explicit_default_values, false, &params);
1308 SetupDefaultsForOptionalParams(&params, default_values);
1309 }
1302 1310
1303 // Populate function scope with the formal parameters. 1311 // Populate function scope with the formal parameters.
1304 LocalScope* scope = current_block_->scope; 1312 LocalScope* scope = current_block_->scope;
1305 AddFormalParamsToScope(&params, scope); 1313 AddFormalParamsToScope(&params, scope);
1306 1314
1307 ArgumentListNode* func_args = new ArgumentListNode(token_pos); 1315 ArgumentListNode* func_args = new ArgumentListNode(token_pos);
1308 if (!func.is_static()) { 1316 if (!func.is_static()) {
1309 func_args->Add(LoadReceiver(token_pos)); 1317 func_args->Add(LoadReceiver(token_pos));
1310 } 1318 }
1311 // Skip implicit parameter at 0. 1319 // Skip implicit parameter at 0.
(...skipping 2104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3416 } while (CurrentToken() == Token::kCOMMA); 3424 } while (CurrentToken() == Token::kCOMMA);
3417 } 3425 }
3418 3426
3419 3427
3420 // If the current identifier is a library prefix followed by a period, 3428 // If the current identifier is a library prefix followed by a period,
3421 // consume the identifier and period, and return the resolved library 3429 // consume the identifier and period, and return the resolved library
3422 // prefix. 3430 // prefix.
3423 RawLibraryPrefix* Parser::ParsePrefix() { 3431 RawLibraryPrefix* Parser::ParsePrefix() {
3424 ASSERT(IsIdentifier()); 3432 ASSERT(IsIdentifier());
3425 // A library prefix can never stand by itself. It must be followed by 3433 // A library prefix can never stand by itself. It must be followed by
3426 // a period. 3434 // a period or a hash mark (for closurization).
3427 if (LookaheadToken(1) != Token::kPERIOD) { 3435 Token::Kind next_token = LookaheadToken(1);
3436 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) {
3428 return LibraryPrefix::null(); 3437 return LibraryPrefix::null();
3429 } 3438 }
3430 const String& ident = *CurrentLiteral(); 3439 const String& ident = *CurrentLiteral();
3431 3440
3432 // It is relatively fast to look up a name in the library dictionary, 3441 // It is relatively fast to look up a name in the library dictionary,
3433 // compared to searching the nested local scopes. Look up the name 3442 // compared to searching the nested local scopes. Look up the name
3434 // in the library scope and return in the common case where ident is 3443 // in the library scope and return in the common case where ident is
3435 // not a library prefix. 3444 // not a library prefix.
3436 LibraryPrefix& prefix = 3445 LibraryPrefix& prefix =
3437 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); 3446 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident));
3438 if (prefix.IsNull()) { 3447 if (prefix.IsNull()) {
3439 return LibraryPrefix::null(); 3448 return LibraryPrefix::null();
3440 } 3449 }
3441 3450
3442 // A library prefix with the name exists. Now check whether it is 3451 // A library prefix with the name exists. Now check whether it is
3443 // shadowed by a local definition. 3452 // shadowed by a local definition.
3444 if (!is_top_level_ && 3453 if (!is_top_level_ &&
3445 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { 3454 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) {
3446 return LibraryPrefix::null(); 3455 return LibraryPrefix::null();
3447 } 3456 }
3448 // Check whether the identifier is shadowed by a type parameter. 3457 // Check whether the identifier is shadowed by a type parameter.
3449 ASSERT(!current_class().IsNull()); 3458 ASSERT(!current_class().IsNull());
3450 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { 3459 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) {
3451 return LibraryPrefix::null(); 3460 return LibraryPrefix::null();
3452 } 3461 }
3453 3462
3454 // We have a name that is not shadowed, followed by a period. 3463 // We have a name that is not shadowed, followed by a period or #.
3455 // Consume the identifier and the period. 3464 // Consume the identifier, let the caller consume the . or #.
3456 ConsumeToken();
3457 ASSERT(CurrentToken() == Token::kPERIOD); // We checked above.
3458 ConsumeToken(); 3465 ConsumeToken();
3459 return prefix.raw(); 3466 return prefix.raw();
3460 } 3467 }
3461 3468
3462 3469
3463 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { 3470 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
3464 TRACE_PARSER("ParseMethodOrConstructor"); 3471 TRACE_PARSER("ParseMethodOrConstructor");
3465 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); 3472 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter());
3466 ASSERT(method->type != NULL); 3473 ASSERT(method->type != NULL);
3467 ASSERT(current_member_ == method); 3474 ASSERT(current_member_ == method);
(...skipping 7819 matching lines...) Expand 10 before | Expand all | Expand 10 after
11287 } 11294 }
11288 // Done parsing selectors. 11295 // Done parsing selectors.
11289 return left; 11296 return left;
11290 } 11297 }
11291 ASSERT(selector != NULL); 11298 ASSERT(selector != NULL);
11292 left = selector; 11299 left = selector;
11293 } 11300 }
11294 } 11301 }
11295 11302
11296 11303
11304 // Closurization e#m of getter, setter, method or operator.
11305 AstNode* Parser::ParseClosurization(AstNode* primary) {
11306 ExpectToken(Token::kHASH);
11307 intptr_t property_pos = TokenPos();
11308 bool is_setter_name = false;
11309
11310 String& extractor_name = String::ZoneHandle(Z);
11311 if (IsIdentifier()) {
11312 extractor_name = CurrentLiteral()->raw();
11313 ConsumeToken();
11314 if (CurrentToken() == Token::kASSIGN) {
11315 ConsumeToken();
11316 is_setter_name = true;
11317 }
11318 } else if (Token::CanBeOverloaded(CurrentToken())) {
11319 extractor_name = String::New(Token::Str(CurrentToken()));
11320 ConsumeToken();
11321 } else {
11322 ReportError("identifier or operator expected");
11323 }
11324
11325 if (primary->IsPrimaryNode() && primary->AsPrimaryNode()->IsSuper()) {
11326 // TODO(hausner): implement super#m
11327 ReportError("closurization of super method not yet supported");
11328 }
11329
11330 // Handle closurization of top-level names from library prefixes, P#m
11331 if (primary->IsLiteralNode() &&
11332 primary->AsLiteralNode()->literal().IsLibraryPrefix()) {
11333 const LibraryPrefix& prefix =
11334 LibraryPrefix::Cast(primary->AsLiteralNode()->literal());
11335 Object& obj = Object::Handle(Z);
11336 const bool is_private_name =
11337 (extractor_name.CharAt(0) == Library::kPrivateIdentifierStart);
11338 if (!is_private_name) {
11339 // Private names are not exported by libraries. The name mangling
11340 // of private names with a library-specific suffix usually ensures
11341 // that _x in library A is not found when looked up from library B.
11342 // In the pathological case where a library imports itself with
11343 // a prefix, the name mangling does not help in hiding the private
11344 // name, so we explicitly prevent lookup of private names here.
11345 obj = prefix.LookupObject(extractor_name);
11346 }
11347 if (!prefix.is_loaded() && (parsed_function() != NULL)) {
11348 // Remember that this function depends on an import prefix of an
11349 // unloaded deferred library.
11350 parsed_function()->AddDeferredPrefix(prefix);
11351 }
11352
11353 if (obj.IsFunction()) {
11354 const Function& func = Function::Cast(obj);
11355 if (!func.IsSetterFunction() || is_setter_name) {
11356 return CreateImplicitClosureNode(func, property_pos, NULL);
11357 }
11358 } else if (obj.IsField()) {
11359 const Field& field = Field::Cast(obj);
11360 if (is_setter_name && !field.is_final()) {
11361 Instance& setter_closure = Instance::ZoneHandle(field.SetterClosure());
Ivan Posva 2015/07/17 08:35:42 These closures are not cached anywhere, which mean
hausner 2015/07/17 17:53:51 They get collected if they are not stored anywhere
11362 return new(Z) LiteralNode(property_pos, setter_closure);
11363 }
11364 if (!is_setter_name) {
11365 Instance& getter_closure = Instance::ZoneHandle(field.GetterClosure());
11366 return new(Z) LiteralNode(property_pos, getter_closure);
11367 }
11368 }
11369 return ThrowNoSuchMethodError(property_pos,
11370 current_class(),
11371 extractor_name,
11372 NULL, // No arguments.
11373 InvocationMirror::kTopLevel,
11374 is_setter_name
11375 ? InvocationMirror::kSetter
11376 : InvocationMirror::kMethod,
11377 NULL); // No existing function.
11378 }
11379
11380 // Handle closurization of static properties of classes, C#n.
11381 if (primary->IsPrimaryNode() &&
11382 primary->AsPrimaryNode()->primary().IsClass()) {
11383 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary());
11384 const Field& field =
11385 Field::Handle(Z, cls.LookupStaticField(extractor_name));
11386 if (!field.IsNull()) {
11387 if (is_setter_name) {
11388 extractor_name = Field::SetterName(extractor_name);
11389 if (!field.is_final()) {
11390 const Instance& setter_closure =
11391 Instance::ZoneHandle(Z, field.SetterClosure());
11392 return new(Z) LiteralNode(property_pos, setter_closure);
Florian Schneider 2015/07/17 09:42:02 My suggestion would be to do sth. like return Cre
hausner 2015/07/17 17:53:51 Yes, I was considering this. I am hoping that we c
11393 }
11394 }
11395 if (!is_setter_name) {
11396 const Instance& getter_closure =
11397 Instance::ZoneHandle(Z, field.GetterClosure());
11398 return new(Z) LiteralNode(property_pos, getter_closure);
11399 }
11400 } else {
11401 Function& func = Function::Handle(Z);
11402 if (is_setter_name) {
11403 extractor_name = Field::SetterName(extractor_name);
11404 func = cls.LookupStaticFunction(extractor_name);
11405 } else {
11406 func = cls.LookupStaticFunction(extractor_name);
11407 if (func.IsNull()) {
11408 const String& getter_name =
11409 String::Handle(Z, Field::GetterName(extractor_name));
11410 func = cls.LookupStaticFunction(getter_name);
11411 }
11412 }
11413 if (!func.IsNull()) {
11414 return CreateImplicitClosureNode(func, property_pos, NULL);
11415 }
11416 }
11417 return ThrowNoSuchMethodError(property_pos,
11418 cls,
11419 extractor_name,
11420 NULL, // No arguments.
11421 InvocationMirror::kStatic,
11422 is_setter_name
11423 ? InvocationMirror::kSetter
11424 : InvocationMirror::kMethod,
11425 NULL); // No existing function.
11426 }
11427
11428 // Closurization of instance getter, setter, method or operator.
11429 if (is_setter_name) {
11430 extractor_name = String::Concat(Symbols::SetterPrefix(), extractor_name);
11431 }
11432 extractor_name = String::Concat(Symbols::HashMark(), extractor_name);
11433 extractor_name = Symbols::New(extractor_name);
11434 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name);
11435 }
11436
11437
11297 AstNode* Parser::ParsePostfixExpr() { 11438 AstNode* Parser::ParsePostfixExpr() {
11298 TRACE_PARSER("ParsePostfixExpr"); 11439 TRACE_PARSER("ParsePostfixExpr");
11299 String* expr_ident = 11440 String* expr_ident =
11300 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; 11441 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
11301 const intptr_t expr_pos = TokenPos(); 11442 const intptr_t expr_pos = TokenPos();
11302 AstNode* expr = ParsePrimary(); 11443 AstNode* expr = ParsePrimary();
11303 expr = ParseSelectors(expr, false); 11444 if (CurrentToken() == Token::kHASH) {
11445 expr = ParseClosurization(expr);
11446 } else {
11447 expr = ParseSelectors(expr, false);
11448 }
11304 if (IsIncrementOperator(CurrentToken())) { 11449 if (IsIncrementOperator(CurrentToken())) {
11305 TRACE_PARSER("IncrementOperator"); 11450 TRACE_PARSER("IncrementOperator");
11306 if (!IsLegalAssignableSyntax(expr, TokenPos())) { 11451 if (!IsLegalAssignableSyntax(expr, TokenPos())) {
11307 ReportError(expr_pos, "expression is not assignable"); 11452 ReportError(expr_pos, "expression is not assignable");
11308 } 11453 }
11309 Token::Kind incr_op = CurrentToken(); 11454 Token::Kind incr_op = CurrentToken();
11310 ConsumeToken(); 11455 ConsumeToken();
11311 // Not prefix. 11456 // Not prefix.
11312 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 11457 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
11313 LocalVariable* temp = let_expr->AddInitializer(expr); 11458 LocalVariable* temp = let_expr->AddInitializer(expr);
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
11966 12111
11967 if (finalization == ClassFinalizer::kIgnore) { 12112 if (finalization == ClassFinalizer::kIgnore) {
11968 if (!is_top_level_ && (current_block_ != NULL)) { 12113 if (!is_top_level_ && (current_block_ != NULL)) {
11969 // Add the library prefix or type class name to the list of referenced 12114 // Add the library prefix or type class name to the list of referenced
11970 // names of this scope, even if the type is ignored. 12115 // names of this scope, even if the type is ignored.
11971 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); 12116 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral());
11972 } 12117 }
11973 SkipQualIdent(); 12118 SkipQualIdent();
11974 } else { 12119 } else {
11975 prefix = ParsePrefix(); 12120 prefix = ParsePrefix();
12121 if (!prefix.IsNull()) {
12122 ExpectToken(Token::kPERIOD);
12123 }
11976 type_name = CurrentLiteral()->raw(); 12124 type_name = CurrentLiteral()->raw();
11977 ConsumeToken(); 12125 ConsumeToken();
11978 12126
11979 // Check whether we have a malformed qualified type name if the caller 12127 // Check whether we have a malformed qualified type name if the caller
11980 // requests to consume unresolved prefix names: 12128 // requests to consume unresolved prefix names:
11981 // If we didn't see a valid prefix but the identifier is followed by 12129 // If we didn't see a valid prefix but the identifier is followed by
11982 // a period and another identifier, consume the qualified identifier 12130 // a period and another identifier, consume the qualified identifier
11983 // and create a malformed type. 12131 // and create a malformed type.
11984 if (consume_unresolved_prefix && 12132 if (consume_unresolved_prefix &&
11985 prefix.IsNull() && 12133 prefix.IsNull() &&
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
12590 TRACE_PARSER("ParseNewOperator"); 12738 TRACE_PARSER("ParseNewOperator");
12591 const intptr_t new_pos = TokenPos(); 12739 const intptr_t new_pos = TokenPos();
12592 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); 12740 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
12593 bool is_const = (op_kind == Token::kCONST); 12741 bool is_const = (op_kind == Token::kCONST);
12594 if (!IsIdentifier()) { 12742 if (!IsIdentifier()) {
12595 ReportError("type name expected"); 12743 ReportError("type name expected");
12596 } 12744 }
12597 intptr_t type_pos = TokenPos(); 12745 intptr_t type_pos = TokenPos();
12598 // Can't allocate const objects of a deferred type. 12746 // Can't allocate const objects of a deferred type.
12599 const bool allow_deferred_type = !is_const; 12747 const bool allow_deferred_type = !is_const;
12600 const bool consume_unresolved_prefix = (LookaheadToken(3) == Token::kLT) || 12748 const Token::Kind la3 = LookaheadToken(3);
12601 (LookaheadToken(3) == Token::kPERIOD); 12749 const bool consume_unresolved_prefix =
12750 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH);
12602 AbstractType& type = AbstractType::Handle(Z, 12751 AbstractType& type = AbstractType::Handle(Z,
12603 ParseType(ClassFinalizer::kCanonicalizeWellFormed, 12752 ParseType(ClassFinalizer::kCanonicalizeWellFormed,
12604 allow_deferred_type, 12753 allow_deferred_type,
12605 consume_unresolved_prefix)); 12754 consume_unresolved_prefix));
12755 if (CurrentToken() == Token::kHASH) {
12756 ReportError("constructor closurization not yet supported");
12757 }
12606 // In case the type is malformed, throw a dynamic type error after finishing 12758 // In case the type is malformed, throw a dynamic type error after finishing
12607 // parsing the instance creation expression. 12759 // parsing the instance creation expression.
12608 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { 12760 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) {
12609 // Replace the type with a malformed type. 12761 // Replace the type with a malformed type.
12610 type = ClassFinalizer::NewFinalizedMalformedType( 12762 type = ClassFinalizer::NewFinalizedMalformedType(
12611 Error::Handle(Z), // No previous error. 12763 Error::Handle(Z), // No previous error.
12612 script_, 12764 script_,
12613 type_pos, 12765 type_pos,
12614 "%s'%s' cannot be instantiated", 12766 "%s'%s' cannot be instantiated",
12615 type.IsTypeParameter() ? "type parameter " : "", 12767 type.IsTypeParameter() ? "type parameter " : "",
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
13014 const Token::Kind token = CurrentToken(); 13166 const Token::Kind token = CurrentToken();
13015 if (IsFunctionLiteral()) { 13167 if (IsFunctionLiteral()) {
13016 // The name of a literal function is visible from inside the function, but 13168 // The name of a literal function is visible from inside the function, but
13017 // must not collide with names in the scope declaring the literal. 13169 // must not collide with names in the scope declaring the literal.
13018 OpenBlock(); 13170 OpenBlock();
13019 primary = ParseFunctionStatement(true); 13171 primary = ParseFunctionStatement(true);
13020 CloseBlock(); 13172 CloseBlock();
13021 } else if (IsIdentifier()) { 13173 } else if (IsIdentifier()) {
13022 intptr_t qual_ident_pos = TokenPos(); 13174 intptr_t qual_ident_pos = TokenPos();
13023 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); 13175 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix());
13176 if (!prefix.IsNull()) {
13177 if (CurrentToken() == Token::kHASH) {
13178 // Closurization of top-level entity in prefix scope.
13179 return new(Z) LiteralNode(qual_ident_pos, prefix);
13180 } else {
13181 ExpectToken(Token::kPERIOD);
13182 }
13183 }
13024 String& ident = *CurrentLiteral(); 13184 String& ident = *CurrentLiteral();
13025 ConsumeToken(); 13185 ConsumeToken();
13026 if (prefix.IsNull()) { 13186 if (prefix.IsNull()) {
13027 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { 13187 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) {
13028 // Check whether the identifier is a type parameter. 13188 // Check whether the identifier is a type parameter.
13029 if (!current_class().IsNull()) { 13189 if (!current_class().IsNull()) {
13030 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, 13190 TypeParameter& type_param = TypeParameter::ZoneHandle(Z,
13031 current_class().LookupTypeParameter(ident)); 13191 current_class().LookupTypeParameter(ident));
13032 if (!type_param.IsNull()) { 13192 if (!type_param.IsNull()) {
13033 return new(Z) PrimaryNode(qual_ident_pos, type_param); 13193 return new(Z) PrimaryNode(qual_ident_pos, type_param);
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
13556 void Parser::SkipQualIdent() { 13716 void Parser::SkipQualIdent() {
13557 ASSERT(IsIdentifier()); 13717 ASSERT(IsIdentifier());
13558 ConsumeToken(); 13718 ConsumeToken();
13559 if (CurrentToken() == Token::kPERIOD) { 13719 if (CurrentToken() == Token::kPERIOD) {
13560 ConsumeToken(); // Consume the kPERIOD token. 13720 ConsumeToken(); // Consume the kPERIOD token.
13561 ExpectIdentifier("identifier expected after '.'"); 13721 ExpectIdentifier("identifier expected after '.'");
13562 } 13722 }
13563 } 13723 }
13564 13724
13565 } // namespace dart 13725 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698