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

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

Powered by Google App Engine
This is Rietveld 408576698