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

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

Issue 2269693002: Implement parsing support for generic functions (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 3 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/generic_functions_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 30 matching lines...) Expand all
41 41
42 namespace dart { 42 namespace dart {
43 43
44 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\"."); 44 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\".");
45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); 45 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
46 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); 46 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef.");
47 // TODO(floitsch): remove the conditional-directive flag, once we publicly 47 // TODO(floitsch): remove the conditional-directive flag, once we publicly
48 // committed to the current version. 48 // committed to the current version.
49 DEFINE_FLAG(bool, conditional_directives, true, 49 DEFINE_FLAG(bool, conditional_directives, true,
50 "Enable conditional directives"); 50 "Enable conditional directives");
51 DEFINE_FLAG(bool, generic_method_syntax, false, "Enable generic functions.");
51 DEFINE_FLAG(bool, initializing_formal_access, false, 52 DEFINE_FLAG(bool, initializing_formal_access, false,
52 "Make initializing formal parameters visible in initializer list."); 53 "Make initializing formal parameters visible in initializer list.");
53 DEFINE_FLAG(bool, warn_super, false, 54 DEFINE_FLAG(bool, warn_super, false,
54 "Warning if super initializer not last in initializer list."); 55 "Warning if super initializer not last in initializer list.");
55 DEFINE_FLAG(bool, warn_patch, false, "Warn on old-style patch syntax."); 56 DEFINE_FLAG(bool, warn_patch, false, "Warn on old-style patch syntax.");
56 DEFINE_FLAG(bool, await_is_keyword, false, 57 DEFINE_FLAG(bool, await_is_keyword, false,
57 "await and yield are treated as proper keywords in synchronous code."); 58 "await and yield are treated as proper keywords in synchronous code.");
58 59
59 DECLARE_FLAG(bool, profile_vm); 60 DECLARE_FLAG(bool, profile_vm);
60 DECLARE_FLAG(bool, trace_service); 61 DECLARE_FLAG(bool, trace_service);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 ~BoolScope() { 119 ~BoolScope() {
119 *_addr = _saved_value; 120 *_addr = _saved_value;
120 } 121 }
121 122
122 private: 123 private:
123 bool* _addr; 124 bool* _addr;
124 bool _saved_value; 125 bool _saved_value;
125 }; 126 };
126 127
127 128
129 // Helper class to save and restore token position.
130 class Parser::TokenPosScope : public ValueObject {
131 public:
132 explicit TokenPosScope(Parser *p) : p_(p) {
133 saved_pos_ = p_->TokenPos();
134 }
135 TokenPosScope(Parser *p, TokenPosition pos) : p_(p), saved_pos_(pos) {
136 }
137 ~TokenPosScope() {
138 p_->SetPosition(saved_pos_);
139 }
140
141 private:
142 Parser* p_;
143 TokenPosition saved_pos_;
144 DISALLOW_COPY_AND_ASSIGN(TokenPosScope);
145 };
146
147
128 class RecursionChecker : public ValueObject { 148 class RecursionChecker : public ValueObject {
129 public: 149 public:
130 explicit RecursionChecker(Parser* p) : parser_(p) { 150 explicit RecursionChecker(Parser* p) : parser_(p) {
131 parser_->recursion_counter_++; 151 parser_->recursion_counter_++;
132 // No need to check the stack unless the parser is in an unusually deep 152 // No need to check the stack unless the parser is in an unusually deep
133 // recurive state. Thus, we omit the more expensive stack checks in 153 // recurive state. Thus, we omit the more expensive stack checks in
134 // the common case. 154 // the common case.
135 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary. 155 const int kMaxUncheckedDepth = 100; // Somewhat arbitrary.
136 if (parser_->recursion_counter_ > kMaxUncheckedDepth) { 156 if (parser_->recursion_counter_ > kMaxUncheckedDepth) {
137 parser_->CheckStack(); 157 parser_->CheckStack();
(...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
2058 const intptr_t num_existing_parameters = 2078 const intptr_t num_existing_parameters =
2059 params->num_fixed_parameters + params->num_optional_parameters; 2079 params->num_fixed_parameters + params->num_optional_parameters;
2060 for (intptr_t i = 0; i < num_existing_parameters; i++) { 2080 for (intptr_t i = 0; i < num_existing_parameters; i++) {
2061 ParamDesc& existing_parameter = (*params->parameters)[i]; 2081 ParamDesc& existing_parameter = (*params->parameters)[i];
2062 if (existing_parameter.name->Equals(*parameter.name)) { 2082 if (existing_parameter.name->Equals(*parameter.name)) {
2063 ReportError(parameter.name_pos, "duplicate formal parameter '%s'", 2083 ReportError(parameter.name_pos, "duplicate formal parameter '%s'",
2064 parameter.name->ToCString()); 2084 parameter.name->ToCString());
2065 } 2085 }
2066 } 2086 }
2067 2087
2068 if (CurrentToken() == Token::kLPAREN) { 2088 if (IsParameterPart()) {
2069 // This parameter is probably a closure. If we saw the keyword 'var' 2089 // This parameter is probably a closure. If we saw the keyword 'var'
2070 // or 'final', a closure is not legal here and we ignore the 2090 // or 'final', a closure is not legal here and we ignore the
2071 // opening parens. 2091 // opening parens.
2072 // TODO(hausner): The language spec appears to allow var and final 2092 // TODO(hausner): The language spec appears to allow var and final
2073 // in signature types when used with initializing formals: 2093 // in signature types when used with initializing formals:
2074 // fieldFormalParameter: 2094 // fieldFormalParameter:
2075 // metadata finalConstVarOrType? this ‘.’ identifier formalParameterList? ; 2095 // metadata finalConstVarOrType? this ‘.’ identifier formalParameterList? ;
2076 if (!var_seen && !final_seen) { 2096 if (!var_seen && !final_seen) {
2077 // The parsed parameter type is actually the function result type. 2097 // The parsed parameter type is actually the function result type.
2078 const AbstractType& result_type = 2098 const AbstractType& result_type =
2079 AbstractType::Handle(Z, parameter.type->raw()); 2099 AbstractType::Handle(Z, parameter.type->raw());
2080 2100
2081 // Finish parsing the function type parameter. 2101 // Finish parsing the function type parameter.
2102 if (CurrentToken() == Token::kLT) {
2103 // TODO(hausner): handle generic function types.
2104 if (!FLAG_generic_method_syntax) {
2105 ReportError("generic function types not supported");
2106 }
2107 TokenPosition type_param_pos = TokenPos();
2108 if (!TryParseTypeParameters()) {
2109 ReportError(type_param_pos, "error in type parameters");
2110 }
2111 }
2112
2113 ASSERT(CurrentToken() == Token::kLPAREN);
2082 ParamList func_params; 2114 ParamList func_params;
2083 2115
2084 // Add implicit closure object parameter. 2116 // Add implicit closure object parameter.
2085 func_params.AddFinalParameter( 2117 func_params.AddFinalParameter(
2086 TokenPos(), 2118 TokenPos(),
2087 &Symbols::ClosureParameter(), 2119 &Symbols::ClosureParameter(),
2088 &Object::dynamic_type()); 2120 &Object::dynamic_type());
2089 2121
2090 const bool no_explicit_default_values = false; 2122 const bool no_explicit_default_values = false;
2091 ParseFormalParameterList(no_explicit_default_values, false, &func_params); 2123 ParseFormalParameterList(no_explicit_default_values, false, &func_params);
(...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after
3709 3741
3710 // We have a name that is not shadowed, followed by a period or #. 3742 // We have a name that is not shadowed, followed by a period or #.
3711 // Consume the identifier, let the caller consume the . or #. 3743 // Consume the identifier, let the caller consume the . or #.
3712 ConsumeToken(); 3744 ConsumeToken();
3713 return prefix.raw(); 3745 return prefix.raw();
3714 } 3746 }
3715 3747
3716 3748
3717 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { 3749 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
3718 TRACE_PARSER("ParseMethodOrConstructor"); 3750 TRACE_PARSER("ParseMethodOrConstructor");
3719 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); 3751 // We are at the beginning of the formal parameters list.
3752 ASSERT(CurrentToken() == Token::kLPAREN ||
3753 CurrentToken() == Token::kLT ||
3754 method->IsGetter());
3720 ASSERT(method->type != NULL); 3755 ASSERT(method->type != NULL);
3721 ASSERT(current_member_ == method); 3756 ASSERT(current_member_ == method);
3722 3757
3723 if (method->has_var) { 3758 if (method->has_var) {
3724 ReportError(method->name_pos, "keyword var not allowed for methods"); 3759 ReportError(method->name_pos, "keyword var not allowed for methods");
3725 } 3760 }
3726 if (method->has_final) { 3761 if (method->has_final) {
3727 ReportError(method->name_pos, "'final' not allowed for methods"); 3762 ReportError(method->name_pos, "'final' not allowed for methods");
3728 } 3763 }
3729 if (method->has_abstract && method->has_static) { 3764 if (method->has_abstract && method->has_static) {
3730 ReportError(method->name_pos, 3765 ReportError(method->name_pos,
3731 "static method '%s' cannot be abstract", 3766 "static method '%s' cannot be abstract",
3732 method->name->ToCString()); 3767 method->name->ToCString());
3733 } 3768 }
3734 if (method->has_const && !method->IsFactoryOrConstructor()) { 3769 if (method->has_const && !method->IsFactoryOrConstructor()) {
3735 ReportError(method->name_pos, "'const' not allowed for methods"); 3770 ReportError(method->name_pos, "'const' not allowed for methods");
3736 } 3771 }
3737 if (method->has_abstract && method->IsFactoryOrConstructor()) { 3772 if (method->has_abstract && method->IsFactoryOrConstructor()) {
3738 ReportError(method->name_pos, "constructor cannot be abstract"); 3773 ReportError(method->name_pos, "constructor cannot be abstract");
3739 } 3774 }
3740 if (method->has_const && method->IsConstructor()) { 3775 if (method->has_const && method->IsConstructor()) {
3741 current_class().set_is_const(); 3776 current_class().set_is_const();
3742 } 3777 }
3743 3778
3779 if (CurrentToken() == Token::kLT) {
3780 // Parse type parameters, but ignore them.
3781 // TODO(hausner): handle type parameters.
3782 if (!FLAG_generic_method_syntax) {
3783 ReportError("generic type arguments not supported.");
3784 }
3785 TokenPosition type_param_pos = TokenPos();
3786 if (method->IsFactoryOrConstructor()) {
3787 ReportError(method->name_pos, "constructor cannot be generic");
3788 }
3789 if (method->IsGetter() || method->IsSetter()) {
3790 ReportError(type_param_pos, "%s cannot be generic",
3791 method->IsGetter() ? "getter" : "setter");
3792 }
3793 if (!TryParseTypeParameters()) {
3794 ReportError(type_param_pos, "error in type parameters");
3795 }
3796 }
3797
3744 // Parse the formal parameters. 3798 // Parse the formal parameters.
3745 const bool are_implicitly_final = method->has_const; 3799 const bool are_implicitly_final = method->has_const;
3746 const bool allow_explicit_default_values = true; 3800 const bool allow_explicit_default_values = true;
3747 const TokenPosition formal_param_pos = TokenPos(); 3801 const TokenPosition formal_param_pos = TokenPos();
3748 method->params.Clear(); 3802 method->params.Clear();
3749 // Static functions do not have a receiver. 3803 // Static functions do not have a receiver.
3750 // The first parameter of a factory is the TypeArguments vector of 3804 // The first parameter of a factory is the TypeArguments vector of
3751 // the type of the instance to be allocated. 3805 // the type of the instance to be allocated.
3752 if (!method->has_static || method->IsConstructor()) { 3806 if (!method->has_static || method->IsConstructor()) {
3753 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); 3807 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos);
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
4334 } else if ((CurrentToken() == Token::kFACTORY) && 4388 } else if ((CurrentToken() == Token::kFACTORY) &&
4335 (LookaheadToken(1) != Token::kLPAREN)) { 4389 (LookaheadToken(1) != Token::kLPAREN)) {
4336 ConsumeToken(); 4390 ConsumeToken();
4337 if (member.has_static) { 4391 if (member.has_static) {
4338 ReportError("factory method cannot be explicitly marked static"); 4392 ReportError("factory method cannot be explicitly marked static");
4339 } 4393 }
4340 member.has_factory = true; 4394 member.has_factory = true;
4341 member.has_static = true; 4395 member.has_static = true;
4342 // The result type depends on the name of the factory method. 4396 // The result type depends on the name of the factory method.
4343 } 4397 }
4398
4344 // Optionally parse a type. 4399 // Optionally parse a type.
4345 if (CurrentToken() == Token::kVOID) { 4400 if (CurrentToken() == Token::kVOID) {
4346 if (member.has_var || member.has_factory) { 4401 if (member.has_var || member.has_factory) {
4347 ReportError("void not expected"); 4402 ReportError("void not expected");
4348 } 4403 }
4349 ConsumeToken(); 4404 ConsumeToken();
4350 ASSERT(member.type == NULL); 4405 ASSERT(member.type == NULL);
4351 member.type = &Object::void_type(); 4406 member.type = &Object::void_type();
4352 } else if (CurrentToken() == Token::kIDENT) { 4407 } else {
4353 // This is either a type name or the name of a method/constructor/field. 4408 bool found_type = false;
4354 if ((member.type == NULL) && !member.has_factory) { 4409 {
4355 // We have not seen a member type yet, so we check if the next 4410 // Lookahead to determine whether the next tokens are a return type.
4356 // identifier could represent a type before parsing it. 4411 TokenPosScope saved_pos(this);
4357 Token::Kind follower = LookaheadToken(1); 4412 if (TryParseReturnType()) {
4358 // We have an identifier followed by a 'follower' token. 4413 if (IsIdentifier() ||
4359 // We either parse a type or assume that no type is specified. 4414 (CurrentToken() == Token::kGET) ||
4360 if ((follower == Token::kLT) || // Parameterized type. 4415 (CurrentToken() == Token::kSET) ||
4361 (follower == Token::kGET) || // Getter following a type. 4416 (CurrentToken() == Token::kOPERATOR)) {
4362 (follower == Token::kSET) || // Setter following a type. 4417 found_type = true;
4363 (follower == Token::kOPERATOR) || // Operator following a type. 4418 }
4364 (Token::IsIdentifier(follower)) || // Member name following a type.
4365 ((follower == Token::kPERIOD) && // Qualified class name of type,
4366 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr.
4367 ASSERT(is_top_level_);
4368 // The declared type of fields is never ignored, even in unchecked mode,
4369 // because getters and setters could be closurized at some time (not
4370 // supported yet).
4371 member.type = &AbstractType::ZoneHandle(Z,
4372 ParseType(ClassFinalizer::kResolveTypeParameters));
4373 } 4419 }
4374 } 4420 }
4421 if (found_type) {
4422 member.type = &AbstractType::ZoneHandle(Z,
4423 ParseType(ClassFinalizer::kResolveTypeParameters));
4424 }
4375 } 4425 }
4376 4426
4377 // Optionally parse a (possibly named) constructor name or factory. 4427 // Optionally parse a (possibly named) constructor name or factory.
4378 if (IsIdentifier() && 4428 if (IsIdentifier() &&
4379 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { 4429 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) {
4380 member.name_pos = TokenPos(); 4430 member.name_pos = TokenPos();
4381 member.name = CurrentLiteral(); // Unqualified identifier. 4431 member.name = CurrentLiteral(); // Unqualified identifier.
4382 ConsumeToken(); 4432 ConsumeToken();
4383 if (member.has_factory) { 4433 if (member.has_factory) {
4384 // The factory name may be qualified, but the first identifier must match 4434 // The factory name may be qualified, but the first identifier must match
(...skipping 30 matching lines...) Expand all
4415 if (CurrentToken() == Token::kPERIOD) { 4465 if (CurrentToken() == Token::kPERIOD) {
4416 // Named constructor. 4466 // Named constructor.
4417 ConsumeToken(); 4467 ConsumeToken();
4418 member.dict_name = ExpectIdentifier("identifier expected"); 4468 member.dict_name = ExpectIdentifier("identifier expected");
4419 to_concat.Add(*member.dict_name); 4469 to_concat.Add(*member.dict_name);
4420 } 4470 }
4421 *member.name = Symbols::FromConcatAll(T, to_concat); 4471 *member.name = Symbols::FromConcatAll(T, to_concat);
4422 CheckToken(Token::kLPAREN); 4472 CheckToken(Token::kLPAREN);
4423 } else if ((CurrentToken() == Token::kGET) && !member.has_var && 4473 } else if ((CurrentToken() == Token::kGET) && !member.has_var &&
4424 (LookaheadToken(1) != Token::kLPAREN) && 4474 (LookaheadToken(1) != Token::kLPAREN) &&
4475 (LookaheadToken(1) != Token::kLT) &&
4425 (LookaheadToken(1) != Token::kASSIGN) && 4476 (LookaheadToken(1) != Token::kASSIGN) &&
4426 (LookaheadToken(1) != Token::kCOMMA) && 4477 (LookaheadToken(1) != Token::kCOMMA) &&
4427 (LookaheadToken(1) != Token::kSEMICOLON)) { 4478 (LookaheadToken(1) != Token::kSEMICOLON)) {
4428 ConsumeToken(); 4479 ConsumeToken();
4429 member.kind = RawFunction::kGetterFunction; 4480 member.kind = RawFunction::kGetterFunction;
4430 member.name_pos = this->TokenPos(); 4481 member.name_pos = this->TokenPos();
4431 member.name = ExpectIdentifier("identifier expected"); 4482 member.name = ExpectIdentifier("identifier expected");
4432 // If the result type was not specified, it will be set to DynamicType. 4483 // If the result type was not specified, it will be set to DynamicType.
4433 } else if ((CurrentToken() == Token::kSET) && !member.has_var && 4484 } else if ((CurrentToken() == Token::kSET) && !member.has_var &&
4434 (LookaheadToken(1) != Token::kLPAREN) && 4485 (LookaheadToken(1) != Token::kLPAREN) &&
4486 (LookaheadToken(1) != Token::kLT) &&
4435 (LookaheadToken(1) != Token::kASSIGN) && 4487 (LookaheadToken(1) != Token::kASSIGN) &&
4436 (LookaheadToken(1) != Token::kCOMMA) && 4488 (LookaheadToken(1) != Token::kCOMMA) &&
4437 (LookaheadToken(1) != Token::kSEMICOLON)) { 4489 (LookaheadToken(1) != Token::kSEMICOLON)) {
4438 ConsumeToken(); 4490 ConsumeToken();
4439 member.kind = RawFunction::kSetterFunction; 4491 member.kind = RawFunction::kSetterFunction;
4440 member.name_pos = this->TokenPos(); 4492 member.name_pos = this->TokenPos();
4441 member.name = ExpectIdentifier("identifier expected"); 4493 member.name = ExpectIdentifier("identifier expected");
4442 CheckToken(Token::kLPAREN); 4494 CheckToken(Token::kLPAREN);
4443 // The grammar allows a return type, so member.type is not always NULL here. 4495 // The grammar allows a return type, so member.type is not always NULL here.
4444 // If no return type is specified, the return type of the setter is dynamic. 4496 // If no return type is specified, the return type of the setter is dynamic.
4445 if (member.type == NULL) { 4497 if (member.type == NULL) {
4446 member.type = &Object::dynamic_type(); 4498 member.type = &Object::dynamic_type();
4447 } 4499 }
4448 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && 4500 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var &&
4449 (LookaheadToken(1) != Token::kLPAREN) && 4501 (LookaheadToken(1) != Token::kLPAREN) &&
4450 (LookaheadToken(1) != Token::kASSIGN) && 4502 (LookaheadToken(1) != Token::kASSIGN) &&
4451 (LookaheadToken(1) != Token::kCOMMA) && 4503 (LookaheadToken(1) != Token::kCOMMA) &&
4452 (LookaheadToken(1) != Token::kSEMICOLON)) { 4504 (LookaheadToken(1) != Token::kSEMICOLON)) {
4505 // TODO(hausner): handle the case of a generic function named 'operator':
4506 // eg: T operator<T>(a, b) => ...
4453 ConsumeToken(); 4507 ConsumeToken();
4454 if (!Token::CanBeOverloaded(CurrentToken())) { 4508 if (!Token::CanBeOverloaded(CurrentToken())) {
4455 ReportError("invalid operator overloading"); 4509 ReportError("invalid operator overloading");
4456 } 4510 }
4457 if (member.has_static) { 4511 if (member.has_static) {
4458 ReportError("operator overloading functions cannot be static"); 4512 ReportError("operator overloading functions cannot be static");
4459 } 4513 }
4460 member.operator_token = CurrentToken(); 4514 member.operator_token = CurrentToken();
4461 member.has_operator = true; 4515 member.has_operator = true;
4462 member.kind = RawFunction::kRegularFunction; 4516 member.kind = RawFunction::kRegularFunction;
4463 member.name_pos = this->TokenPos(); 4517 member.name_pos = this->TokenPos();
4464 member.name = &String::ZoneHandle(Z, 4518 member.name = &String::ZoneHandle(Z,
4465 Symbols::Token(member.operator_token).raw()); 4519 Symbols::Token(member.operator_token).raw());
4466 ConsumeToken(); 4520 ConsumeToken();
4467 } else if (IsIdentifier()) { 4521 } else if (IsIdentifier()) {
4468 member.name = CurrentLiteral(); 4522 member.name = CurrentLiteral();
4469 member.name_pos = TokenPos(); 4523 member.name_pos = TokenPos();
4470 ConsumeToken(); 4524 ConsumeToken();
4471 } else { 4525 } else {
4472 ReportError("identifier expected"); 4526 ReportError("identifier expected");
4473 } 4527 }
4474 4528
4475 ASSERT(member.name != NULL); 4529 ASSERT(member.name != NULL);
4476 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { 4530 if (IsParameterPart() || member.IsGetter()) {
4477 // Constructor or method. 4531 // Constructor or method.
4478 if (member.type == NULL) { 4532 if (member.type == NULL) {
4479 member.type = &Object::dynamic_type(); 4533 member.type = &Object::dynamic_type();
4480 } 4534 }
4481 ASSERT(member.IsFactory() == member.has_factory); 4535 ASSERT(member.IsFactory() == member.has_factory);
4482 ParseMethodOrConstructor(members, &member); 4536 ParseMethodOrConstructor(members, &member);
4483 } else if (CurrentToken() == Token::kSEMICOLON || 4537 } else if (CurrentToken() == Token::kSEMICOLON ||
4484 CurrentToken() == Token::kCOMMA || 4538 CurrentToken() == Token::kCOMMA ||
4485 CurrentToken() == Token::kASSIGN) { 4539 CurrentToken() == Token::kASSIGN) {
4486 // Field definition. 4540 // Field definition.
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
5121 5175
5122 5176
5123 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". 5177 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(".
5124 // We need this lookahead to distinguish between the optional return type 5178 // We need this lookahead to distinguish between the optional return type
5125 // and the alias name of a function type alias. 5179 // and the alias name of a function type alias.
5126 // Token position remains unchanged. 5180 // Token position remains unchanged.
5127 bool Parser::IsFunctionTypeAliasName() { 5181 bool Parser::IsFunctionTypeAliasName() {
5128 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { 5182 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
5129 return true; 5183 return true;
5130 } 5184 }
5131 const TokenPosition saved_pos = TokenPos(); 5185 const TokenPosScope saved_pos(this);
5132 bool is_alias_name = false;
5133 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { 5186 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
5134 ConsumeToken(); 5187 ConsumeToken();
5135 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) { 5188 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) {
5136 is_alias_name = true; 5189 return true;
5137 } 5190 }
5138 } 5191 }
5139 SetPosition(saved_pos); 5192 return false;
5140 return is_alias_name;
5141 } 5193 }
5142 5194
5143 5195
5144 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". 5196 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=".
5145 // Token position remains unchanged. 5197 // Token position remains unchanged.
5146 bool Parser::IsMixinAppAlias() { 5198 bool Parser::IsMixinAppAlias() {
5147 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { 5199 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) {
5148 return true; 5200 return true;
5149 } 5201 }
5150 const TokenPosition saved_pos = TokenPos(); 5202 const TokenPosScope saved_pos(this);
5151 bool is_mixin_def = false;
5152 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { 5203 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
5153 ConsumeToken(); 5204 ConsumeToken();
5154 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { 5205 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) {
5155 is_mixin_def = true; 5206 return true;
5156 } 5207 }
5157 } 5208 }
5158 SetPosition(saved_pos); 5209 return false;
5159 return is_mixin_def;
5160 } 5210 }
5161 5211
5162 5212
5163 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, 5213 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
5164 const Object& tl_owner, 5214 const Object& tl_owner,
5165 TokenPosition metadata_pos) { 5215 TokenPosition metadata_pos) {
5166 TRACE_PARSER("ParseTypedef"); 5216 TRACE_PARSER("ParseTypedef");
5167 TokenPosition declaration_pos = 5217 TokenPosition declaration_pos =
5168 metadata_pos.IsReal() ? metadata_pos : TokenPos(); 5218 metadata_pos.IsReal() ? metadata_pos : TokenPos();
5169 ExpectToken(Token::kTYPEDEF); 5219 ExpectToken(Token::kTYPEDEF);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
5256 ASSERT(!function_type_alias.is_finalized()); 5306 ASSERT(!function_type_alias.is_finalized());
5257 pending_classes.Add(function_type_alias, Heap::kOld); 5307 pending_classes.Add(function_type_alias, Heap::kOld);
5258 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { 5308 if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
5259 library_.AddClassMetadata(function_type_alias, 5309 library_.AddClassMetadata(function_type_alias,
5260 tl_owner, 5310 tl_owner,
5261 metadata_pos); 5311 metadata_pos);
5262 } 5312 }
5263 } 5313 }
5264 5314
5265 5315
5266 // Consumes exactly one right angle bracket. If the current token is a single 5316 // Consumes exactly one right angle bracket. If the current token is
5267 // bracket token, it is consumed normally. However, if it is a double or triple 5317 // a single bracket token, it is consumed normally. However, if it is
5268 // bracket, it is replaced by a single or double bracket token without 5318 // a double bracket, it is replaced by a single bracket token without
5269 // incrementing the token index. 5319 // incrementing the token index.
5270 void Parser::ConsumeRightAngleBracket() { 5320 void Parser::ConsumeRightAngleBracket() {
5271 if (token_kind_ == Token::kGT) { 5321 if (token_kind_ == Token::kGT) {
5272 ConsumeToken(); 5322 ConsumeToken();
5273 } else if (token_kind_ == Token::kSHR) { 5323 } else if (token_kind_ == Token::kSHR) {
5274 token_kind_ = Token::kGT; 5324 token_kind_ = Token::kGT;
5275 } else { 5325 } else {
5276 UNREACHABLE(); 5326 UNREACHABLE();
5277 } 5327 }
5278 } 5328 }
5279 5329
5280 5330
5281 bool Parser::IsPatchAnnotation(TokenPosition pos) { 5331 bool Parser::IsPatchAnnotation(TokenPosition pos) {
5282 if (pos == TokenPosition::kNoSource) { 5332 if (pos == TokenPosition::kNoSource) {
5283 return false; 5333 return false;
5284 } 5334 }
5285 TokenPosition saved_pos = TokenPos(); 5335 TokenPosScope saved_pos(this);
5286 SetPosition(pos); 5336 SetPosition(pos);
5287 ExpectToken(Token::kAT); 5337 ExpectToken(Token::kAT);
5288 bool is_patch = IsSymbol(Symbols::Patch()); 5338 return IsSymbol(Symbols::Patch());
5289 SetPosition(saved_pos);
5290 return is_patch;
5291 } 5339 }
5292 5340
5293 5341
5294 TokenPosition Parser::SkipMetadata() { 5342 TokenPosition Parser::SkipMetadata() {
5295 if (CurrentToken() != Token::kAT) { 5343 if (CurrentToken() != Token::kAT) {
5296 return TokenPosition::kNoSource; 5344 return TokenPosition::kNoSource;
5297 } 5345 }
5298 TokenPosition metadata_pos = TokenPos(); 5346 TokenPosition metadata_pos = TokenPos();
5299 while (CurrentToken() == Token::kAT) { 5347 while (CurrentToken() == Token::kAT) {
5300 ConsumeToken(); 5348 ConsumeToken();
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
5638 metadata_pos = TokenPosition::kNoSource; 5686 metadata_pos = TokenPosition::kNoSource;
5639 } else if (CurrentToken() == Token::kEXTERNAL) { 5687 } else if (CurrentToken() == Token::kEXTERNAL) {
5640 ConsumeToken(); 5688 ConsumeToken();
5641 is_external = true; 5689 is_external = true;
5642 } 5690 }
5643 if (CurrentToken() == Token::kVOID) { 5691 if (CurrentToken() == Token::kVOID) {
5644 ConsumeToken(); 5692 ConsumeToken();
5645 result_type = Type::VoidType(); 5693 result_type = Type::VoidType();
5646 } else { 5694 } else {
5647 // Parse optional type. 5695 // Parse optional type.
5648 if ((CurrentToken() == Token::kIDENT) && 5696 if (IsFunctionReturnType()) {
5649 (LookaheadToken(1) != Token::kLPAREN)) {
5650 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); 5697 result_type = ParseType(ClassFinalizer::kResolveTypeParameters);
5651 } 5698 }
5652 } 5699 }
5653 const TokenPosition name_pos = TokenPos(); 5700 const TokenPosition name_pos = TokenPos();
5654 const String& func_name = *ExpectIdentifier("function name expected"); 5701 const String& func_name = *ExpectIdentifier("function name expected");
5655 5702
5656 bool found = library_.LookupLocalObject(func_name) != Object::null(); 5703 bool found = library_.LookupLocalObject(func_name) != Object::null();
5657 if (found && !is_patch) { 5704 if (found && !is_patch) {
5658 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); 5705 ReportError(name_pos, "'%s' is already defined", func_name.ToCString());
5659 } else if (!found && is_patch) { 5706 } else if (!found && is_patch) {
5660 ReportError(name_pos, "missing '%s' cannot be patched", 5707 ReportError(name_pos, "missing '%s' cannot be patched",
5661 func_name.ToCString()); 5708 func_name.ToCString());
5662 } 5709 }
5663 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); 5710 String& accessor_name = String::Handle(Z, Field::GetterName(func_name));
5664 if (library_.LookupLocalObject(accessor_name) != Object::null()) { 5711 if (library_.LookupLocalObject(accessor_name) != Object::null()) {
5665 ReportError(name_pos, "'%s' is already defined as getter", 5712 ReportError(name_pos, "'%s' is already defined as getter",
5666 func_name.ToCString()); 5713 func_name.ToCString());
5667 } 5714 }
5668 // A setter named x= may co-exist with a function named x, thus we do 5715 // A setter named x= may co-exist with a function named x, thus we do
5669 // not need to check setters. 5716 // not need to check setters.
5670 5717
5718 if (CurrentToken() == Token::kLT) {
5719 // Type parameters of generic function.
5720 // TODO(hausner): handle type parameters.
5721 if (!FLAG_generic_method_syntax) {
5722 ReportError("generic functions not supported");
5723 }
5724 TokenPosition type_arg_pos = TokenPos();
5725 if (!TryParseTypeParameters()) {
5726 ReportError(type_arg_pos, "error in type parameters");
5727 }
5728 }
5729
5671 CheckToken(Token::kLPAREN); 5730 CheckToken(Token::kLPAREN);
5672 const TokenPosition function_pos = TokenPos(); 5731 const TokenPosition function_pos = TokenPos();
5673 ParamList params; 5732 ParamList params;
5674 const bool allow_explicit_default_values = true; 5733 const bool allow_explicit_default_values = true;
5675 ParseFormalParameterList(allow_explicit_default_values, false, &params); 5734 ParseFormalParameterList(allow_explicit_default_values, false, &params);
5676 5735
5677 const TokenPosition modifier_pos = TokenPos(); 5736 const TokenPosition modifier_pos = TokenPos();
5678 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); 5737 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
5679 5738
5680 TokenPosition function_end_pos = function_pos; 5739 TokenPosition function_end_pos = function_pos;
(...skipping 2072 matching lines...) Expand 10 before | Expand all | Expand 10 after
7753 TRACE_PARSER("ParseFunctionStatement"); 7812 TRACE_PARSER("ParseFunctionStatement");
7754 AbstractType& result_type = AbstractType::Handle(Z); 7813 AbstractType& result_type = AbstractType::Handle(Z);
7755 const String* variable_name = NULL; 7814 const String* variable_name = NULL;
7756 const String* function_name = NULL; 7815 const String* function_name = NULL;
7757 7816
7758 result_type = Type::DynamicType(); 7817 result_type = Type::DynamicType();
7759 7818
7760 const TokenPosition function_pos = TokenPos(); 7819 const TokenPosition function_pos = TokenPos();
7761 TokenPosition metadata_pos = TokenPosition::kNoSource; 7820 TokenPosition metadata_pos = TokenPosition::kNoSource;
7762 if (is_literal) { 7821 if (is_literal) {
7763 ASSERT(CurrentToken() == Token::kLPAREN); 7822 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT);
7764 function_name = &Symbols::AnonymousClosure(); 7823 function_name = &Symbols::AnonymousClosure();
7765 } else { 7824 } else {
7766 metadata_pos = SkipMetadata(); 7825 metadata_pos = SkipMetadata();
7767 if (CurrentToken() == Token::kVOID) { 7826 if (CurrentToken() == Token::kVOID) {
7768 ConsumeToken(); 7827 ConsumeToken();
7769 result_type = Type::VoidType(); 7828 result_type = Type::VoidType();
7770 } else if ((CurrentToken() == Token::kIDENT) && 7829 } else if (IsFunctionReturnType()) {
7771 (LookaheadToken(1) != Token::kLPAREN)) {
7772 result_type = ParseType(ClassFinalizer::kCanonicalize); 7830 result_type = ParseType(ClassFinalizer::kCanonicalize);
7773 } 7831 }
7774 const TokenPosition name_pos = TokenPos(); 7832 const TokenPosition name_pos = TokenPos();
7775 variable_name = ExpectIdentifier("function name expected"); 7833 variable_name = ExpectIdentifier("function name expected");
7776 function_name = variable_name; 7834 function_name = variable_name;
7777 7835
7778 // Check that the function name has not been referenced 7836 // Check that the function name has not been referenced
7779 // before this declaration. 7837 // before this declaration.
7780 ASSERT(current_block_ != NULL); 7838 ASSERT(current_block_ != NULL);
7781 const TokenPosition previous_pos = 7839 const TokenPosition previous_pos =
7782 current_block_->scope->PreviousReferencePos(*function_name); 7840 current_block_->scope->PreviousReferencePos(*function_name);
7783 if (previous_pos.IsReal()) { 7841 if (previous_pos.IsReal()) {
7784 ASSERT(!script_.IsNull()); 7842 ASSERT(!script_.IsNull());
7785 intptr_t line_number; 7843 intptr_t line_number;
7786 script_.GetTokenLocation(previous_pos, &line_number, NULL); 7844 script_.GetTokenLocation(previous_pos, &line_number, NULL);
7787 ReportError(name_pos, 7845 ReportError(name_pos,
7788 "identifier '%s' previously used in line %" Pd "", 7846 "identifier '%s' previously used in line %" Pd "",
7789 function_name->ToCString(), 7847 function_name->ToCString(),
7790 line_number); 7848 line_number);
7791 } 7849 }
7792 } 7850 }
7851
7852 if (CurrentToken() == Token::kLT) {
7853 if (!FLAG_generic_method_syntax) {
7854 ReportError("generic functions not supported");
7855 }
7856 TokenPosition type_arg_pos = TokenPos();
7857 // TODO(hausner): handle type parameters of generic function.
7858 if (!TryParseTypeParameters()) {
7859 ReportError(type_arg_pos, "error in type parameters");
7860 }
7861 }
7862
7793 CheckToken(Token::kLPAREN); 7863 CheckToken(Token::kLPAREN);
7794 7864
7795 // Check whether we have parsed this closure function before, in a previous 7865 // Check whether we have parsed this closure function before, in a previous
7796 // compilation. If so, reuse the function object, else create a new one 7866 // compilation. If so, reuse the function object, else create a new one
7797 // and register it in the current class. 7867 // and register it in the current class.
7798 // Note that we cannot share the same closure function between the closurized 7868 // Note that we cannot share the same closure function between the closurized
7799 // and non-closurized versions of the same parent function. 7869 // and non-closurized versions of the same parent function.
7800 Function& function = Function::ZoneHandle(Z); 7870 Function& function = Function::ZoneHandle(Z);
7801 bool found_func = true; 7871 bool found_func = true;
7802 // TODO(hausner): There could be two different closures at the given 7872 // TODO(hausner): There could be two different closures at the given
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
7956 AstNode* initialization = new(Z) StoreLocalNode( 8026 AstNode* initialization = new(Z) StoreLocalNode(
7957 function_pos, function_variable, closure); 8027 function_pos, function_variable, closure);
7958 return initialization; 8028 return initialization;
7959 } 8029 }
7960 } 8030 }
7961 8031
7962 8032
7963 // Returns true if the current and next tokens can be parsed as type 8033 // Returns true if the current and next tokens can be parsed as type
7964 // parameters. Current token position is not saved and restored. 8034 // parameters. Current token position is not saved and restored.
7965 bool Parser::TryParseTypeParameters() { 8035 bool Parser::TryParseTypeParameters() {
7966 if (CurrentToken() == Token::kLT) { 8036 ASSERT(CurrentToken() == Token::kLT);
7967 // We are possibly looking at type parameters. Find closing ">". 8037 int nesting_level = 0;
7968 int nesting_level = 0; 8038 do {
7969 do { 8039 Token::Kind ct = CurrentToken();
7970 if (CurrentToken() == Token::kLT) { 8040 if (ct == Token::kLT) {
7971 nesting_level++; 8041 nesting_level++;
7972 } else if (CurrentToken() == Token::kGT) { 8042 } else if (ct == Token::kGT) {
7973 nesting_level--; 8043 nesting_level--;
7974 } else if (CurrentToken() == Token::kSHR) { 8044 } else if (ct == Token::kSHR) {
7975 nesting_level -= 2; 8045 nesting_level -= 2;
7976 } else if (CurrentToken() == Token::kIDENT) { 8046 } else if (ct == Token::kIDENT) {
7977 // Check to see if it is a qualified identifier. 8047 // Check to see if it is a qualified identifier.
7978 if (LookaheadToken(1) == Token::kPERIOD) { 8048 if (LookaheadToken(1) == Token::kPERIOD) {
7979 // Consume the identifier, the period will be consumed below. 8049 // Consume the identifier, the period will be consumed below.
7980 ConsumeToken(); 8050 ConsumeToken();
7981 }
7982 } else if (CurrentToken() != Token::kCOMMA &&
7983 CurrentToken() != Token::kEXTENDS) {
7984 // We are looking at something other than type parameters.
7985 return false;
7986 } 8051 }
7987 ConsumeToken(); 8052 } else if ((ct != Token::kCOMMA) &&
7988 } while (nesting_level > 0); 8053 (ct != Token::kEXTENDS) &&
7989 if (nesting_level < 0) { 8054 (!FLAG_generic_method_syntax || (ct != Token::kSUPER))) {
8055 // We are looking at something other than type parameters.
7990 return false; 8056 return false;
7991 } 8057 }
8058 ConsumeToken();
8059 } while (nesting_level > 0);
8060 if (nesting_level < 0) {
8061 return false;
7992 } 8062 }
7993 return true; 8063 return true;
7994 } 8064 }
7995 8065
7996 8066
8067 // Returns true if the next tokens can be parsed as type parameters.
8068 bool Parser::IsTypeParameters() {
8069 if (CurrentToken() == Token::kLT) {
8070 TokenPosScope param_pos(this);
8071 if (!TryParseTypeParameters()) {
8072 return false;
8073 }
8074 return true;
8075 }
8076 return false;
8077 }
8078
8079
8080 // Returns true if the next tokens are [ typeParameters ] '('.
8081 bool Parser::IsParameterPart() {
8082 if (CurrentToken() == Token::kLPAREN) {
8083 return true;
8084 }
8085 if (CurrentToken() == Token::kLT) {
8086 TokenPosScope type_arg_pos(this);
8087 if (!TryParseTypeParameters()) {
8088 return false;
8089 }
8090 return CurrentToken() == Token::kLPAREN;
8091 }
8092 return false;
8093 }
8094
8095
8096 // Returns true if the current and next tokens can be parsed as type
8097 // arguments. Current token position is not saved and restored.
8098 bool Parser::TryParseTypeArguments() {
8099 ASSERT(CurrentToken() == Token::kLT);
8100 int nesting_level = 0;
8101 do {
8102 Token::Kind ct = CurrentToken();
8103 if (ct == Token::kLT) {
8104 nesting_level++;
8105 } else if (ct == Token::kGT) {
8106 nesting_level--;
8107 } else if (ct == Token::kSHR) {
8108 nesting_level -= 2;
8109 } else if (ct == Token::kIDENT) {
8110 // Check to see if it is a qualified identifier.
8111 if (LookaheadToken(1) == Token::kPERIOD) {
8112 // Consume the identifier, the period will be consumed below.
8113 ConsumeToken();
8114 }
8115 } else if (ct != Token::kCOMMA) {
8116 return false;
8117 }
8118 ConsumeToken();
8119 } while (nesting_level > 0);
8120 if (nesting_level < 0) {
8121 return false;
8122 }
8123 return true;
8124 }
8125
8126
8127 // Returns true if the next tokens are [ typeArguments ] '('.
8128 bool Parser::IsArgumentPart() {
8129 if (CurrentToken() == Token::kLPAREN) {
8130 return true;
8131 }
8132 if (CurrentToken() == Token::kLT) {
8133 TokenPosScope type_arg_pos(this);
8134 if (!TryParseTypeArguments()) {
8135 return false;
8136 }
8137 return CurrentToken() == Token::kLPAREN;
8138 }
8139 return false;
8140 }
8141
8142
7997 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) { 8143 bool Parser::IsSimpleLiteral(const AbstractType& type, Instance* value) {
7998 // Assigning null never causes a type error. 8144 // Assigning null never causes a type error.
7999 if (CurrentToken() == Token::kNULL) { 8145 if (CurrentToken() == Token::kNULL) {
8000 *value = Instance::null(); 8146 *value = Instance::null();
8001 return true; 8147 return true;
8002 } 8148 }
8003 // If the type of the const field is guaranteed to be instantiated once 8149 // If the type of the const field is guaranteed to be instantiated once
8004 // resolved at class finalization time, and if the type of the literal is one 8150 // resolved at class finalization time, and if the type of the literal is one
8005 // of int, double, String, or bool, then preset the field with the value and 8151 // of int, double, String, or bool, then preset the field with the value and
8006 // perform the type check (in checked mode only) at finalization time. 8152 // perform the type check (in checked mode only) at finalization time.
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
8150 (CurrentToken() == Token::kASSIGN)) { 8296 (CurrentToken() == Token::kASSIGN)) {
8151 is_var_decl = true; 8297 is_var_decl = true;
8152 } 8298 }
8153 } 8299 }
8154 } 8300 }
8155 SetPosition(saved_pos); 8301 SetPosition(saved_pos);
8156 return is_var_decl; 8302 return is_var_decl;
8157 } 8303 }
8158 8304
8159 8305
8306 // Look ahead to see if the following tokens are a return type followed
8307 // by an identifier.
8308 bool Parser::IsFunctionReturnType() {
8309 TokenPosScope decl_pos(this);
8310 if (TryParseReturnType()) {
8311 if (IsIdentifier()) {
8312 // Return type followed by function name.
8313 return true;
8314 }
8315 }
8316 return false;
8317 }
8318
8319
8160 // Look ahead to detect whether the next tokens should be parsed as 8320 // Look ahead to detect whether the next tokens should be parsed as
8161 // a function declaration. Token position remains unchanged. 8321 // a function declaration. Token position remains unchanged.
8162 bool Parser::IsFunctionDeclaration() { 8322 bool Parser::IsFunctionDeclaration() {
8163 const TokenPosition saved_pos = TokenPos();
8164 bool is_external = false; 8323 bool is_external = false;
8324 TokenPosScope decl_pos(this);
8165 SkipMetadata(); 8325 SkipMetadata();
8166 if (is_top_level_ && (CurrentToken() == Token::kEXTERNAL)) { 8326 if ((is_top_level_) && (CurrentToken() == Token::kEXTERNAL)) {
8167 // Skip over 'external' for top-level function declarations. 8327 // Skip over 'external' for top-level function declarations.
8168 is_external = true; 8328 is_external = true;
8169 ConsumeToken(); 8329 ConsumeToken();
8170 } 8330 }
8171 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { 8331 const TokenPosition type_or_name_pos = TokenPos();
8172 // Possibly a function without explicit return type. 8332 if (TryParseReturnType()) {
8173 ConsumeToken(); // Consume function identifier.
8174 } else if (TryParseReturnType()) {
8175 if (!IsIdentifier()) { 8333 if (!IsIdentifier()) {
8176 SetPosition(saved_pos); 8334 SetPosition(type_or_name_pos);
8177 return false;
8178 } 8335 }
8179 ConsumeToken(); // Consume function identifier.
8180 } else { 8336 } else {
8181 SetPosition(saved_pos); 8337 SetPosition(type_or_name_pos);
8338 }
8339 // Check for function name followed by optional type parameters.
8340 if (!IsIdentifier()) {
8182 return false; 8341 return false;
8183 } 8342 }
8343 ConsumeToken();
8344 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) {
8345 return false;
8346 }
8347
8348 // Optional type, function name and optinal type parameters are parsed.
8349 if (CurrentToken() != Token::kLPAREN) {
8350 return false;
8351 }
8352
8184 // Check parameter list and the following token. 8353 // Check parameter list and the following token.
8185 if (CurrentToken() == Token::kLPAREN) { 8354 SkipToMatchingParenthesis();
8186 SkipToMatchingParenthesis(); 8355 if ((CurrentToken() == Token::kLBRACE) ||
8187 if ((CurrentToken() == Token::kLBRACE) || 8356 (CurrentToken() == Token::kARROW) ||
8188 (CurrentToken() == Token::kARROW) || 8357 (is_top_level_ && IsSymbol(Symbols::Native())) ||
8189 (is_top_level_ && IsSymbol(Symbols::Native())) || 8358 is_external ||
8190 is_external || 8359 IsSymbol(Symbols::Async()) ||
8191 IsSymbol(Symbols::Async()) || 8360 IsSymbol(Symbols::Sync())) {
8192 IsSymbol(Symbols::Sync())) { 8361 return true;
8193 SetPosition(saved_pos);
8194 return true;
8195 }
8196 } 8362 }
8197 SetPosition(saved_pos);
8198 return false; 8363 return false;
8199 } 8364 }
8200 8365
8201 8366
8202 bool Parser::IsTopLevelAccessor() { 8367 bool Parser::IsTopLevelAccessor() {
8203 const TokenPosition saved_pos = TokenPos(); 8368 const TokenPosScope saved_pos(this);
8204 if (CurrentToken() == Token::kEXTERNAL) { 8369 if (CurrentToken() == Token::kEXTERNAL) {
8205 ConsumeToken(); 8370 ConsumeToken();
8206 } 8371 }
8207 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { 8372 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
8208 SetPosition(saved_pos);
8209 return true; 8373 return true;
8210 } 8374 }
8211 if (TryParseReturnType()) { 8375 if (TryParseReturnType()) {
8212 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { 8376 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
8213 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. 8377 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name.
8214 SetPosition(saved_pos);
8215 return true; 8378 return true;
8216 } 8379 }
8217 } 8380 }
8218 } 8381 }
8219 SetPosition(saved_pos);
8220 return false; 8382 return false;
8221 } 8383 }
8222 8384
8223 8385
8224 bool Parser::IsFunctionLiteral() { 8386 bool Parser::IsFunctionLiteral() {
8225 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { 8387 if (!allow_function_literals_) {
8226 return false; 8388 return false;
8227 } 8389 }
8228 const TokenPosition saved_pos = TokenPos(); 8390 if ((CurrentToken() == Token::kLPAREN) || (CurrentToken() == Token::kLT)) {
8229 bool is_function_literal = false; 8391 TokenPosScope saved_pos(this);
8230 SkipToMatchingParenthesis(); 8392 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameters()) {
8231 ParseFunctionModifier(); 8393 return false;
8232 if ((CurrentToken() == Token::kLBRACE) || 8394 }
8233 (CurrentToken() == Token::kARROW)) { 8395 if (CurrentToken() != Token::kLPAREN) {
8234 is_function_literal = true; 8396 return false;
8397 }
8398 SkipToMatchingParenthesis();
8399 ParseFunctionModifier();
8400 if ((CurrentToken() == Token::kLBRACE) ||
8401 (CurrentToken() == Token::kARROW)) {
8402 return true;
8403 }
8235 } 8404 }
8236 SetPosition(saved_pos); 8405 return false;
8237 return is_function_literal;
8238 } 8406 }
8239 8407
8240 8408
8241 // Current token position is the token after the opening ( of the for 8409 // Current token position is the token after the opening ( of the for
8242 // statement. Returns true if we recognize a for ( .. in expr) 8410 // statement. Returns true if we recognize a for ( .. in expr)
8243 // statement. 8411 // statement.
8244 bool Parser::IsForInStatement() { 8412 bool Parser::IsForInStatement() {
8245 const TokenPosition saved_pos = TokenPos(); 8413 const TokenPosScope saved_pos(this);
8246 bool result = false;
8247 // Allow const modifier as well when recognizing a for-in statement 8414 // Allow const modifier as well when recognizing a for-in statement
8248 // pattern. We will get an error later if the loop variable is 8415 // pattern. We will get an error later if the loop variable is
8249 // declared with const. 8416 // declared with const.
8250 if (CurrentToken() == Token::kVAR || 8417 if (CurrentToken() == Token::kVAR ||
8251 CurrentToken() == Token::kFINAL || 8418 CurrentToken() == Token::kFINAL ||
8252 CurrentToken() == Token::kCONST) { 8419 CurrentToken() == Token::kCONST) {
8253 ConsumeToken(); 8420 ConsumeToken();
8254 } 8421 }
8255 if (IsIdentifier()) { 8422 if (IsIdentifier()) {
8256 if (LookaheadToken(1) == Token::kIN) { 8423 if (LookaheadToken(1) == Token::kIN) {
8257 result = true; 8424 return true;
8258 } else if (TryParseOptionalType()) { 8425 } else if (TryParseOptionalType()) {
8259 if (IsIdentifier()) { 8426 if (IsIdentifier()) {
8260 ConsumeToken(); 8427 ConsumeToken();
8261 } 8428 }
8262 result = (CurrentToken() == Token::kIN); 8429 return CurrentToken() == Token::kIN;
8263 } 8430 }
8264 } 8431 }
8265 SetPosition(saved_pos); 8432 return false;
8266 return result;
8267 } 8433 }
8268 8434
8269 8435
8270 static bool ContainsAbruptCompletingStatement(SequenceNode* seq); 8436 static bool ContainsAbruptCompletingStatement(SequenceNode* seq);
8271 8437
8272 static bool IsAbruptCompleting(AstNode* statement) { 8438 static bool IsAbruptCompleting(AstNode* statement) {
8273 return statement->IsReturnNode() || 8439 return statement->IsReturnNode() ||
8274 statement->IsJumpNode() || 8440 statement->IsJumpNode() ||
8275 statement->IsThrowNode() || 8441 statement->IsThrowNode() ||
8276 (statement->IsSequenceNode() && 8442 (statement->IsSequenceNode() &&
(...skipping 3379 matching lines...) Expand 10 before | Expand all | Expand 10 after
11656 left = new(Z) TypeNode(primary->token_pos(), type_parameter); 11822 left = new(Z) TypeNode(primary->token_pos(), type_parameter);
11657 } else { 11823 } else {
11658 // Super field access handled in ParseSuperFieldAccess(), 11824 // Super field access handled in ParseSuperFieldAccess(),
11659 // super calls handled in ParseSuperCall(). 11825 // super calls handled in ParseSuperCall().
11660 ASSERT(!primary_node->IsSuper()); 11826 ASSERT(!primary_node->IsSuper());
11661 left = LoadFieldIfUnresolved(left); 11827 left = LoadFieldIfUnresolved(left);
11662 } 11828 }
11663 } 11829 }
11664 const TokenPosition ident_pos = TokenPos(); 11830 const TokenPosition ident_pos = TokenPos();
11665 String* ident = ExpectIdentifier("identifier expected"); 11831 String* ident = ExpectIdentifier("identifier expected");
11666 if (CurrentToken() == Token::kLPAREN) { 11832 if (IsArgumentPart()) {
11667 // Identifier followed by a opening paren: method call. 11833 // Identifier followed by optional type arguments and opening paren:
11834 // method call.
11835 if (CurrentToken() == Token::kLT) {
11836 // Type arguments.
11837 if (!FLAG_generic_method_syntax) {
11838 ReportError("generic type arguments not supported.");
11839 }
11840 // TODO(hausner): handle type arguments.
11841 ParseTypeArguments(ClassFinalizer::kIgnore);
11842 }
11668 if (left->IsPrimaryNode() && 11843 if (left->IsPrimaryNode() &&
11669 left->AsPrimaryNode()->primary().IsClass()) { 11844 left->AsPrimaryNode()->primary().IsClass()) {
11670 // Static method call prefixed with class name. 11845 // Static method call prefixed with class name.
11671 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); 11846 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary());
11672 selector = ParseStaticCall(cls, *ident, ident_pos); 11847 selector = ParseStaticCall(cls, *ident, ident_pos);
11673 } else { 11848 } else {
11674 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); 11849 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional);
11675 } 11850 }
11676 } else { 11851 } else {
11677 // Field access. 11852 // Field access.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
11749 TypeParameter::Cast(primary_node->primary()), 11924 TypeParameter::Cast(primary_node->primary()),
11750 ClassFinalizer::kCanonicalize); 11925 ClassFinalizer::kCanonicalize);
11751 ASSERT(!type_parameter.IsMalformed()); 11926 ASSERT(!type_parameter.IsMalformed());
11752 array = new(Z) TypeNode(primary_pos, type_parameter); 11927 array = new(Z) TypeNode(primary_pos, type_parameter);
11753 } else { 11928 } else {
11754 UNREACHABLE(); // Internal parser error. 11929 UNREACHABLE(); // Internal parser error.
11755 } 11930 }
11756 } 11931 }
11757 selector = new(Z) LoadIndexedNode( 11932 selector = new(Z) LoadIndexedNode(
11758 bracket_pos, array, index, Class::ZoneHandle(Z)); 11933 bracket_pos, array, index, Class::ZoneHandle(Z));
11759 } else if (CurrentToken() == Token::kLPAREN) { 11934 } else if (IsArgumentPart()) {
11935 if (CurrentToken() == Token::kLT) {
11936 // Type arguments.
11937 if (!FLAG_generic_method_syntax) {
11938 ReportError("generic type arguments not supported.");
11939 }
11940 // TODO(hausner): handle type arguments.
11941 ParseTypeArguments(ClassFinalizer::kIgnore);
11942 }
11760 if (left->IsPrimaryNode()) { 11943 if (left->IsPrimaryNode()) {
11761 PrimaryNode* primary_node = left->AsPrimaryNode(); 11944 PrimaryNode* primary_node = left->AsPrimaryNode();
11762 const TokenPosition primary_pos = primary_node->token_pos(); 11945 const TokenPosition primary_pos = primary_node->token_pos();
11763 if (primary_node->primary().IsFunction()) { 11946 if (primary_node->primary().IsFunction()) {
11764 const Function& func = Function::Cast(primary_node->primary()); 11947 const Function& func = Function::Cast(primary_node->primary());
11765 const String& func_name = String::ZoneHandle(Z, func.name()); 11948 const String& func_name = String::ZoneHandle(Z, func.name());
11766 if (func.is_static()) { 11949 if (func.is_static()) {
11767 // Parse static function call. 11950 // Parse static function call.
11768 Class& cls = Class::Handle(Z, func.Owner()); 11951 Class& cls = Class::Handle(Z, func.Owner());
11769 selector = ParseStaticCall(cls, func_name, primary_pos); 11952 selector = ParseStaticCall(cls, func_name, primary_pos);
(...skipping 2600 matching lines...) Expand 10 before | Expand all | Expand 10 after
14370 ConsumeToken(); 14553 ConsumeToken();
14371 } else { 14554 } else {
14372 break; 14555 break;
14373 } 14556 }
14374 } 14557 }
14375 ExpectToken(Token::kRBRACE); 14558 ExpectToken(Token::kRBRACE);
14376 } 14559 }
14377 14560
14378 14561
14379 void Parser::SkipActualParameters() { 14562 void Parser::SkipActualParameters() {
14563 if (CurrentToken() == Token::kLT) {
14564 SkipTypeArguments();
14565 }
14380 ExpectToken(Token::kLPAREN); 14566 ExpectToken(Token::kLPAREN);
14381 while (CurrentToken() != Token::kRPAREN) { 14567 while (CurrentToken() != Token::kRPAREN) {
14382 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { 14568 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) {
14383 // Named actual parameter. 14569 // Named actual parameter.
14384 ConsumeToken(); 14570 ConsumeToken();
14385 ConsumeToken(); 14571 ConsumeToken();
14386 } 14572 }
14387 SkipNestedExpr(); 14573 SkipNestedExpr();
14388 if (CurrentToken() == Token::kCOMMA) { 14574 if (CurrentToken() == Token::kCOMMA) {
14389 ConsumeToken(); 14575 ConsumeToken();
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
14537 ExpectIdentifier("identifier or [ expected after .."); 14723 ExpectIdentifier("identifier or [ expected after ..");
14538 } 14724 }
14539 } else if ((current_token == Token::kPERIOD) || 14725 } else if ((current_token == Token::kPERIOD) ||
14540 (current_token == Token::kQM_PERIOD)) { 14726 (current_token == Token::kQM_PERIOD)) {
14541 ConsumeToken(); 14727 ConsumeToken();
14542 ExpectIdentifier("identifier expected"); 14728 ExpectIdentifier("identifier expected");
14543 } else if (current_token == Token::kLBRACK) { 14729 } else if (current_token == Token::kLBRACK) {
14544 ConsumeToken(); 14730 ConsumeToken();
14545 SkipNestedExpr(); 14731 SkipNestedExpr();
14546 ExpectToken(Token::kRBRACK); 14732 ExpectToken(Token::kRBRACK);
14547 } else if (current_token == Token::kLPAREN) { 14733 } else if (IsArgumentPart()) {
14548 SkipActualParameters(); 14734 SkipActualParameters();
14549 } else { 14735 } else {
14550 break; 14736 break;
14551 } 14737 }
14552 } 14738 }
14553 } 14739 }
14554 14740
14555 void Parser::SkipPostfixExpr() { 14741 void Parser::SkipPostfixExpr() {
14556 SkipPrimary(); 14742 SkipPrimary();
14557 if (CurrentToken() == Token::kHASH) { 14743 if (CurrentToken() == Token::kHASH) {
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
14741 const ArgumentListNode& function_args, 14927 const ArgumentListNode& function_args,
14742 const LocalVariable* temp_for_last_arg, 14928 const LocalVariable* temp_for_last_arg,
14743 bool is_super_invocation) { 14929 bool is_super_invocation) {
14744 UNREACHABLE(); 14930 UNREACHABLE();
14745 return NULL; 14931 return NULL;
14746 } 14932 }
14747 14933
14748 } // namespace dart 14934 } // namespace dart
14749 14935
14750 #endif // DART_PRECOMPILED_RUNTIME 14936 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | tests/language/generic_functions_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698