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

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

Issue 2010283004: Fix capturing variables in optimized compilations (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix skipping closurization Created 4 years, 6 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') | tests/language/regress_26453_test.dart » ('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 #include "vm/flags.h" 6 #include "vm/flags.h"
7 7
8 #ifndef DART_PRECOMPILED_RUNTIME 8 #ifndef DART_PRECOMPILED_RUNTIME
9 9
10 #include "lib/invocation_mirror.h" 10 #include "lib/invocation_mirror.h"
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 ASSERT(parsed_function() != NULL); 501 ASSERT(parsed_function() != NULL);
502 return parsed_function()->function(); 502 return parsed_function()->function();
503 } 503 }
504 504
505 505
506 const Function& Parser::innermost_function() const { 506 const Function& Parser::innermost_function() const {
507 return innermost_function_; 507 return innermost_function_;
508 } 508 }
509 509
510 510
511 int Parser::FunctionLevel() const {
512 if (current_block_ != NULL) {
513 return current_block_->scope->function_level();
514 }
515 return 0;
516 }
517
518
511 const Class& Parser::current_class() const { 519 const Class& Parser::current_class() const {
512 return current_class_; 520 return current_class_;
513 } 521 }
514 522
515 523
516 void Parser::set_current_class(const Class& value) { 524 void Parser::set_current_class(const Class& value) {
517 current_class_ = value.raw(); 525 current_class_ = value.raw();
518 } 526 }
519 527
520 528
(...skipping 1841 matching lines...) Expand 10 before | Expand all | Expand 10 after
2362 2370
2363 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, 2371 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func,
2364 TokenPosition token_pos, 2372 TokenPosition token_pos,
2365 AstNode* receiver) { 2373 AstNode* receiver) {
2366 Function& implicit_closure_function = 2374 Function& implicit_closure_function =
2367 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); 2375 Function::ZoneHandle(Z, func.ImplicitClosureFunction());
2368 if (receiver != NULL) { 2376 if (receiver != NULL) {
2369 // If we create an implicit instance closure from inside a closure of a 2377 // If we create an implicit instance closure from inside a closure of a
2370 // parameterized class, make sure that the receiver is captured as 2378 // parameterized class, make sure that the receiver is captured as
2371 // instantiator. 2379 // instantiator.
2372 if (current_block_->scope->function_level() > 0) { 2380 if (FunctionLevel() > 0) {
2373 const Type& signature_type = Type::Handle(Z, 2381 const Type& signature_type = Type::Handle(Z,
2374 implicit_closure_function.SignatureType()); 2382 implicit_closure_function.SignatureType());
2375 const Class& scope_class = Class::Handle(Z, signature_type.type_class()); 2383 const Class& scope_class = Class::Handle(Z, signature_type.type_class());
2376 if (scope_class.IsGeneric()) { 2384 if (scope_class.IsGeneric()) {
2377 CaptureInstantiator(); 2385 CaptureInstantiator();
2378 } 2386 }
2379 } 2387 }
2380 } 2388 }
2381 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); 2389 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL);
2382 } 2390 }
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 if (param.is_field_initializer) { 3359 if (param.is_field_initializer) {
3352 ReportError(param.name_pos, 3360 ReportError(param.name_pos,
3353 "field initializer only allowed in constructors"); 3361 "field initializer only allowed in constructors");
3354 } 3362 }
3355 } 3363 }
3356 } 3364 }
3357 // Populate function scope with the formal parameters. 3365 // Populate function scope with the formal parameters.
3358 AddFormalParamsToScope(&params, current_block_->scope); 3366 AddFormalParamsToScope(&params, current_block_->scope);
3359 3367
3360 if (I->type_checks() && 3368 if (I->type_checks() &&
3361 (current_block_->scope->function_level() > 0)) { 3369 (FunctionLevel() > 0)) {
3362 // We are parsing, but not compiling, a local function. 3370 // We are parsing, but not compiling, a local function.
3363 // The instantiator may be required at run time for generic type checks. 3371 // The instantiator may be required at run time for generic type checks.
3364 if (IsInstantiatorRequired()) { 3372 if (IsInstantiatorRequired()) {
3365 // Make sure that the receiver of the enclosing instance function 3373 // Make sure that the receiver of the enclosing instance function
3366 // (or implicit first parameter of an enclosing factory) is marked as 3374 // (or implicit first parameter of an enclosing factory) is marked as
3367 // captured if type checks are enabled, because they may access it to 3375 // captured if type checks are enabled, because they may access it to
3368 // instantiate types. 3376 // instantiate types.
3369 CaptureInstantiator(); 3377 CaptureInstantiator();
3370 } 3378 }
3371 } 3379 }
(...skipping 4027 matching lines...) Expand 10 before | Expand all | Expand 10 after
7399 7407
7400 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope, 7408 LocalVariable* Parser::LookupTypeArgumentsParameter(LocalScope* from_scope,
7401 bool test_only) { 7409 bool test_only) {
7402 ASSERT(current_function().IsInFactoryScope()); 7410 ASSERT(current_function().IsInFactoryScope());
7403 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(), 7411 return from_scope->LookupVariable(Symbols::TypeArgumentsParameter(),
7404 test_only); 7412 test_only);
7405 } 7413 }
7406 7414
7407 7415
7408 void Parser::CaptureInstantiator() { 7416 void Parser::CaptureInstantiator() {
7409 ASSERT(current_block_->scope->function_level() > 0); 7417 ASSERT(FunctionLevel() > 0);
7410 const String* variable_name = current_function().IsInFactoryScope() ? 7418 const String* variable_name = current_function().IsInFactoryScope() ?
7411 &Symbols::TypeArgumentsParameter() : &Symbols::This(); 7419 &Symbols::TypeArgumentsParameter() : &Symbols::This();
7412 current_block_->scope->CaptureVariable( 7420 current_block_->scope->CaptureVariable(
7413 current_block_->scope->LookupVariable(*variable_name, true)); 7421 current_block_->scope->LookupVariable(*variable_name, true));
7414 } 7422 }
7415 7423
7416 7424
7417 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { 7425 AstNode* Parser::LoadReceiver(TokenPosition token_pos) {
7418 // A nested function may access 'this', referring to the receiver of the 7426 // A nested function may access 'this', referring to the receiver of the
7419 // outermost enclosing function. 7427 // outermost enclosing function.
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
7636 } 7644 }
7637 } 7645 }
7638 CheckToken(Token::kLPAREN); 7646 CheckToken(Token::kLPAREN);
7639 7647
7640 // Check whether we have parsed this closure function before, in a previous 7648 // Check whether we have parsed this closure function before, in a previous
7641 // compilation. If so, reuse the function object, else create a new one 7649 // compilation. If so, reuse the function object, else create a new one
7642 // and register it in the current class. 7650 // and register it in the current class.
7643 // Note that we cannot share the same closure function between the closurized 7651 // Note that we cannot share the same closure function between the closurized
7644 // and non-closurized versions of the same parent function. 7652 // and non-closurized versions of the same parent function.
7645 Function& function = Function::ZoneHandle(Z); 7653 Function& function = Function::ZoneHandle(Z);
7654 bool found_func = true;
7646 // TODO(hausner): There could be two different closures at the given 7655 // TODO(hausner): There could be two different closures at the given
7647 // function_pos, one enclosed in a closurized function and one enclosed in the 7656 // function_pos, one enclosed in a closurized function and one enclosed in the
7648 // non-closurized version of this same function. 7657 // non-closurized version of this same function.
7649 function = I->LookupClosureFunction(innermost_function(), function_pos); 7658 function = I->LookupClosureFunction(innermost_function(), function_pos);
7650 if (function.IsNull()) { 7659 if (function.IsNull()) {
7651 // The function will be registered in the lookup table by the 7660 // The function will be registered in the lookup table by the
7652 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure 7661 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure
7653 // function has been properly setup. 7662 // function has been properly setup.
7663 found_func = false;
7654 function = Function::NewClosureFunction(*function_name, 7664 function = Function::NewClosureFunction(*function_name,
7655 innermost_function(), 7665 innermost_function(),
7656 function_pos); 7666 function_pos);
7657 function.set_result_type(result_type); 7667 function.set_result_type(result_type);
7658 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { 7668 if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
7659 library_.AddFunctionMetadata(function, metadata_pos); 7669 library_.AddFunctionMetadata(function, metadata_pos);
7660 } 7670 }
7661 } 7671 }
7662 7672
7663 // The function type needs to be finalized at compile time, since the closure 7673 // The function type needs to be finalized at compile time, since the closure
(...skipping 29 matching lines...) Expand all
7693 current_block_->scope->LookupVariable(function_variable->name(), 7703 current_block_->scope->LookupVariable(function_variable->name(),
7694 true); 7704 true);
7695 ASSERT(existing_var != NULL); 7705 ASSERT(existing_var != NULL);
7696 // Use before define cases have already been detected and reported above. 7706 // Use before define cases have already been detected and reported above.
7697 ASSERT(existing_var->owner() == current_block_->scope); 7707 ASSERT(existing_var->owner() == current_block_->scope);
7698 ReportError(function_pos, "identifier '%s' already defined", 7708 ReportError(function_pos, "identifier '%s' already defined",
7699 function_variable->name().ToCString()); 7709 function_variable->name().ToCString());
7700 } 7710 }
7701 } 7711 }
7702 7712
7703 // Parse the local function. 7713 Type& signature_type = Type::ZoneHandle(Z);
7704 SequenceNode* statements = Parser::ParseFunc(function, !is_literal); 7714 SequenceNode* statements = NULL;
7705 INC_STAT(thread(), num_functions_parsed, 1); 7715 if (!found_func) {
7716 // Parse the local function. As a side effect of the parsing, the
7717 // variables of this function's scope that are referenced by the local
7718 // function (and its inner nested functions) will be marked as captured.
7706 7719
7707 // Now that the local function has formal parameters, lookup the signature 7720 statements = Parser::ParseFunc(function, !is_literal);
7708 Type& signature_type = Type::ZoneHandle(Z, function.SignatureType()); 7721 INC_STAT(thread(), num_functions_parsed, 1);
7709 signature_type ^= ClassFinalizer::FinalizeType( 7722
7710 current_class(), signature_type, ClassFinalizer::kCanonicalize); 7723 // Now that the local function has formal parameters, lookup the signature
7711 function.SetSignatureType(signature_type); 7724 signature_type = function.SignatureType();
7725 signature_type ^= ClassFinalizer::FinalizeType(
7726 current_class(), signature_type, ClassFinalizer::kCanonicalize);
7727 function.SetSignatureType(signature_type);
7728 } else {
7729 // The local function was parsed before. The captured variables are
7730 // saved in the function's context scope. Iterate over the context scope
7731 // and mark its variables as captured.
7732 const ContextScope& context_scope =
7733 ContextScope::Handle(Z, function.context_scope());
7734 ASSERT(!context_scope.IsNull());
7735 String& var_name = String::Handle(Z);
7736 for (int i = 0; i < context_scope.num_variables(); i++) {
7737 var_name = context_scope.NameAt(i);
7738 // We need to look up the name in a way that returns even hidden
7739 // variables, e.g. 'this' in an initializer list.
7740 LocalVariable* v = current_block_->scope->LookupVariable(var_name, true);
7741 ASSERT(v != NULL);
7742 current_block_->scope->CaptureVariable(v);
7743 }
7744 SkipFunctionLiteral();
7745 signature_type = function.SignatureType();
7746 }
7712 7747
7713 // Local functions are registered in the enclosing class, but 7748 // Local functions are registered in the enclosing class, but
7714 // ignored during class finalization. The enclosing class has 7749 // ignored during class finalization. The enclosing class has
7715 // already been finalized. 7750 // already been finalized.
7716 ASSERT(current_class().is_finalized()); 7751 ASSERT(current_class().is_finalized());
7717 ASSERT(signature_type.IsFinalized()); 7752 ASSERT(signature_type.IsFinalized());
7718 7753
7719 // Make sure that the instantiator is captured. 7754 // Make sure that the instantiator is captured.
7720 if ((current_block_->scope->function_level() > 0) && 7755 if ((FunctionLevel() > 0) &&
7721 Class::Handle(signature_type.type_class()).IsGeneric()) { 7756 Class::Handle(signature_type.type_class()).IsGeneric()) {
7722 CaptureInstantiator(); 7757 CaptureInstantiator();
7723 } 7758 }
7724 7759
7725 // A local signature type itself cannot be malformed or malbounded, only its 7760 // A local signature type itself cannot be malformed or malbounded, only its
7726 // signature function's result type or parameter types may be. 7761 // signature function's result type or parameter types may be.
7727 ASSERT(!signature_type.IsMalformed()); 7762 ASSERT(!signature_type.IsMalformed());
7728 ASSERT(!signature_type.IsMalbounded()); 7763 ASSERT(!signature_type.IsMalbounded());
7729 7764
7730 if (variable_name != NULL) { 7765 if (variable_name != NULL) {
(...skipping 25 matching lines...) Expand all
7756 // captured. The captured variables will be recorded along with their 7791 // captured. The captured variables will be recorded along with their
7757 // allocation information in a Scope object stored in the function object. 7792 // allocation information in a Scope object stored in the function object.
7758 // This Scope object is then provided to the compiler when compiling the local 7793 // This Scope object is then provided to the compiler when compiling the local
7759 // function. It would be too early to record the captured variables here, 7794 // function. It would be too early to record the captured variables here,
7760 // since further closure functions may capture more variables. 7795 // since further closure functions may capture more variables.
7761 // This Scope object is constructed after all variables have been allocated. 7796 // This Scope object is constructed after all variables have been allocated.
7762 // The local scope of the parsed function can be pruned, since contained 7797 // The local scope of the parsed function can be pruned, since contained
7763 // variables are not relevant for the compilation of the enclosing function. 7798 // variables are not relevant for the compilation of the enclosing function.
7764 // This pruning is done by omitting to hook the local scope in its parent 7799 // This pruning is done by omitting to hook the local scope in its parent
7765 // scope in the constructor of LocalScope. 7800 // scope in the constructor of LocalScope.
7766 AstNode* closure = new(Z) ClosureNode( 7801 AstNode* closure =
7767 function_pos, function, NULL, statements->scope()); 7802 new(Z) ClosureNode(function_pos, function, NULL,
7803 statements != NULL ? statements->scope() : NULL);
7768 7804
7769 if (function_variable == NULL) { 7805 if (function_variable == NULL) {
7770 ASSERT(is_literal); 7806 ASSERT(is_literal);
7771 return closure; 7807 return closure;
7772 } else { 7808 } else {
7773 AstNode* initialization = new(Z) StoreLocalNode( 7809 AstNode* initialization = new(Z) StoreLocalNode(
7774 function_pos, function_variable, closure); 7810 function_pos, function_variable, closure);
7775 return initialization; 7811 return initialization;
7776 } 7812 }
7777 } 7813 }
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
8541 LocalVariable** async_saved_try_ctx, 8577 LocalVariable** async_saved_try_ctx,
8542 LocalVariable** outer_saved_try_ctx, 8578 LocalVariable** outer_saved_try_ctx,
8543 LocalVariable** outer_async_saved_try_ctx) const { 8579 LocalVariable** outer_async_saved_try_ctx) const {
8544 *saved_try_ctx = NULL; 8580 *saved_try_ctx = NULL;
8545 *async_saved_try_ctx = NULL; 8581 *async_saved_try_ctx = NULL;
8546 *outer_saved_try_ctx = NULL; 8582 *outer_saved_try_ctx = NULL;
8547 *outer_async_saved_try_ctx = NULL; 8583 *outer_async_saved_try_ctx = NULL;
8548 if (try_stack_ != NULL) { 8584 if (try_stack_ != NULL) {
8549 LocalScope* scope = try_stack_->try_block()->scope; 8585 LocalScope* scope = try_stack_->try_block()->scope;
8550 uint16_t try_index = try_stack_->try_index(); 8586 uint16_t try_index = try_stack_->try_index();
8551 const int current_function_level = current_block_->scope->function_level(); 8587 const int current_function_level = FunctionLevel();
8552 if (scope->function_level() == current_function_level) { 8588 if (scope->function_level() == current_function_level) {
8553 // The block declaring :saved_try_ctx_var variable is the parent of the 8589 // The block declaring :saved_try_ctx_var variable is the parent of the
8554 // pushed try block. 8590 // pushed try block.
8555 *saved_try_ctx = LookupSavedTryContextVar(scope->parent()); 8591 *saved_try_ctx = LookupSavedTryContextVar(scope->parent());
8556 *async_saved_try_ctx = LookupAsyncSavedTryContextVar(T, 8592 *async_saved_try_ctx = LookupAsyncSavedTryContextVar(T,
8557 async_temp_scope_, try_index); 8593 async_temp_scope_, try_index);
8558 if ((try_stack_->outer_try() != NULL) && !try_stack_->inside_finally()) { 8594 if ((try_stack_->outer_try() != NULL) && !try_stack_->inside_finally()) {
8559 // Collecting the outer try scope is not necessary if we 8595 // Collecting the outer try scope is not necessary if we
8560 // are in a finally block. 8596 // are in a finally block.
8561 scope = try_stack_->outer_try()->try_block()->scope; 8597 scope = try_stack_->outer_try()->try_block()->scope;
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after
9292 try_stack_ = try_stack_->outer_try(); 9328 try_stack_ = try_stack_->outer_try();
9293 return innermost_try; 9329 return innermost_try;
9294 } 9330 }
9295 9331
9296 9332
9297 void Parser::AddNodeForFinallyInlining(AstNode* node) { 9333 void Parser::AddNodeForFinallyInlining(AstNode* node) {
9298 if (node == NULL) { 9334 if (node == NULL) {
9299 return; 9335 return;
9300 } 9336 }
9301 ASSERT(node->IsReturnNode() || node->IsJumpNode()); 9337 ASSERT(node->IsReturnNode() || node->IsJumpNode());
9302 const intptr_t func_level = current_block_->scope->function_level(); 9338 const intptr_t func_level = FunctionLevel();
9303 TryStack* iterator = try_stack_; 9339 TryStack* iterator = try_stack_;
9304 while ((iterator != NULL) && 9340 while ((iterator != NULL) &&
9305 (iterator->try_block()->scope->function_level() == func_level)) { 9341 (iterator->try_block()->scope->function_level() == func_level)) {
9306 // For continue and break node check if the target label is in scope. 9342 // For continue and break node check if the target label is in scope.
9307 if (node->IsJumpNode()) { 9343 if (node->IsJumpNode()) {
9308 SourceLabel* label = node->AsJumpNode()->label(); 9344 SourceLabel* label = node->AsJumpNode()->label();
9309 ASSERT(label != NULL); 9345 ASSERT(label != NULL);
9310 LocalScope* try_scope = iterator->try_block()->scope; 9346 LocalScope* try_scope = iterator->try_block()->scope;
9311 // If the label is defined in a scope which is a child (nested scope) 9347 // If the label is defined in a scope which is a child (nested scope)
9312 // of the try scope then we are not breaking out of this try block 9348 // of the try scope then we are not breaking out of this try block
9313 // so we do not need to inline the finally code. Otherwise we need 9349 // so we do not need to inline the finally code. Otherwise we need
9314 // to inline the finally code of this try block and then move on to the 9350 // to inline the finally code of this try block and then move on to the
9315 // next outer try block. 9351 // next outer try block.
9316 if (label->owner()->IsNestedWithin(try_scope)) { 9352 if (label->owner()->IsNestedWithin(try_scope)) {
9317 break; 9353 break;
9318 } 9354 }
9319 } 9355 }
9320 iterator->AddNodeForFinallyInlining(node); 9356 iterator->AddNodeForFinallyInlining(node);
9321 iterator = iterator->outer_try(); 9357 iterator = iterator->outer_try();
9322 } 9358 }
9323 } 9359 }
9324 9360
9325 9361
9326 // Add the inlined finally clause to the specified node. 9362 // Add the inlined finally clause to the specified node.
9327 void Parser::AddFinallyClauseToNode(bool is_async, 9363 void Parser::AddFinallyClauseToNode(bool is_async,
9328 AstNode* node, 9364 AstNode* node,
9329 InlinedFinallyNode* finally_clause) { 9365 InlinedFinallyNode* finally_clause) {
9330 ReturnNode* return_node = node->AsReturnNode(); 9366 ReturnNode* return_node = node->AsReturnNode();
9331 if (return_node != NULL) { 9367 if (return_node != NULL) {
9332 parsed_function()->EnsureFinallyReturnTemp(is_async); 9368 if (FunctionLevel() == 0) {
9369 parsed_function()->EnsureFinallyReturnTemp(is_async);
9370 }
9333 return_node->AddInlinedFinallyNode(finally_clause); 9371 return_node->AddInlinedFinallyNode(finally_clause);
9334 return; 9372 return;
9335 } 9373 }
9336 JumpNode* jump_node = node->AsJumpNode(); 9374 JumpNode* jump_node = node->AsJumpNode();
9337 ASSERT(jump_node != NULL); 9375 ASSERT(jump_node != NULL);
9338 jump_node->AddInlinedFinallyNode(finally_clause); 9376 jump_node->AddInlinedFinallyNode(finally_clause);
9339 } 9377 }
9340 9378
9341 9379
9342 SequenceNode* Parser::ParseCatchClauses( 9380 SequenceNode* Parser::ParseCatchClauses(
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
9437 catch_blocks.Last() = block; 9475 catch_blocks.Last() = block;
9438 } 9476 }
9439 // This catch clause will handle all exceptions. We can safely forget 9477 // This catch clause will handle all exceptions. We can safely forget
9440 // all previous catch clause types. 9478 // all previous catch clause types.
9441 handler_types.SetLength(0); 9479 handler_types.SetLength(0);
9442 handler_types.Add(*exception_param.type); 9480 handler_types.Add(*exception_param.type);
9443 } else { 9481 } else {
9444 // Has a type specification that is not malformed or malbounded. Now 9482 // Has a type specification that is not malformed or malbounded. Now
9445 // form an 'if type check' to guard the catch handler code. 9483 // form an 'if type check' to guard the catch handler code.
9446 if (!exception_param.type->IsInstantiated() && 9484 if (!exception_param.type->IsInstantiated() &&
9447 (current_block_->scope->function_level() > 0)) { 9485 (FunctionLevel() > 0)) {
9448 // Make sure that the instantiator is captured. 9486 // Make sure that the instantiator is captured.
9449 CaptureInstantiator(); 9487 CaptureInstantiator();
9450 } 9488 }
9451 TypeNode* exception_type = new(Z) TypeNode( 9489 TypeNode* exception_type = new(Z) TypeNode(
9452 catch_pos, *exception_param.type); 9490 catch_pos, *exception_param.type);
9453 AstNode* exception_value = new(Z) LoadLocalNode( 9491 AstNode* exception_value = new(Z) LoadLocalNode(
9454 catch_pos, exception_var); 9492 catch_pos, exception_var);
9455 if (!exception_type->type().IsInstantiated()) { 9493 if (!exception_type->type().IsInstantiated()) {
9456 EnsureExpressionTemp(); 9494 EnsureExpressionTemp();
9457 } 9495 }
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
9852 if (target->kind() == SourceLabel::kSwitch) { 9890 if (target->kind() == SourceLabel::kSwitch) {
9853 ReportError(jump_pos, "'continue' jump to switch statement is illegal"); 9891 ReportError(jump_pos, "'continue' jump to switch statement is illegal");
9854 } else if (target->kind() == SourceLabel::kStatement) { 9892 } else if (target->kind() == SourceLabel::kStatement) {
9855 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", 9893 ReportError(jump_pos, "'continue' jump to label '%s' is illegal",
9856 target->name().ToCString()); 9894 target->name().ToCString());
9857 } 9895 }
9858 } 9896 }
9859 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { 9897 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) {
9860 ReportError(jump_pos, "'break' to case clause label is illegal"); 9898 ReportError(jump_pos, "'break' to case clause label is illegal");
9861 } 9899 }
9862 if (target->FunctionLevel() != current_block_->scope->function_level()) { 9900 if (target->FunctionLevel() != FunctionLevel()) {
9863 ReportError(jump_pos, "'%s' target must be in same function context", 9901 ReportError(jump_pos, "'%s' target must be in same function context",
9864 Token::Str(jump_kind)); 9902 Token::Str(jump_kind));
9865 } 9903 }
9866 return new(Z) JumpNode(jump_pos, jump_kind, target); 9904 return new(Z) JumpNode(jump_pos, jump_kind, target);
9867 } 9905 }
9868 9906
9869 9907
9870 AstNode* Parser::ParseYieldStatement() { 9908 AstNode* Parser::ParseYieldStatement() {
9871 bool is_yield_each = false; 9909 bool is_yield_each = false;
9872 const TokenPosition yield_pos = TokenPos(); 9910 const TokenPosition yield_pos = TokenPos();
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
10051 } else if (token == Token::kSWITCH) { 10089 } else if (token == Token::kSWITCH) {
10052 statement = ParseSwitchStatement(label_name); 10090 statement = ParseSwitchStatement(label_name);
10053 } else if (token == Token::kTRY) { 10091 } else if (token == Token::kTRY) {
10054 statement = ParseTryStatement(label_name); 10092 statement = ParseTryStatement(label_name);
10055 } else if (token == Token::kRETURN) { 10093 } else if (token == Token::kRETURN) {
10056 const TokenPosition return_pos = TokenPos(); 10094 const TokenPosition return_pos = TokenPos();
10057 ConsumeToken(); 10095 ConsumeToken();
10058 if (CurrentToken() != Token::kSEMICOLON) { 10096 if (CurrentToken() != Token::kSEMICOLON) {
10059 const TokenPosition expr_pos = TokenPos(); 10097 const TokenPosition expr_pos = TokenPos();
10060 if (current_function().IsGenerativeConstructor() && 10098 if (current_function().IsGenerativeConstructor() &&
10061 (current_block_->scope->function_level() == 0)) { 10099 (FunctionLevel() == 0)) {
10062 ReportError(expr_pos, 10100 ReportError(expr_pos,
10063 "return of a value is not allowed in constructors"); 10101 "return of a value is not allowed in constructors");
10064 } else if (current_function().IsGeneratorClosure() && 10102 } else if (current_function().IsGeneratorClosure() &&
10065 (current_block_->scope->function_level() == 0)) { 10103 (FunctionLevel() == 0)) {
10066 ReportError(expr_pos, "generator functions may not return a value"); 10104 ReportError(expr_pos, "generator functions may not return a value");
10067 } 10105 }
10068 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); 10106 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
10069 if (I->type_checks() && 10107 if (I->type_checks() &&
10070 current_function().IsAsyncClosure() && 10108 current_function().IsAsyncClosure() && (FunctionLevel() == 0)) {
10071 (current_block_->scope->function_level() == 0)) {
10072 // In checked mode, when the declared result type is Future<T>, verify 10109 // In checked mode, when the declared result type is Future<T>, verify
10073 // that the returned expression is of type T or Future<T> as follows: 10110 // that the returned expression is of type T or Future<T> as follows:
10074 // return temp = expr, temp is Future ? temp as Future<T> : temp as T; 10111 // return temp = expr, temp is Future ? temp as Future<T> : temp as T;
10075 // In case of a mismatch, we need a TypeError and not a CastError, so 10112 // In case of a mismatch, we need a TypeError and not a CastError, so
10076 // we do not actually implement an "as" test, but an "assignable" test. 10113 // we do not actually implement an "as" test, but an "assignable" test.
10077 const Function& async_func = 10114 const Function& async_func =
10078 Function::Handle(Z, current_function().parent_function()); 10115 Function::Handle(Z, current_function().parent_function());
10079 const AbstractType& result_type = 10116 const AbstractType& result_type =
10080 AbstractType::ZoneHandle(Z, async_func.result_type()); 10117 AbstractType::ZoneHandle(Z, async_func.result_type());
10081 const Class& future_class = 10118 const Class& future_class =
(...skipping 30 matching lines...) Expand all
10112 is_future, 10149 is_future,
10113 as_future_t, 10150 as_future_t,
10114 as_t)); 10151 as_t));
10115 expr = checked_expr; 10152 expr = checked_expr;
10116 } 10153 }
10117 } 10154 }
10118 } 10155 }
10119 statement = new(Z) ReturnNode(statement_pos, expr); 10156 statement = new(Z) ReturnNode(statement_pos, expr);
10120 } else { 10157 } else {
10121 if (current_function().IsSyncGenClosure() && 10158 if (current_function().IsSyncGenClosure() &&
10122 (current_block_->scope->function_level() == 0)) { 10159 (FunctionLevel() == 0)) {
10123 // In a synchronous generator, return without an expression 10160 // In a synchronous generator, return without an expression
10124 // returns false, signaling that the iterator terminates and 10161 // returns false, signaling that the iterator terminates and
10125 // did not yield a value. 10162 // did not yield a value.
10126 statement = new(Z) ReturnNode(statement_pos, 10163 statement = new(Z) ReturnNode(statement_pos,
10127 new(Z) LiteralNode(return_pos, Bool::False())); 10164 new(Z) LiteralNode(return_pos, Bool::False()));
10128 } else { 10165 } else {
10129 statement = new(Z) ReturnNode(statement_pos); 10166 statement = new(Z) ReturnNode(statement_pos);
10130 } 10167 }
10131 } 10168 }
10132 AddNodeForFinallyInlining(statement); 10169 AddNodeForFinallyInlining(statement);
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
10522 right_operand = ParseBinaryExpr(current_preced + 1); 10559 right_operand = ParseBinaryExpr(current_preced + 1);
10523 } else { 10560 } else {
10524 // For 'is' and 'as' we expect the right operand to be a type. 10561 // For 'is' and 'as' we expect the right operand to be a type.
10525 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { 10562 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) {
10526 ConsumeToken(); 10563 ConsumeToken();
10527 op_kind = Token::kISNOT; 10564 op_kind = Token::kISNOT;
10528 } 10565 }
10529 const TokenPosition type_pos = TokenPos(); 10566 const TokenPosition type_pos = TokenPos();
10530 const AbstractType& type = AbstractType::ZoneHandle(Z, 10567 const AbstractType& type = AbstractType::ZoneHandle(Z,
10531 ParseType(ClassFinalizer::kCanonicalize)); 10568 ParseType(ClassFinalizer::kCanonicalize));
10532 if (!type.IsInstantiated() && 10569 if (!type.IsInstantiated() && (FunctionLevel() > 0)) {
10533 (current_block_->scope->function_level() > 0)) {
10534 // Make sure that the instantiator is captured. 10570 // Make sure that the instantiator is captured.
10535 CaptureInstantiator(); 10571 CaptureInstantiator();
10536 } 10572 }
10537 right_operand = new(Z) TypeNode(type_pos, type); 10573 right_operand = new(Z) TypeNode(type_pos, type);
10538 // In production mode, the type may be malformed. 10574 // In production mode, the type may be malformed.
10539 // In checked mode, the type may be malformed or malbounded. 10575 // In checked mode, the type may be malformed or malbounded.
10540 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || 10576 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) ||
10541 (op_kind == Token::kAS)) && 10577 (op_kind == Token::kAS)) &&
10542 type.IsMalformedOrMalbounded()) { 10578 type.IsMalformedOrMalbounded()) {
10543 // Note that a type error is thrown in a type test or in 10579 // Note that a type error is thrown in a type test or in
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after
11444 left = LoadClosure(primary_node); 11480 left = LoadClosure(primary_node);
11445 } else if (primary_node->primary().IsTypeParameter()) { 11481 } else if (primary_node->primary().IsTypeParameter()) {
11446 if (ParsingStaticMember()) { 11482 if (ParsingStaticMember()) {
11447 const String& name = String::Handle(Z, 11483 const String& name = String::Handle(Z,
11448 TypeParameter::Cast(primary_node->primary()).name()); 11484 TypeParameter::Cast(primary_node->primary()).name());
11449 ReportError(primary_pos, 11485 ReportError(primary_pos,
11450 "cannot access type parameter '%s' " 11486 "cannot access type parameter '%s' "
11451 "from static function", 11487 "from static function",
11452 name.ToCString()); 11488 name.ToCString());
11453 } 11489 }
11454 if (current_block_->scope->function_level() > 0) { 11490 if (FunctionLevel() > 0) {
11455 // Make sure that the instantiator is captured. 11491 // Make sure that the instantiator is captured.
11456 CaptureInstantiator(); 11492 CaptureInstantiator();
11457 } 11493 }
11458 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); 11494 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z);
11459 type_parameter ^= ClassFinalizer::FinalizeType( 11495 type_parameter ^= ClassFinalizer::FinalizeType(
11460 current_class(), 11496 current_class(),
11461 TypeParameter::Cast(primary_node->primary()), 11497 TypeParameter::Cast(primary_node->primary()),
11462 ClassFinalizer::kCanonicalize); 11498 ClassFinalizer::kCanonicalize);
11463 ASSERT(!type_parameter.IsMalformed()); 11499 ASSERT(!type_parameter.IsMalformed());
11464 left = new(Z) TypeNode(primary->token_pos(), type_parameter); 11500 left = new(Z) TypeNode(primary->token_pos(), type_parameter);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
11540 array = new(Z) TypeNode(primary_pos, type); 11576 array = new(Z) TypeNode(primary_pos, type);
11541 } else if (primary_node->primary().IsTypeParameter()) { 11577 } else if (primary_node->primary().IsTypeParameter()) {
11542 if (ParsingStaticMember()) { 11578 if (ParsingStaticMember()) {
11543 const String& name = String::ZoneHandle(Z, 11579 const String& name = String::ZoneHandle(Z,
11544 TypeParameter::Cast(primary_node->primary()).name()); 11580 TypeParameter::Cast(primary_node->primary()).name());
11545 ReportError(primary_pos, 11581 ReportError(primary_pos,
11546 "cannot access type parameter '%s' " 11582 "cannot access type parameter '%s' "
11547 "from static function", 11583 "from static function",
11548 name.ToCString()); 11584 name.ToCString());
11549 } 11585 }
11550 if (current_block_->scope->function_level() > 0) { 11586 if (FunctionLevel() > 0) {
11551 // Make sure that the instantiator is captured. 11587 // Make sure that the instantiator is captured.
11552 CaptureInstantiator(); 11588 CaptureInstantiator();
11553 } 11589 }
11554 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); 11590 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z);
11555 type_parameter ^= ClassFinalizer::FinalizeType( 11591 type_parameter ^= ClassFinalizer::FinalizeType(
11556 current_class(), 11592 current_class(),
11557 TypeParameter::Cast(primary_node->primary()), 11593 TypeParameter::Cast(primary_node->primary()),
11558 ClassFinalizer::kCanonicalize); 11594 ClassFinalizer::kCanonicalize);
11559 ASSERT(!type_parameter.IsMalformed()); 11595 ASSERT(!type_parameter.IsMalformed());
11560 array = new(Z) TypeNode(primary_pos, type_parameter); 11596 array = new(Z) TypeNode(primary_pos, type_parameter);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
11658 left = new(Z) TypeNode(primary_pos, type); 11694 left = new(Z) TypeNode(primary_pos, type);
11659 } else if (primary_node->primary().IsTypeParameter()) { 11695 } else if (primary_node->primary().IsTypeParameter()) {
11660 if (ParsingStaticMember()) { 11696 if (ParsingStaticMember()) {
11661 const String& name = String::ZoneHandle(Z, 11697 const String& name = String::ZoneHandle(Z,
11662 TypeParameter::Cast(primary_node->primary()).name()); 11698 TypeParameter::Cast(primary_node->primary()).name());
11663 ReportError(primary_pos, 11699 ReportError(primary_pos,
11664 "cannot access type parameter '%s' " 11700 "cannot access type parameter '%s' "
11665 "from static function", 11701 "from static function",
11666 name.ToCString()); 11702 name.ToCString());
11667 } 11703 }
11668 if (current_block_->scope->function_level() > 0) { 11704 if (FunctionLevel() > 0) {
11669 // Make sure that the instantiator is captured. 11705 // Make sure that the instantiator is captured.
11670 CaptureInstantiator(); 11706 CaptureInstantiator();
11671 } 11707 }
11672 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); 11708 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z);
11673 type_parameter ^= ClassFinalizer::FinalizeType( 11709 type_parameter ^= ClassFinalizer::FinalizeType(
11674 current_class(), 11710 current_class(),
11675 TypeParameter::Cast(primary_node->primary()), 11711 TypeParameter::Cast(primary_node->primary()),
11676 ClassFinalizer::kCanonicalize); 11712 ClassFinalizer::kCanonicalize);
11677 ASSERT(!type_parameter.IsMalformed()); 11713 ASSERT(!type_parameter.IsMalformed());
11678 left = new(Z) TypeNode(primary_pos, type_parameter); 11714 left = new(Z) TypeNode(primary_pos, type_parameter);
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
12491 // First try to find the variable in the local scope (block scope or 12527 // First try to find the variable in the local scope (block scope or
12492 // class scope). 12528 // class scope).
12493 AstNode* resolved = NULL; 12529 AstNode* resolved = NULL;
12494 ResolveIdentInLocalScope(ident_pos, ident, &resolved); 12530 ResolveIdentInLocalScope(ident_pos, ident, &resolved);
12495 if (resolved == NULL) { 12531 if (resolved == NULL) {
12496 // Check whether the identifier is a type parameter. 12532 // Check whether the identifier is a type parameter.
12497 if (!current_class().IsNull()) { 12533 if (!current_class().IsNull()) {
12498 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, 12534 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z,
12499 current_class().LookupTypeParameter(ident)); 12535 current_class().LookupTypeParameter(ident));
12500 if (!type_parameter.IsNull()) { 12536 if (!type_parameter.IsNull()) {
12501 if (current_block_->scope->function_level() > 0) { 12537 if (FunctionLevel() > 0) {
12502 // Make sure that the instantiator is captured. 12538 // Make sure that the instantiator is captured.
12503 CaptureInstantiator(); 12539 CaptureInstantiator();
12504 } 12540 }
12505 type_parameter ^= ClassFinalizer::FinalizeType( 12541 type_parameter ^= ClassFinalizer::FinalizeType(
12506 current_class(), type_parameter, ClassFinalizer::kCanonicalize); 12542 current_class(), type_parameter, ClassFinalizer::kCanonicalize);
12507 ASSERT(!type_parameter.IsMalformed()); 12543 ASSERT(!type_parameter.IsMalformed());
12508 return new(Z) TypeNode(ident_pos, type_parameter); 12544 return new(Z) TypeNode(ident_pos, type_parameter);
12509 } 12545 }
12510 } 12546 }
12511 // Not found in the local scope, and the name is not a type parameter. 12547 // Not found in the local scope, and the name is not a type parameter.
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
12832 // Factory call at runtime. 12868 // Factory call at runtime.
12833 const Class& factory_class = 12869 const Class& factory_class =
12834 Class::Handle(Z, Library::LookupCoreClass(Symbols::List())); 12870 Class::Handle(Z, Library::LookupCoreClass(Symbols::List()));
12835 ASSERT(!factory_class.IsNull()); 12871 ASSERT(!factory_class.IsNull());
12836 const Function& factory_method = Function::ZoneHandle(Z, 12872 const Function& factory_method = Function::ZoneHandle(Z,
12837 factory_class.LookupFactory( 12873 factory_class.LookupFactory(
12838 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); 12874 Library::PrivateCoreLibName(Symbols::ListLiteralFactory())));
12839 ASSERT(!factory_method.IsNull()); 12875 ASSERT(!factory_method.IsNull());
12840 if (!list_type_arguments.IsNull() && 12876 if (!list_type_arguments.IsNull() &&
12841 !list_type_arguments.IsInstantiated() && 12877 !list_type_arguments.IsInstantiated() &&
12842 (current_block_->scope->function_level() > 0)) { 12878 (FunctionLevel() > 0)) {
12843 // Make sure that the instantiator is captured. 12879 // Make sure that the instantiator is captured.
12844 CaptureInstantiator(); 12880 CaptureInstantiator();
12845 } 12881 }
12846 TypeArguments& factory_type_args = 12882 TypeArguments& factory_type_args =
12847 TypeArguments::ZoneHandle(Z, list_type_arguments.raw()); 12883 TypeArguments::ZoneHandle(Z, list_type_arguments.raw());
12848 // If the factory class extends other parameterized classes, adjust the 12884 // If the factory class extends other parameterized classes, adjust the
12849 // type argument vector. 12885 // type argument vector.
12850 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { 12886 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) {
12851 ASSERT(factory_type_args.Length() == 1); 12887 ASSERT(factory_type_args.Length() == 1);
12852 Type& factory_type = Type::Handle(Z, Type::New( 12888 Type& factory_type = Type::Handle(Z, Type::New(
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
13094 // Factory call at runtime. 13130 // Factory call at runtime.
13095 const Class& factory_class = 13131 const Class& factory_class =
13096 Class::Handle(Z, Library::LookupCoreClass(Symbols::Map())); 13132 Class::Handle(Z, Library::LookupCoreClass(Symbols::Map()));
13097 ASSERT(!factory_class.IsNull()); 13133 ASSERT(!factory_class.IsNull());
13098 const Function& factory_method = Function::ZoneHandle(Z, 13134 const Function& factory_method = Function::ZoneHandle(Z,
13099 factory_class.LookupFactory( 13135 factory_class.LookupFactory(
13100 Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); 13136 Library::PrivateCoreLibName(Symbols::MapLiteralFactory())));
13101 ASSERT(!factory_method.IsNull()); 13137 ASSERT(!factory_method.IsNull());
13102 if (!map_type_arguments.IsNull() && 13138 if (!map_type_arguments.IsNull() &&
13103 !map_type_arguments.IsInstantiated() && 13139 !map_type_arguments.IsInstantiated() &&
13104 (current_block_->scope->function_level() > 0)) { 13140 (FunctionLevel() > 0)) {
13105 // Make sure that the instantiator is captured. 13141 // Make sure that the instantiator is captured.
13106 CaptureInstantiator(); 13142 CaptureInstantiator();
13107 } 13143 }
13108 TypeArguments& factory_type_args = 13144 TypeArguments& factory_type_args =
13109 TypeArguments::ZoneHandle(Z, map_type_arguments.raw()); 13145 TypeArguments::ZoneHandle(Z, map_type_arguments.raw());
13110 // If the factory class extends other parameterized classes, adjust the 13146 // If the factory class extends other parameterized classes, adjust the
13111 // type argument vector. 13147 // type argument vector.
13112 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) { 13148 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) {
13113 ASSERT(factory_type_args.Length() == 2); 13149 ASSERT(factory_type_args.Length() == 2);
13114 Type& factory_type = Type::Handle(Z, Type::New( 13150 Type& factory_type = Type::Handle(Z, Type::New(
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
13678 "const factory result is not an instance of '%s'", 13714 "const factory result is not an instance of '%s'",
13679 String::Handle(Z, type_bound.UserVisibleName()).ToCString()); 13715 String::Handle(Z, type_bound.UserVisibleName()).ToCString());
13680 new_object = ThrowTypeError(new_pos, type_bound); 13716 new_object = ThrowTypeError(new_pos, type_bound);
13681 } 13717 }
13682 type_bound = AbstractType::null(); 13718 type_bound = AbstractType::null();
13683 } 13719 }
13684 } else { 13720 } else {
13685 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); 13721 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
13686 if (!type_arguments.IsNull() && 13722 if (!type_arguments.IsNull() &&
13687 !type_arguments.IsInstantiated() && 13723 !type_arguments.IsInstantiated() &&
13688 (current_block_->scope->function_level() > 0)) { 13724 (FunctionLevel() > 0)) {
13689 // Make sure that the instantiator is captured. 13725 // Make sure that the instantiator is captured.
13690 CaptureInstantiator(); 13726 CaptureInstantiator();
13691 } 13727 }
13692 // If the type argument vector is not instantiated, we verify in checked 13728 // If the type argument vector is not instantiated, we verify in checked
13693 // mode at runtime that it is within its declared bounds. 13729 // mode at runtime that it is within its declared bounds.
13694 new_object = CreateConstructorCallNode( 13730 new_object = CreateConstructorCallNode(
13695 new_pos, type_arguments, constructor, arguments); 13731 new_pos, type_arguments, constructor, arguments);
13696 } 13732 }
13697 if (!type_bound.IsNull()) { 13733 if (!type_bound.IsNull()) {
13698 new_object = new(Z) AssignableNode( 13734 new_object = new(Z) AssignableNode(
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
14345 SkipActualParameters(); 14381 SkipActualParameters();
14346 } else { 14382 } else {
14347 break; 14383 break;
14348 } 14384 }
14349 } 14385 }
14350 } 14386 }
14351 14387
14352 void Parser::SkipPostfixExpr() { 14388 void Parser::SkipPostfixExpr() {
14353 SkipPrimary(); 14389 SkipPrimary();
14354 if (CurrentToken() == Token::kHASH) { 14390 if (CurrentToken() == Token::kHASH) {
14391 ConsumeToken();
14355 if (IsIdentifier()) { 14392 if (IsIdentifier()) {
14356 ConsumeToken(); 14393 ConsumeToken();
14357 SkipIf(Token::kASSIGN); 14394 SkipIf(Token::kASSIGN);
14358 } else if (Token::CanBeOverloaded(CurrentToken())) { 14395 } else if (Token::CanBeOverloaded(CurrentToken())) {
14359 ConsumeToken(); 14396 ConsumeToken();
14360 } else { 14397 } else {
14361 ReportError("identifier or operator expected"); 14398 ReportError("identifier or operator expected");
14362 } 14399 }
14363 } 14400 }
14364 SkipSelectors(); 14401 SkipSelectors();
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
14537 const ArgumentListNode& function_args, 14574 const ArgumentListNode& function_args,
14538 const LocalVariable* temp_for_last_arg, 14575 const LocalVariable* temp_for_last_arg,
14539 bool is_super_invocation) { 14576 bool is_super_invocation) {
14540 UNREACHABLE(); 14577 UNREACHABLE();
14541 return NULL; 14578 return NULL;
14542 } 14579 }
14543 14580
14544 } // namespace dart 14581 } // namespace dart
14545 14582
14546 #endif // DART_PRECOMPILED_RUNTIME 14583 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/regress_26453_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698