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 1234883005: Implement tear-off closure operator # (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address review comments 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 826 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 ASSERT(isolate->long_jump_base()->IsSafeToJump()); 837 ASSERT(isolate->long_jump_base()->IsSafeToJump());
838 ASSERT(parsed_function != NULL); 838 ASSERT(parsed_function != NULL);
839 const Function& func = parsed_function->function(); 839 const Function& func = parsed_function->function();
840 const Script& script = Script::Handle(zone, func.script()); 840 const Script& script = Script::Handle(zone, func.script());
841 Parser parser(script, parsed_function, func.token_pos()); 841 Parser parser(script, parsed_function, func.token_pos());
842 SequenceNode* node_sequence = NULL; 842 SequenceNode* node_sequence = NULL;
843 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); 843 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null());
844 switch (func.kind()) { 844 switch (func.kind()) {
845 case RawFunction::kClosureFunction: 845 case RawFunction::kClosureFunction:
846 if (func.IsImplicitClosureFunction()) { 846 if (func.IsImplicitClosureFunction()) {
847 parser.SkipFunctionPreamble();
848 node_sequence = 847 node_sequence =
849 parser.ParseImplicitClosure(func, &default_parameter_values); 848 parser.ParseImplicitClosure(func, &default_parameter_values);
850 break; 849 break;
851 } 850 }
852 // Fall-through: Handle non-implicit closures. 851 // Fall-through: Handle non-implicit closures.
853 case RawFunction::kRegularFunction: 852 case RawFunction::kRegularFunction:
854 case RawFunction::kGetterFunction: 853 case RawFunction::kGetterFunction:
855 case RawFunction::kSetterFunction: 854 case RawFunction::kSetterFunction:
856 case RawFunction::kConstructor: 855 case RawFunction::kConstructor:
857 // The call to a redirecting factory is redirected. 856 // The call to a redirecting factory is redirected.
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 new StoreInstanceFieldNode(ident_pos, receiver, field, value); 1277 new StoreInstanceFieldNode(ident_pos, receiver, field, value);
1279 current_block_->statements->Add(store_field); 1278 current_block_->statements->Add(store_field);
1280 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); 1279 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
1281 return CloseBlock(); 1280 return CloseBlock();
1282 } 1281 }
1283 1282
1284 1283
1285 SequenceNode* Parser::ParseImplicitClosure(const Function& func, 1284 SequenceNode* Parser::ParseImplicitClosure(const Function& func,
1286 Array* default_values) { 1285 Array* default_values) {
1287 TRACE_PARSER("ParseImplicitClosure"); 1286 TRACE_PARSER("ParseImplicitClosure");
1288
1289 intptr_t token_pos = func.token_pos(); 1287 intptr_t token_pos = func.token_pos();
1290 1288
1291 OpenFunctionBlock(func); 1289 OpenFunctionBlock(func);
1292 1290
1293 ParamList params; 1291 ParamList params;
1294
1295 params.AddFinalParameter( 1292 params.AddFinalParameter(
1296 token_pos, 1293 token_pos,
1297 &Symbols::ClosureParameter(), 1294 &Symbols::ClosureParameter(),
1298 &Type::ZoneHandle(Type::DynamicType())); 1295 &Type::ZoneHandle(Type::DynamicType()));
1299 1296
1300 const bool allow_explicit_default_values = true;
1301 ParseFormalParameterList(allow_explicit_default_values, false, &params);
1302 SetupDefaultsForOptionalParams(&params, default_values);
1303
1304 // Getters can't be closurized. If supported, they need special
1305 // handling of the parameters as in ParseFunc.
1306 const Function& parent = Function::ZoneHandle(func.parent_function()); 1297 const Function& parent = Function::ZoneHandle(func.parent_function());
1307 ASSERT(!parent.IsGetterFunction()); 1298 if (parent.IsImplicitSetterFunction()) {
1299 const intptr_t ident_pos = func.token_pos();
1300 ASSERT(IsIdentifier());
1301 const String& field_name = *CurrentLiteral();
1302 const Class& field_class = Class::ZoneHandle(Z, parent.Owner());
1303 const Field& field =
1304 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name));
1305 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type());
1306 params.AddFinalParameter(ident_pos,
1307 &Symbols::Value(),
1308 &field_type);
1309 ASSERT(func.num_fixed_parameters() == 2); // closure, value.
1310 } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) {
1311 const bool allow_explicit_default_values = true;
1312 SkipFunctionPreamble();
1313 ParseFormalParameterList(allow_explicit_default_values, false, &params);
1314 SetupDefaultsForOptionalParams(&params, default_values);
1315 }
1308 1316
1309 // Populate function scope with the formal parameters. 1317 // Populate function scope with the formal parameters.
1310 LocalScope* scope = current_block_->scope; 1318 LocalScope* scope = current_block_->scope;
1311 AddFormalParamsToScope(&params, scope); 1319 AddFormalParamsToScope(&params, scope);
1312 1320
1313 ArgumentListNode* func_args = new ArgumentListNode(token_pos); 1321 ArgumentListNode* func_args = new ArgumentListNode(token_pos);
1314 if (!func.is_static()) { 1322 if (!func.is_static()) {
1315 func_args->Add(LoadReceiver(token_pos)); 1323 func_args->Add(LoadReceiver(token_pos));
1316 } 1324 }
1317 // Skip implicit parameter at 0. 1325 // Skip implicit parameter at 0.
(...skipping 2104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3422 } while (CurrentToken() == Token::kCOMMA); 3430 } while (CurrentToken() == Token::kCOMMA);
3423 } 3431 }
3424 3432
3425 3433
3426 // If the current identifier is a library prefix followed by a period, 3434 // If the current identifier is a library prefix followed by a period,
3427 // consume the identifier and period, and return the resolved library 3435 // consume the identifier and period, and return the resolved library
3428 // prefix. 3436 // prefix.
3429 RawLibraryPrefix* Parser::ParsePrefix() { 3437 RawLibraryPrefix* Parser::ParsePrefix() {
3430 ASSERT(IsIdentifier()); 3438 ASSERT(IsIdentifier());
3431 // A library prefix can never stand by itself. It must be followed by 3439 // A library prefix can never stand by itself. It must be followed by
3432 // a period. 3440 // a period or a hash mark (for closurization).
3433 if (LookaheadToken(1) != Token::kPERIOD) { 3441 Token::Kind next_token = LookaheadToken(1);
3442 if ((next_token != Token::kPERIOD) && (next_token != Token::kHASH)) {
3434 return LibraryPrefix::null(); 3443 return LibraryPrefix::null();
3435 } 3444 }
3436 const String& ident = *CurrentLiteral(); 3445 const String& ident = *CurrentLiteral();
3437 3446
3438 // It is relatively fast to look up a name in the library dictionary, 3447 // It is relatively fast to look up a name in the library dictionary,
3439 // compared to searching the nested local scopes. Look up the name 3448 // compared to searching the nested local scopes. Look up the name
3440 // in the library scope and return in the common case where ident is 3449 // in the library scope and return in the common case where ident is
3441 // not a library prefix. 3450 // not a library prefix.
3442 LibraryPrefix& prefix = 3451 LibraryPrefix& prefix =
3443 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); 3452 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident));
3444 if (prefix.IsNull()) { 3453 if (prefix.IsNull()) {
3445 return LibraryPrefix::null(); 3454 return LibraryPrefix::null();
3446 } 3455 }
3447 3456
3448 // A library prefix with the name exists. Now check whether it is 3457 // A library prefix with the name exists. Now check whether it is
3449 // shadowed by a local definition. 3458 // shadowed by a local definition.
3450 if (!is_top_level_ && 3459 if (!is_top_level_ &&
3451 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { 3460 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) {
3452 return LibraryPrefix::null(); 3461 return LibraryPrefix::null();
3453 } 3462 }
3454 // Check whether the identifier is shadowed by a type parameter. 3463 // Check whether the identifier is shadowed by a type parameter.
3455 ASSERT(!current_class().IsNull()); 3464 ASSERT(!current_class().IsNull());
3456 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { 3465 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) {
3457 return LibraryPrefix::null(); 3466 return LibraryPrefix::null();
3458 } 3467 }
3459 3468
3460 // We have a name that is not shadowed, followed by a period. 3469 // We have a name that is not shadowed, followed by a period or #.
3461 // Consume the identifier and the period. 3470 // Consume the identifier, let the caller consume the . or #.
3462 ConsumeToken();
3463 ASSERT(CurrentToken() == Token::kPERIOD); // We checked above.
3464 ConsumeToken(); 3471 ConsumeToken();
3465 return prefix.raw(); 3472 return prefix.raw();
3466 } 3473 }
3467 3474
3468 3475
3469 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { 3476 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
3470 TRACE_PARSER("ParseMethodOrConstructor"); 3477 TRACE_PARSER("ParseMethodOrConstructor");
3471 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); 3478 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter());
3472 ASSERT(method->type != NULL); 3479 ASSERT(method->type != NULL);
3473 ASSERT(current_member_ == method); 3480 ASSERT(current_member_ == method);
(...skipping 7835 matching lines...) Expand 10 before | Expand all | Expand 10 after
11309 } 11316 }
11310 // Done parsing selectors. 11317 // Done parsing selectors.
11311 return left; 11318 return left;
11312 } 11319 }
11313 ASSERT(selector != NULL); 11320 ASSERT(selector != NULL);
11314 left = selector; 11321 left = selector;
11315 } 11322 }
11316 } 11323 }
11317 11324
11318 11325
11326 // Closurization e#m of getter, setter, method or operator.
11327 AstNode* Parser::ParseClosurization(AstNode* primary) {
11328 ExpectToken(Token::kHASH);
11329 intptr_t property_pos = TokenPos();
11330 bool is_setter_name = false;
11331
11332 String& extractor_name = String::ZoneHandle(Z);
11333 if (IsIdentifier()) {
11334 extractor_name = CurrentLiteral()->raw();
11335 ConsumeToken();
11336 if (CurrentToken() == Token::kASSIGN) {
11337 ConsumeToken();
11338 is_setter_name = true;
11339 }
11340 } else if (Token::CanBeOverloaded(CurrentToken())) {
11341 extractor_name = String::New(Token::Str(CurrentToken()));
11342 ConsumeToken();
11343 } else {
11344 ReportError("identifier or operator expected");
11345 }
11346
11347 if (primary->IsPrimaryNode() && primary->AsPrimaryNode()->IsSuper()) {
11348 // TODO(hausner): implement super#m
11349 ReportError("closurization of super method not yet supported");
11350 }
11351
11352 // Handle closurization of top-level names from library prefixes, P#m
11353 if (primary->IsLiteralNode() &&
11354 primary->AsLiteralNode()->literal().IsLibraryPrefix()) {
11355 const LibraryPrefix& prefix =
11356 LibraryPrefix::Cast(primary->AsLiteralNode()->literal());
11357 Object& obj = Object::Handle(Z);
11358 const bool is_private_name =
11359 (extractor_name.CharAt(0) == Library::kPrivateIdentifierStart);
11360 if (!is_private_name) {
11361 // Private names are not exported by libraries. The name mangling
11362 // of private names with a library-specific suffix usually ensures
11363 // that _x in library A is not found when looked up from library B.
11364 // In the pathological case where a library imports itself with
11365 // a prefix, the name mangling does not help in hiding the private
11366 // name, so we explicitly prevent lookup of private names here.
11367 obj = prefix.LookupObject(extractor_name);
11368 }
11369 if (!prefix.is_loaded() && (parsed_function() != NULL)) {
11370 // Remember that this function depends on an import prefix of an
11371 // unloaded deferred library.
11372 parsed_function()->AddDeferredPrefix(prefix);
11373 }
11374
11375 if (obj.IsFunction()) {
11376 const Function& func = Function::Cast(obj);
11377 if (!func.IsSetterFunction() || is_setter_name) {
11378 return CreateImplicitClosureNode(func, property_pos, NULL);
11379 }
11380 } else if (obj.IsField()) {
11381 const Field& field = Field::Cast(obj);
11382 if (is_setter_name && !field.is_final()) {
11383 Instance& setter_closure = Instance::ZoneHandle(field.SetterClosure());
11384 return new(Z) LiteralNode(property_pos, setter_closure);
11385 }
11386 if (!is_setter_name) {
11387 Instance& getter_closure = Instance::ZoneHandle(field.GetterClosure());
11388 return new(Z) LiteralNode(property_pos, getter_closure);
11389 }
11390 }
11391 return ThrowNoSuchMethodError(property_pos,
11392 current_class(),
11393 extractor_name,
11394 NULL, // No arguments.
11395 InvocationMirror::kTopLevel,
11396 is_setter_name
11397 ? InvocationMirror::kSetter
11398 : InvocationMirror::kMethod,
11399 NULL); // No existing function.
11400 }
11401
11402 // Handle closurization of static properties of classes, C#n.
11403 if (primary->IsPrimaryNode() &&
11404 primary->AsPrimaryNode()->primary().IsClass()) {
11405 const Class& cls = Class::Cast(primary->AsPrimaryNode()->primary());
11406 const Field& field =
11407 Field::Handle(Z, cls.LookupStaticField(extractor_name));
11408 if (!field.IsNull()) {
11409 if (is_setter_name) {
11410 extractor_name = Field::SetterName(extractor_name);
11411 if (!field.is_final()) {
11412 const Instance& setter_closure =
11413 Instance::ZoneHandle(Z, field.SetterClosure());
11414 ASSERT(setter_closure.IsClosure());
11415 const Function& cf =
hausner 2015/07/17 23:13:07 This is how precompilation can be done, unless I a
Florian Schneider 2015/07/20 07:00:16 Doesn't evaluating the function expression in Sett
hausner 2015/07/21 17:18:36 The created closures are now cached for later reus
11416 Function::Handle(Closure::function(setter_closure));
11417 Error& error = Error::Handle(Z);
11418 error = Compiler::CompileFunction(Thread::Current(), cf);
11419 ASSERT(error.IsNull());
11420 return new(Z) LiteralNode(property_pos, setter_closure);
11421 }
11422 }
11423 if (!is_setter_name) {
11424 const Instance& getter_closure =
11425 Instance::ZoneHandle(Z, field.GetterClosure());
11426 ASSERT(getter_closure.IsClosure());
11427 const Function& cf =
11428 Function::Handle(Closure::function(getter_closure));
11429 Error& error = Error::Handle(Z);
11430 error = Compiler::CompileFunction(Thread::Current(), cf);
11431 ASSERT(error.IsNull());
11432 return new(Z) LiteralNode(property_pos, getter_closure);
11433 }
11434 } else {
11435 Function& func = Function::Handle(Z);
11436 if (is_setter_name) {
11437 extractor_name = Field::SetterName(extractor_name);
11438 func = cls.LookupStaticFunction(extractor_name);
11439 } else {
11440 func = cls.LookupStaticFunction(extractor_name);
11441 if (func.IsNull()) {
11442 const String& getter_name =
11443 String::Handle(Z, Field::GetterName(extractor_name));
11444 func = cls.LookupStaticFunction(getter_name);
11445 }
11446 }
11447 if (!func.IsNull()) {
11448 return CreateImplicitClosureNode(func, property_pos, NULL);
11449 }
11450 }
11451 return ThrowNoSuchMethodError(property_pos,
11452 cls,
11453 extractor_name,
11454 NULL, // No arguments.
11455 InvocationMirror::kStatic,
11456 is_setter_name
11457 ? InvocationMirror::kSetter
11458 : InvocationMirror::kMethod,
11459 NULL); // No existing function.
11460 }
11461
11462 // Closurization of instance getter, setter, method or operator.
11463 if (is_setter_name) {
11464 extractor_name = String::Concat(Symbols::SetterPrefix(), extractor_name);
11465 }
11466 extractor_name = String::Concat(Symbols::HashMark(), extractor_name);
11467 extractor_name = Symbols::New(extractor_name);
11468 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name);
11469 }
11470
11471
11319 AstNode* Parser::ParsePostfixExpr() { 11472 AstNode* Parser::ParsePostfixExpr() {
11320 TRACE_PARSER("ParsePostfixExpr"); 11473 TRACE_PARSER("ParsePostfixExpr");
11321 String* expr_ident = 11474 String* expr_ident =
11322 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; 11475 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
11323 const intptr_t expr_pos = TokenPos(); 11476 const intptr_t expr_pos = TokenPos();
11324 AstNode* expr = ParsePrimary(); 11477 AstNode* expr = ParsePrimary();
11325 expr = ParseSelectors(expr, false); 11478 if (CurrentToken() == Token::kHASH) {
11479 expr = LoadFieldIfUnresolved(expr);
11480 expr = ParseClosurization(expr);
11481 } else {
11482 expr = ParseSelectors(expr, false);
11483 }
11326 if (IsIncrementOperator(CurrentToken())) { 11484 if (IsIncrementOperator(CurrentToken())) {
11327 TRACE_PARSER("IncrementOperator"); 11485 TRACE_PARSER("IncrementOperator");
11328 if (!IsLegalAssignableSyntax(expr, TokenPos())) { 11486 if (!IsLegalAssignableSyntax(expr, TokenPos())) {
11329 ReportError(expr_pos, "expression is not assignable"); 11487 ReportError(expr_pos, "expression is not assignable");
11330 } 11488 }
11331 Token::Kind incr_op = CurrentToken(); 11489 Token::Kind incr_op = CurrentToken();
11332 ConsumeToken(); 11490 ConsumeToken();
11333 // Not prefix. 11491 // Not prefix.
11334 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); 11492 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
11335 LocalVariable* temp = let_expr->AddInitializer(expr); 11493 LocalVariable* temp = let_expr->AddInitializer(expr);
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
11997 12155
11998 if (finalization == ClassFinalizer::kIgnore) { 12156 if (finalization == ClassFinalizer::kIgnore) {
11999 if (!is_top_level_ && (current_block_ != NULL)) { 12157 if (!is_top_level_ && (current_block_ != NULL)) {
12000 // Add the library prefix or type class name to the list of referenced 12158 // Add the library prefix or type class name to the list of referenced
12001 // names of this scope, even if the type is ignored. 12159 // names of this scope, even if the type is ignored.
12002 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); 12160 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral());
12003 } 12161 }
12004 SkipQualIdent(); 12162 SkipQualIdent();
12005 } else { 12163 } else {
12006 *prefix = ParsePrefix(); 12164 *prefix = ParsePrefix();
12165 if (!prefix->IsNull()) {
12166 ExpectToken(Token::kPERIOD);
12167 }
12007 type_name = CurrentLiteral()->raw(); 12168 type_name = CurrentLiteral()->raw();
12008 ConsumeToken(); 12169 ConsumeToken();
12009 12170
12010 // Check whether we have a malformed qualified type name if the caller 12171 // Check whether we have a malformed qualified type name if the caller
12011 // requests to consume unresolved prefix names: 12172 // requests to consume unresolved prefix names:
12012 // If we didn't see a valid prefix but the identifier is followed by 12173 // If we didn't see a valid prefix but the identifier is followed by
12013 // a period and another identifier, consume the qualified identifier 12174 // a period and another identifier, consume the qualified identifier
12014 // and create a malformed type. 12175 // and create a malformed type.
12015 if (consume_unresolved_prefix && 12176 if (consume_unresolved_prefix &&
12016 prefix->IsNull() && 12177 prefix->IsNull() &&
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
12622 TRACE_PARSER("ParseNewOperator"); 12783 TRACE_PARSER("ParseNewOperator");
12623 const intptr_t new_pos = TokenPos(); 12784 const intptr_t new_pos = TokenPos();
12624 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); 12785 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
12625 bool is_const = (op_kind == Token::kCONST); 12786 bool is_const = (op_kind == Token::kCONST);
12626 if (!IsIdentifier()) { 12787 if (!IsIdentifier()) {
12627 ReportError("type name expected"); 12788 ReportError("type name expected");
12628 } 12789 }
12629 intptr_t type_pos = TokenPos(); 12790 intptr_t type_pos = TokenPos();
12630 // Can't allocate const objects of a deferred type. 12791 // Can't allocate const objects of a deferred type.
12631 const bool allow_deferred_type = !is_const; 12792 const bool allow_deferred_type = !is_const;
12632 const bool consume_unresolved_prefix = (LookaheadToken(3) == Token::kLT) || 12793 const Token::Kind la3 = LookaheadToken(3);
12633 (LookaheadToken(3) == Token::kPERIOD); 12794 const bool consume_unresolved_prefix =
12795 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH);
12796
12634 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); 12797 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z);
12635 AbstractType& type = AbstractType::Handle(Z, 12798 AbstractType& type = AbstractType::Handle(Z,
12636 ParseType(ClassFinalizer::kCanonicalizeWellFormed, 12799 ParseType(ClassFinalizer::kCanonicalizeWellFormed,
12637 allow_deferred_type, 12800 allow_deferred_type,
12638 consume_unresolved_prefix, 12801 consume_unresolved_prefix,
12639 &prefix)); 12802 &prefix));
12803 if (CurrentToken() == Token::kHASH) {
12804 ReportError("constructor closurization not yet supported");
12805 }
12640 if (FLAG_load_deferred_eagerly && 12806 if (FLAG_load_deferred_eagerly &&
12641 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) { 12807 !prefix.IsNull() && prefix.is_deferred_load() && !prefix.is_loaded()) {
12642 // Add runtime check. 12808 // Add runtime check.
12643 Type& malformed_type = Type::Handle(Z); 12809 Type& malformed_type = Type::Handle(Z);
12644 malformed_type = ClassFinalizer::NewFinalizedMalformedType( 12810 malformed_type = ClassFinalizer::NewFinalizedMalformedType(
12645 Error::Handle(Z), // No previous error. 12811 Error::Handle(Z), // No previous error.
12646 script_, 12812 script_,
12647 type_pos, 12813 type_pos,
12648 "deferred type '%s.%s' is not yet loaded", 12814 "deferred type '%s.%s' is not yet loaded",
12649 String::Handle(Z, prefix.name()).ToCString(), 12815 String::Handle(Z, prefix.name()).ToCString(),
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
13064 const Token::Kind token = CurrentToken(); 13230 const Token::Kind token = CurrentToken();
13065 if (IsFunctionLiteral()) { 13231 if (IsFunctionLiteral()) {
13066 // The name of a literal function is visible from inside the function, but 13232 // The name of a literal function is visible from inside the function, but
13067 // must not collide with names in the scope declaring the literal. 13233 // must not collide with names in the scope declaring the literal.
13068 OpenBlock(); 13234 OpenBlock();
13069 primary = ParseFunctionStatement(true); 13235 primary = ParseFunctionStatement(true);
13070 CloseBlock(); 13236 CloseBlock();
13071 } else if (IsIdentifier()) { 13237 } else if (IsIdentifier()) {
13072 intptr_t qual_ident_pos = TokenPos(); 13238 intptr_t qual_ident_pos = TokenPos();
13073 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); 13239 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix());
13240 if (!prefix.IsNull()) {
13241 if (CurrentToken() == Token::kHASH) {
13242 // Closurization of top-level entity in prefix scope.
13243 return new(Z) LiteralNode(qual_ident_pos, prefix);
13244 } else {
13245 ExpectToken(Token::kPERIOD);
13246 }
13247 }
13074 String& ident = *CurrentLiteral(); 13248 String& ident = *CurrentLiteral();
13075 ConsumeToken(); 13249 ConsumeToken();
13076 if (prefix.IsNull()) { 13250 if (prefix.IsNull()) {
13077 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { 13251 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) {
13078 // Check whether the identifier is a type parameter. 13252 // Check whether the identifier is a type parameter.
13079 if (!current_class().IsNull()) { 13253 if (!current_class().IsNull()) {
13080 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, 13254 TypeParameter& type_param = TypeParameter::ZoneHandle(Z,
13081 current_class().LookupTypeParameter(ident)); 13255 current_class().LookupTypeParameter(ident));
13082 if (!type_param.IsNull()) { 13256 if (!type_param.IsNull()) {
13083 return new(Z) PrimaryNode(qual_ident_pos, type_param); 13257 return new(Z) PrimaryNode(qual_ident_pos, type_param);
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
13425 } else { 13599 } else {
13426 UnexpectedToken(); 13600 UnexpectedToken();
13427 } 13601 }
13428 } 13602 }
13429 13603
13430 13604
13431 void Parser::SkipNewOperator() { 13605 void Parser::SkipNewOperator() {
13432 ConsumeToken(); // Skip new or const keyword. 13606 ConsumeToken(); // Skip new or const keyword.
13433 if (IsIdentifier()) { 13607 if (IsIdentifier()) {
13434 SkipType(false); 13608 SkipType(false);
13609 SkipIf(Token::kHASH);
13610 if (CurrentToken() == Token::kPERIOD) {
13611 ConsumeToken();
13612 ExpectIdentifier("identifier expected");
13613 }
13435 if (CurrentToken() == Token::kLPAREN) { 13614 if (CurrentToken() == Token::kLPAREN) {
13436 SkipActualParameters(); 13615 SkipActualParameters();
13437 return; 13616 return;
13438 } 13617 }
13439 } 13618 }
13440 } 13619 }
13441 13620
13442 13621
13443 void Parser::SkipStringLiteral() { 13622 void Parser::SkipStringLiteral() {
13444 ASSERT(CurrentToken() == Token::kSTRING); 13623 ASSERT(CurrentToken() == Token::kSTRING);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
13543 } else if (current_token == Token::kLPAREN) { 13722 } else if (current_token == Token::kLPAREN) {
13544 SkipActualParameters(); 13723 SkipActualParameters();
13545 } else { 13724 } else {
13546 break; 13725 break;
13547 } 13726 }
13548 } 13727 }
13549 } 13728 }
13550 13729
13551 void Parser::SkipPostfixExpr() { 13730 void Parser::SkipPostfixExpr() {
13552 SkipPrimary(); 13731 SkipPrimary();
13732 if (CurrentToken() == Token::kHASH) {
13733 if (IsIdentifier()) {
13734 ConsumeToken();
13735 SkipIf(Token::kASSIGN);
13736 } else if (Token::CanBeOverloaded(CurrentToken())) {
13737 ConsumeToken();
13738 } else {
13739 ReportError("identifier or operator expected");
13740 }
13741 }
13553 SkipSelectors(); 13742 SkipSelectors();
13554 if (IsIncrementOperator(CurrentToken())) { 13743 if (IsIncrementOperator(CurrentToken())) {
13555 ConsumeToken(); 13744 ConsumeToken();
13556 } 13745 }
13557 } 13746 }
13558 13747
13559 13748
13560 void Parser::SkipUnaryExpr() { 13749 void Parser::SkipUnaryExpr() {
13561 if (IsPrefixOperator(CurrentToken()) || 13750 if (IsPrefixOperator(CurrentToken()) ||
13562 IsIncrementOperator(CurrentToken()) || 13751 IsIncrementOperator(CurrentToken()) ||
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
13628 void Parser::SkipQualIdent() { 13817 void Parser::SkipQualIdent() {
13629 ASSERT(IsIdentifier()); 13818 ASSERT(IsIdentifier());
13630 ConsumeToken(); 13819 ConsumeToken();
13631 if (CurrentToken() == Token::kPERIOD) { 13820 if (CurrentToken() == Token::kPERIOD) {
13632 ConsumeToken(); // Consume the kPERIOD token. 13821 ConsumeToken(); // Consume the kPERIOD token.
13633 ExpectIdentifier("identifier expected after '.'"); 13822 ExpectIdentifier("identifier expected after '.'");
13634 } 13823 }
13635 } 13824 }
13636 13825
13637 } // namespace dart 13826 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698