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

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

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