| OLD | NEW |
| 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/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 11 #include "vm/class_finalizer.h" |
| 11 #include "vm/compiler.h" | 12 #include "vm/compiler.h" |
| 12 #include "vm/compiler_stats.h" | 13 #include "vm/compiler_stats.h" |
| 13 #include "vm/dart_api_impl.h" | 14 #include "vm/dart_api_impl.h" |
| 14 #include "vm/dart_entry.h" | 15 #include "vm/dart_entry.h" |
| 15 #include "vm/flags.h" | 16 #include "vm/flags.h" |
| 16 #include "vm/growable_array.h" | 17 #include "vm/growable_array.h" |
| 17 #include "vm/handles.h" | 18 #include "vm/handles.h" |
| 18 #include "vm/heap.h" | 19 #include "vm/heap.h" |
| (...skipping 2962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2981 } | 2982 } |
| 2982 ASSERT((CurrentToken() == Token::kLPAREN) || | 2983 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 2983 func.IsGetterFunction() || | 2984 func.IsGetterFunction() || |
| 2984 func.is_async_closure()); | 2985 func.is_async_closure()); |
| 2985 const bool allow_explicit_default_values = true; | 2986 const bool allow_explicit_default_values = true; |
| 2986 if (func.IsGetterFunction()) { | 2987 if (func.IsGetterFunction()) { |
| 2987 // Populate function scope with the formal parameters. Since in this case | 2988 // Populate function scope with the formal parameters. Since in this case |
| 2988 // we are compiling a getter this will at most populate the receiver. | 2989 // we are compiling a getter this will at most populate the receiver. |
| 2989 AddFormalParamsToScope(¶ms, current_block_->scope); | 2990 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2990 } else if (func.is_async_closure()) { | 2991 } else if (func.is_async_closure()) { |
| 2992 // Async closures have one optional parameter for continuation results. |
| 2993 ParamDesc result_param; |
| 2994 result_param.name = &Symbols::AsyncOperationParam(); |
| 2995 result_param.default_value = &Object::null_instance(); |
| 2996 result_param.type = &Type::ZoneHandle(I, Type::DynamicType()); |
| 2997 params.parameters->Add(result_param); |
| 2998 params.num_optional_parameters++; |
| 2999 params.has_optional_positional_parameters = true; |
| 3000 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 2991 AddFormalParamsToScope(¶ms, current_block_->scope); | 3001 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2992 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 3002 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 2993 ASSERT(func.NumParameters() == params.parameters->length()); | 3003 ASSERT(func.NumParameters() == params.parameters->length()); |
| 2994 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { | 3004 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { |
| 2995 // Parse away any formal parameters, as they are accessed as as context | 3005 // Parse away any formal parameters, as they are accessed as as context |
| 2996 // variables. | 3006 // variables. |
| 2997 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 3007 ParamList parse_away; |
| 3008 ParseFormalParameterList(allow_explicit_default_values, |
| 3009 false, |
| 3010 &parse_away); |
| 2998 } | 3011 } |
| 2999 } else { | 3012 } else { |
| 3000 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 3013 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 3001 | 3014 |
| 3002 // The number of parameters and their type are not yet set in local | 3015 // The number of parameters and their type are not yet set in local |
| 3003 // functions, since they are not 'top-level' parsed. | 3016 // functions, since they are not 'top-level' parsed. |
| 3004 if (func.IsLocalFunction()) { | 3017 if (func.IsLocalFunction()) { |
| 3005 AddFormalParamsToFunction(¶ms, func); | 3018 AddFormalParamsToFunction(¶ms, func); |
| 3006 } | 3019 } |
| 3007 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3020 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 3037 } | 3050 } |
| 3038 | 3051 |
| 3039 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 3052 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
| 3040 func.set_modifier(func_modifier); | 3053 func.set_modifier(func_modifier); |
| 3041 | 3054 |
| 3042 OpenBlock(); // Open a nested scope for the outermost function block. | 3055 OpenBlock(); // Open a nested scope for the outermost function block. |
| 3043 | 3056 |
| 3044 Function& async_closure = Function::ZoneHandle(I); | 3057 Function& async_closure = Function::ZoneHandle(I); |
| 3045 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3058 if (func.IsAsyncFunction() && !func.is_async_closure()) { |
| 3046 async_closure = OpenAsyncFunction(formal_params_pos); | 3059 async_closure = OpenAsyncFunction(formal_params_pos); |
| 3060 } else if (func.is_async_closure()) { |
| 3061 OpenAsyncClosure(); |
| 3047 } | 3062 } |
| 3048 | 3063 |
| 3049 intptr_t end_token_pos = 0; | 3064 intptr_t end_token_pos = 0; |
| 3050 if (CurrentToken() == Token::kLBRACE) { | 3065 if (CurrentToken() == Token::kLBRACE) { |
| 3051 ConsumeToken(); | 3066 ConsumeToken(); |
| 3052 if (String::Handle(I, func.name()).Equals( | 3067 if (String::Handle(I, func.name()).Equals( |
| 3053 Symbols::EqualOperator())) { | 3068 Symbols::EqualOperator())) { |
| 3054 const Class& owner = Class::Handle(I, func.Owner()); | 3069 const Class& owner = Class::Handle(I, func.Owner()); |
| 3055 if (!owner.IsObjectClass()) { | 3070 if (!owner.IsObjectClass()) { |
| 3056 AddEqualityNullCheck(); | 3071 AddEqualityNullCheck(); |
| (...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5519 // We are parsing a nested function while compiling the enclosing function. | 5534 // We are parsing a nested function while compiling the enclosing function. |
| 5520 outer_scope = | 5535 outer_scope = |
| 5521 new(I) LocalScope(current_block_->scope, | 5536 new(I) LocalScope(current_block_->scope, |
| 5522 current_block_->scope->function_level() + 1, | 5537 current_block_->scope->function_level() + 1, |
| 5523 0); | 5538 0); |
| 5524 } | 5539 } |
| 5525 ChainNewBlock(outer_scope); | 5540 ChainNewBlock(outer_scope); |
| 5526 } | 5541 } |
| 5527 | 5542 |
| 5528 | 5543 |
| 5544 void Parser::OpenAsyncClosure() { |
| 5545 TRACE_PARSER("OpenAsyncClosure"); |
| 5546 parsed_function()->set_await_temps_scope(current_block_->scope); |
| 5547 // TODO(mlippautz): Set up explicit jump table for await continuations. |
| 5548 } |
| 5549 |
| 5550 |
| 5529 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { | 5551 RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) { |
| 5552 TRACE_PARSER("OpenAsyncFunction"); |
| 5530 // Create the closure containing the old body of this function. | 5553 // Create the closure containing the old body of this function. |
| 5531 Class& sig_cls = Class::ZoneHandle(I); | 5554 Class& sig_cls = Class::ZoneHandle(I); |
| 5532 Type& sig_type = Type::ZoneHandle(I); | 5555 Type& sig_type = Type::ZoneHandle(I); |
| 5533 Function& closure = Function::ZoneHandle(I); | 5556 Function& closure = Function::ZoneHandle(I); |
| 5534 String& sig = String::ZoneHandle(I); | 5557 String& sig = String::ZoneHandle(I); |
| 5535 ParamList closure_params; | 5558 ParamList closure_params; |
| 5536 closure_params.AddFinalParameter( | 5559 closure_params.AddFinalParameter( |
| 5537 formal_param_pos, | 5560 formal_param_pos, |
| 5538 &Symbols::ClosureParameter(), | 5561 &Symbols::ClosureParameter(), |
| 5539 &Type::ZoneHandle(I, Type::DynamicType())); | 5562 &Type::ZoneHandle(I, Type::DynamicType())); |
| 5563 ParamDesc result_param; |
| 5564 result_param.name = &Symbols::AsyncOperationParam(); |
| 5565 result_param.default_value = &Object::null_instance(); |
| 5566 result_param.type = &Type::ZoneHandle(I, Type::DynamicType()); |
| 5567 closure_params.parameters->Add(result_param); |
| 5568 closure_params.has_optional_positional_parameters = true; |
| 5569 closure_params.num_optional_parameters++; |
| 5540 closure = Function::NewClosureFunction( | 5570 closure = Function::NewClosureFunction( |
| 5541 Symbols::AnonymousClosure(), | 5571 Symbols::AnonymousClosure(), |
| 5542 innermost_function(), | 5572 innermost_function(), |
| 5543 formal_param_pos); | 5573 formal_param_pos); |
| 5544 AddFormalParamsToFunction(&closure_params, closure); | 5574 AddFormalParamsToFunction(&closure_params, closure); |
| 5545 closure.set_is_async_closure(true); | 5575 closure.set_is_async_closure(true); |
| 5546 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | 5576 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); |
| 5547 sig = closure.Signature(); | 5577 sig = closure.Signature(); |
| 5548 sig_cls = library_.LookupLocalClass(sig); | 5578 sig_cls = library_.LookupLocalClass(sig); |
| 5549 if (sig_cls.IsNull()) { | 5579 if (sig_cls.IsNull()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5573 current_block_->scope->set_begin_token_pos(statements->token_pos()); | 5603 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
| 5574 current_block_->scope->set_end_token_pos(TokenPos()); | 5604 current_block_->scope->set_end_token_pos(TokenPos()); |
| 5575 } | 5605 } |
| 5576 current_block_ = current_block_->parent; | 5606 current_block_ = current_block_->parent; |
| 5577 return statements; | 5607 return statements; |
| 5578 } | 5608 } |
| 5579 | 5609 |
| 5580 | 5610 |
| 5581 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, | 5611 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, |
| 5582 SequenceNode* closure_body) { | 5612 SequenceNode* closure_body) { |
| 5613 TRACE_PARSER("CloseAsyncFunction"); |
| 5583 ASSERT(!closure.IsNull()); | 5614 ASSERT(!closure.IsNull()); |
| 5584 ASSERT(closure_body != NULL); | 5615 ASSERT(closure_body != NULL); |
| 5585 // The block for the async closure body has already been closed. Close the | 5616 // The block for the async closure body has already been closed. Close the |
| 5586 // corresponding function block. | 5617 // corresponding function block. |
| 5587 CloseBlock(); | 5618 CloseBlock(); |
| 5588 | 5619 |
| 5589 // Create and return a new future that executes a closure with the current | 5620 // Create and return a new future that executes a closure with the current |
| 5590 // body. | 5621 // body. |
| 5591 | 5622 |
| 5592 bool found = false; | 5623 bool found = false; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5669 new (I) LoadLocalNode( | 5700 new (I) LoadLocalNode( |
| 5670 Scanner::kNoSourcePos, | 5701 Scanner::kNoSourcePos, |
| 5671 async_completer), | 5702 async_completer), |
| 5672 Symbols::CompleterFuture())); | 5703 Symbols::CompleterFuture())); |
| 5673 current_block_->statements->Add(return_node); | 5704 current_block_->statements->Add(return_node); |
| 5674 return CloseBlock(); | 5705 return CloseBlock(); |
| 5675 } | 5706 } |
| 5676 | 5707 |
| 5677 | 5708 |
| 5678 void Parser::CloseAsyncClosure(SequenceNode* body) { | 5709 void Parser::CloseAsyncClosure(SequenceNode* body) { |
| 5710 TRACE_PARSER("CloseAsyncClosure"); |
| 5679 // We need a temporary expression to store intermediate return values. | 5711 // We need a temporary expression to store intermediate return values. |
| 5680 parsed_function()->EnsureExpressionTemp(); | 5712 parsed_function()->EnsureExpressionTemp(); |
| 5681 } | 5713 } |
| 5682 | 5714 |
| 5683 | 5715 |
| 5684 // Set up default values for all optional parameters to the function. | 5716 // Set up default values for all optional parameters to the function. |
| 5685 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, | 5717 void Parser::SetupDefaultsForOptionalParams(const ParamList* params, |
| 5686 Array* default_values) { | 5718 Array* default_values) { |
| 5687 if (params->num_optional_parameters > 0) { | 5719 if (params->num_optional_parameters > 0) { |
| 5688 // Build array of default parameter values. | 5720 // Build array of default parameter values. |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5871 const intptr_t ident_pos = TokenPos(); | 5903 const intptr_t ident_pos = TokenPos(); |
| 5872 const String& ident = *CurrentLiteral(); | 5904 const String& ident = *CurrentLiteral(); |
| 5873 LocalVariable* variable = new(I) LocalVariable( | 5905 LocalVariable* variable = new(I) LocalVariable( |
| 5874 ident_pos, ident, type); | 5906 ident_pos, ident, type); |
| 5875 ConsumeToken(); // Variable identifier. | 5907 ConsumeToken(); // Variable identifier. |
| 5876 AstNode* initialization = NULL; | 5908 AstNode* initialization = NULL; |
| 5877 if (CurrentToken() == Token::kASSIGN) { | 5909 if (CurrentToken() == Token::kASSIGN) { |
| 5878 // Variable initialization. | 5910 // Variable initialization. |
| 5879 const intptr_t assign_pos = TokenPos(); | 5911 const intptr_t assign_pos = TokenPos(); |
| 5880 ConsumeToken(); | 5912 ConsumeToken(); |
| 5881 AstNode* expr = ParseExpr(is_const, kConsumeCascades); | 5913 AstNode* expr = ParseAwaitableExpr(is_const, kConsumeCascades); |
| 5882 initialization = new(I) StoreLocalNode( | 5914 initialization = new(I) StoreLocalNode( |
| 5883 assign_pos, variable, expr); | 5915 assign_pos, variable, expr); |
| 5884 if (is_const) { | 5916 if (is_const) { |
| 5885 ASSERT(expr->IsLiteralNode()); | 5917 ASSERT(expr->IsLiteralNode()); |
| 5886 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 5918 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 5887 } | 5919 } |
| 5888 } else if (is_final || is_const) { | 5920 } else if (is_final || is_const) { |
| 5889 ReportError(ident_pos, | 5921 ReportError(ident_pos, |
| 5890 "missing initialization of 'final' or 'const' variable"); | 5922 "missing initialization of 'final' or 'const' variable"); |
| 5891 } else { | 5923 } else { |
| (...skipping 1852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7744 scope->LocalLookupVariable(Symbols::ExceptionVar()); | 7776 scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 7745 ASSERT(excp_var != NULL); | 7777 ASSERT(excp_var != NULL); |
| 7746 LocalVariable* trace_var = | 7778 LocalVariable* trace_var = |
| 7747 scope->LocalLookupVariable(Symbols::StackTraceVar()); | 7779 scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 7748 ASSERT(trace_var != NULL); | 7780 ASSERT(trace_var != NULL); |
| 7749 statement = new(I) ThrowNode( | 7781 statement = new(I) ThrowNode( |
| 7750 statement_pos, | 7782 statement_pos, |
| 7751 new(I) LoadLocalNode(statement_pos, excp_var), | 7783 new(I) LoadLocalNode(statement_pos, excp_var), |
| 7752 new(I) LoadLocalNode(statement_pos, trace_var)); | 7784 new(I) LoadLocalNode(statement_pos, trace_var)); |
| 7753 } else { | 7785 } else { |
| 7754 statement = ParseExpr(kAllowConst, kConsumeCascades); | 7786 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades); |
| 7755 ExpectSemicolon(); | 7787 ExpectSemicolon(); |
| 7756 } | 7788 } |
| 7757 return statement; | 7789 return statement; |
| 7758 } | 7790 } |
| 7759 | 7791 |
| 7760 | 7792 |
| 7761 void Parser::ReportError(const Error& error) { | 7793 void Parser::ReportError(const Error& error) { |
| 7762 Report::LongJump(error); | 7794 Report::LongJump(error); |
| 7763 UNREACHABLE(); | 7795 UNREACHABLE(); |
| 7764 } | 7796 } |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8400 ASSERT(field.value() != Object::sentinel().raw()); | 8432 ASSERT(field.value() != Object::sentinel().raw()); |
| 8401 ASSERT(field.value() != Object::transition_sentinel().raw()); | 8433 ASSERT(field.value() != Object::transition_sentinel().raw()); |
| 8402 return new(iso) LiteralNode(expr->token_pos(), | 8434 return new(iso) LiteralNode(expr->token_pos(), |
| 8403 Instance::ZoneHandle(iso, field.value())); | 8435 Instance::ZoneHandle(iso, field.value())); |
| 8404 } | 8436 } |
| 8405 } | 8437 } |
| 8406 return expr; | 8438 return expr; |
| 8407 } | 8439 } |
| 8408 | 8440 |
| 8409 | 8441 |
| 8442 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, |
| 8443 bool consume_cascades) { |
| 8444 TRACE_PARSER("ParseAwaitableExpr"); |
| 8445 parsed_function()->reset_have_seen_await(); |
| 8446 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 8447 if (parsed_function()->have_seen_await()) { |
| 8448 if (!current_block_->scope->LookupVariable( |
| 8449 Symbols::AsyncOperation(), true)) { |
| 8450 // Async operations are always encapsulated into a local function. We only |
| 8451 // need to transform the expression when generating code for this inner |
| 8452 // function. |
| 8453 return expr; |
| 8454 } |
| 8455 SequenceNode* intermediates_block = new(I) SequenceNode( |
| 8456 Scanner::kNoSourcePos, current_block_->scope); |
| 8457 AwaitTransformer at(intermediates_block, library_, parsed_function()); |
| 8458 AstNode* result = at.Transform(expr); |
| 8459 current_block_->statements->Add(intermediates_block); |
| 8460 parsed_function()->reset_have_seen_await(); |
| 8461 return result; |
| 8462 } |
| 8463 return expr; |
| 8464 } |
| 8465 |
| 8466 |
| 8410 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 8467 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 8411 bool consume_cascades) { | 8468 bool consume_cascades) { |
| 8412 TRACE_PARSER("ParseExpr"); | 8469 TRACE_PARSER("ParseExpr"); |
| 8413 String* expr_ident = | 8470 String* expr_ident = |
| 8414 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8471 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8415 const intptr_t expr_pos = TokenPos(); | 8472 const intptr_t expr_pos = TokenPos(); |
| 8416 | 8473 |
| 8417 if (CurrentToken() == Token::kTHROW) { | 8474 if (CurrentToken() == Token::kTHROW) { |
| 8418 ConsumeToken(); | 8475 ConsumeToken(); |
| 8419 if (CurrentToken() == Token::kSEMICOLON) { | 8476 if (CurrentToken() == Token::kSEMICOLON) { |
| (...skipping 2348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10768 TRACE_PARSER("ParsePrimary"); | 10825 TRACE_PARSER("ParsePrimary"); |
| 10769 ASSERT(!is_top_level_); | 10826 ASSERT(!is_top_level_); |
| 10770 AstNode* primary = NULL; | 10827 AstNode* primary = NULL; |
| 10771 const Token::Kind token = CurrentToken(); | 10828 const Token::Kind token = CurrentToken(); |
| 10772 if (IsFunctionLiteral()) { | 10829 if (IsFunctionLiteral()) { |
| 10773 // The name of a literal function is visible from inside the function, but | 10830 // The name of a literal function is visible from inside the function, but |
| 10774 // must not collide with names in the scope declaring the literal. | 10831 // must not collide with names in the scope declaring the literal. |
| 10775 OpenBlock(); | 10832 OpenBlock(); |
| 10776 primary = ParseFunctionStatement(true); | 10833 primary = ParseFunctionStatement(true); |
| 10777 CloseBlock(); | 10834 CloseBlock(); |
| 10835 } else if (IsLiteral("await") && |
| 10836 (parsed_function()->function().IsAsyncFunction() || |
| 10837 parsed_function()->function().is_async_closure())) { |
| 10838 // The body of an async function is parsed multiple times. The first time |
| 10839 // when setting up an AsyncFunction() for generating relevant scope |
| 10840 // information. The second time the body is parsed for actually generating |
| 10841 // code. |
| 10842 TRACE_PARSER("ParseAwaitExpr"); |
| 10843 ConsumeToken(); |
| 10844 parsed_function()->record_await(); |
| 10845 primary = new(I) AwaitNode( |
| 10846 TokenPos(), ParseExpr(kAllowConst, kConsumeCascades)); |
| 10778 } else if (IsIdentifier()) { | 10847 } else if (IsIdentifier()) { |
| 10779 intptr_t qual_ident_pos = TokenPos(); | 10848 intptr_t qual_ident_pos = TokenPos(); |
| 10780 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(I, ParsePrefix()); | 10849 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(I, ParsePrefix()); |
| 10781 String& ident = *CurrentLiteral(); | 10850 String& ident = *CurrentLiteral(); |
| 10782 ConsumeToken(); | 10851 ConsumeToken(); |
| 10783 if (prefix.IsNull()) { | 10852 if (prefix.IsNull()) { |
| 10784 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { | 10853 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { |
| 10785 // Check whether the identifier is a type parameter. | 10854 // Check whether the identifier is a type parameter. |
| 10786 if (!current_class().IsNull()) { | 10855 if (!current_class().IsNull()) { |
| 10787 TypeParameter& type_param = TypeParameter::ZoneHandle(I, | 10856 TypeParameter& type_param = TypeParameter::ZoneHandle(I, |
| (...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11308 void Parser::SkipQualIdent() { | 11377 void Parser::SkipQualIdent() { |
| 11309 ASSERT(IsIdentifier()); | 11378 ASSERT(IsIdentifier()); |
| 11310 ConsumeToken(); | 11379 ConsumeToken(); |
| 11311 if (CurrentToken() == Token::kPERIOD) { | 11380 if (CurrentToken() == Token::kPERIOD) { |
| 11312 ConsumeToken(); // Consume the kPERIOD token. | 11381 ConsumeToken(); // Consume the kPERIOD token. |
| 11313 ExpectIdentifier("identifier expected after '.'"); | 11382 ExpectIdentifier("identifier expected after '.'"); |
| 11314 } | 11383 } |
| 11315 } | 11384 } |
| 11316 | 11385 |
| 11317 } // namespace dart | 11386 } // namespace dart |
| OLD | NEW |