| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 param.name_pos = name_pos; | 316 param.name_pos = name_pos; |
| 317 param.name = &String::ZoneHandle(String::NewSymbol(name)); | 317 param.name = &String::ZoneHandle(String::NewSymbol(name)); |
| 318 param.is_final = true; | 318 param.is_final = true; |
| 319 param.type = type; | 319 param.type = type; |
| 320 this->parameters->Add(param); | 320 this->parameters->Add(param); |
| 321 } | 321 } |
| 322 | 322 |
| 323 void AddReceiver(intptr_t name_pos) { | 323 void AddReceiver(intptr_t name_pos) { |
| 324 ASSERT(this->parameters->length() == 0); | 324 ASSERT(this->parameters->length() == 0); |
| 325 // The receiver does not need to be type checked. | 325 // The receiver does not need to be type checked. |
| 326 AddFinalParameter(name_pos, kThisName, &Type::ZoneHandle(Type::VarType())); | 326 AddFinalParameter(name_pos, |
| 327 kThisName, |
| 328 &Type::ZoneHandle(Type::DynamicType())); |
| 327 } | 329 } |
| 328 | 330 |
| 329 void SetImplicitlyFinal() { | 331 void SetImplicitlyFinal() { |
| 330 implicitly_final = true; | 332 implicitly_final = true; |
| 331 } | 333 } |
| 332 | 334 |
| 333 int num_fixed_parameters; | 335 int num_fixed_parameters; |
| 334 int num_optional_parameters; | 336 int num_optional_parameters; |
| 335 bool has_named_optional_parameters; // Indicates use of the new syntax. | 337 bool has_named_optional_parameters; // Indicates use of the new syntax. |
| 336 bool has_field_initializer; | 338 bool has_field_initializer; |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 ParamDesc parameter; | 763 ParamDesc parameter; |
| 762 bool var_seen = false; | 764 bool var_seen = false; |
| 763 bool this_seen = false; | 765 bool this_seen = false; |
| 764 | 766 |
| 765 if (CurrentToken() == Token::kFINAL) { | 767 if (CurrentToken() == Token::kFINAL) { |
| 766 ConsumeToken(); | 768 ConsumeToken(); |
| 767 parameter.is_final = true; | 769 parameter.is_final = true; |
| 768 } else if (CurrentToken() == Token::kVAR) { | 770 } else if (CurrentToken() == Token::kVAR) { |
| 769 ConsumeToken(); | 771 ConsumeToken(); |
| 770 var_seen = true; | 772 var_seen = true; |
| 771 // The parameter type is the 'var' type. | 773 // The parameter type is the 'Dynamic' type. |
| 772 parameter.type = &Type::ZoneHandle(Type::VarType()); | 774 parameter.type = &Type::ZoneHandle(Type::DynamicType()); |
| 773 } | 775 } |
| 774 if (CurrentToken() == Token::kTHIS) { | 776 if (CurrentToken() == Token::kTHIS) { |
| 775 ConsumeToken(); | 777 ConsumeToken(); |
| 776 ExpectToken(Token::kPERIOD); | 778 ExpectToken(Token::kPERIOD); |
| 777 this_seen = true; | 779 this_seen = true; |
| 778 parameter.is_field_initializer = true; | 780 parameter.is_field_initializer = true; |
| 779 } | 781 } |
| 780 if (params->implicitly_final) { | 782 if (params->implicitly_final) { |
| 781 parameter.is_final = true; | 783 parameter.is_final = true; |
| 782 } | 784 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 798 Token::Kind follower = LookaheadToken(1); | 800 Token::Kind follower = LookaheadToken(1); |
| 799 // We have an identifier followed by a 'follower' token. | 801 // We have an identifier followed by a 'follower' token. |
| 800 // We either parse a type or assume that no type is specified. | 802 // We either parse a type or assume that no type is specified. |
| 801 if ((follower == Token::kLT) || // Parameterized type. | 803 if ((follower == Token::kLT) || // Parameterized type. |
| 802 (follower == Token::kPERIOD) || // Qualified class name of type. | 804 (follower == Token::kPERIOD) || // Qualified class name of type. |
| 803 (follower == Token::kIDENT) || // Parameter name following a type. | 805 (follower == Token::kIDENT) || // Parameter name following a type. |
| 804 (follower == Token::kTHIS)) { // Field parameter following a type. | 806 (follower == Token::kTHIS)) { // Field parameter following a type. |
| 805 parameter.type = &Type::ZoneHandle( | 807 parameter.type = &Type::ZoneHandle( |
| 806 ParseType(is_top_level_ ? kCanResolve : kMustResolve)); | 808 ParseType(is_top_level_ ? kCanResolve : kMustResolve)); |
| 807 } else { | 809 } else { |
| 808 parameter.type = &Type::ZoneHandle(Type::VarType()); | 810 parameter.type = &Type::ZoneHandle(Type::DynamicType()); |
| 809 } | 811 } |
| 810 } | 812 } |
| 811 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 813 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
| 812 ConsumeToken(); | 814 ConsumeToken(); |
| 813 ExpectToken(Token::kPERIOD); | 815 ExpectToken(Token::kPERIOD); |
| 814 this_seen = true; | 816 this_seen = true; |
| 815 parameter.is_field_initializer = true; | 817 parameter.is_field_initializer = true; |
| 816 } | 818 } |
| 817 // At this point, we must see an identifier for the parameter name. | 819 // At this point, we must see an identifier for the parameter name. |
| 818 if (CurrentToken() != Token::kIDENT) { | 820 if (CurrentToken() != Token::kIDENT) { |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1452 | 1454 |
| 1453 // Parse expressions of instance fields that have an explicit | 1455 // Parse expressions of instance fields that have an explicit |
| 1454 // initializers. | 1456 // initializers. |
| 1455 GrowableArray<FieldInitExpression> initializers; | 1457 GrowableArray<FieldInitExpression> initializers; |
| 1456 Class& cls = Class::Handle(func.owner()); | 1458 Class& cls = Class::Handle(func.owner()); |
| 1457 ParseInitializedInstanceFields(cls, &initializers); | 1459 ParseInitializedInstanceFields(cls, &initializers); |
| 1458 | 1460 |
| 1459 LocalVariable* receiver = new LocalVariable( | 1461 LocalVariable* receiver = new LocalVariable( |
| 1460 ctor_pos, | 1462 ctor_pos, |
| 1461 String::ZoneHandle(String::NewSymbol(kThisName)), | 1463 String::ZoneHandle(String::NewSymbol(kThisName)), |
| 1462 Type::ZoneHandle(Type::VarType())); | 1464 Type::ZoneHandle(Type::DynamicType())); |
| 1463 current_block_->scope->AddVariable(receiver); | 1465 current_block_->scope->AddVariable(receiver); |
| 1464 | 1466 |
| 1465 // Now that the "this" parameter is in scope, we can generate the code | 1467 // Now that the "this" parameter is in scope, we can generate the code |
| 1466 // to strore the initializer expressions in the respective instance fields. | 1468 // to strore the initializer expressions in the respective instance fields. |
| 1467 for (int i = 0; i < initializers.length(); i++) { | 1469 for (int i = 0; i < initializers.length(); i++) { |
| 1468 const Field* field = initializers[i].inst_field; | 1470 const Field* field = initializers[i].inst_field; |
| 1469 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); | 1471 AstNode* instance = new LoadLocalNode(field->token_index(), *receiver); |
| 1470 AstNode* field_init = | 1472 AstNode* field_init = |
| 1471 new StoreInstanceFieldNode(field->token_index(), | 1473 new StoreInstanceFieldNode(field->token_index(), |
| 1472 instance, | 1474 instance, |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2054 } | 2056 } |
| 2055 if (CurrentToken() == Token::kVAR) { | 2057 if (CurrentToken() == Token::kVAR) { |
| 2056 if (member.has_const) { | 2058 if (member.has_const) { |
| 2057 ErrorMsg("identifier expected after 'const'"); | 2059 ErrorMsg("identifier expected after 'const'"); |
| 2058 } | 2060 } |
| 2059 if (member.has_final) { | 2061 if (member.has_final) { |
| 2060 ErrorMsg("identifier expected after 'final'"); | 2062 ErrorMsg("identifier expected after 'final'"); |
| 2061 } | 2063 } |
| 2062 ConsumeToken(); | 2064 ConsumeToken(); |
| 2063 member.has_var = true; | 2065 member.has_var = true; |
| 2064 // The member type is the 'var' type. | 2066 // The member type is the 'Dynamic' type. |
| 2065 member.type = &Type::ZoneHandle(Type::VarType()); | 2067 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2066 } else if (CurrentToken() == Token::kFACTORY) { | 2068 } else if (CurrentToken() == Token::kFACTORY) { |
| 2067 ConsumeToken(); | 2069 ConsumeToken(); |
| 2068 member.has_factory = true; | 2070 member.has_factory = true; |
| 2069 member.has_static = true; | 2071 member.has_static = true; |
| 2070 // The member result type is the type of this class. | 2072 // The member result type is the type of this class. |
| 2071 // TODO(regis): What are the type arguments? | 2073 // TODO(regis): What are the type arguments? |
| 2072 member.type = | 2074 member.type = |
| 2073 &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz()))); | 2075 &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz()))); |
| 2074 } | 2076 } |
| 2075 // Optionally parse a type. | 2077 // Optionally parse a type. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2149 member.name = ExpectIdentifier("identifier expected"); | 2151 member.name = ExpectIdentifier("identifier expected"); |
| 2150 // If the result type was not specified, it will be set to VarType below. | 2152 // If the result type was not specified, it will be set to VarType below. |
| 2151 } else if (CurrentToken() == Token::kSET) { | 2153 } else if (CurrentToken() == Token::kSET) { |
| 2152 ConsumeToken(); | 2154 ConsumeToken(); |
| 2153 member.kind = RawFunction::kSetterFunction; | 2155 member.kind = RawFunction::kSetterFunction; |
| 2154 member.name_pos = this->token_index_; | 2156 member.name_pos = this->token_index_; |
| 2155 member.name = ExpectIdentifier("identifier expected"); | 2157 member.name = ExpectIdentifier("identifier expected"); |
| 2156 // The grammar allows a return type, so member.type is not always NULL here. | 2158 // The grammar allows a return type, so member.type is not always NULL here. |
| 2157 // If no return type is specified, the return type of the setter is Dynamic. | 2159 // If no return type is specified, the return type of the setter is Dynamic. |
| 2158 if (member.type == NULL) { | 2160 if (member.type == NULL) { |
| 2159 member.type = &Type::ZoneHandle(Type::VarType()); | 2161 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2160 } | 2162 } |
| 2161 } else if (CurrentToken() == Token::kOPERATOR) { | 2163 } else if (CurrentToken() == Token::kOPERATOR) { |
| 2162 ConsumeToken(); | 2164 ConsumeToken(); |
| 2163 if (!Token::CanBeOverloaded(CurrentToken())) { | 2165 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 2164 ErrorMsg("invalid operator overloading"); | 2166 ErrorMsg("invalid operator overloading"); |
| 2165 } | 2167 } |
| 2166 if (member.has_static) { | 2168 if (member.has_static) { |
| 2167 ErrorMsg("operator overloading functions cannot be static"); | 2169 ErrorMsg("operator overloading functions cannot be static"); |
| 2168 } | 2170 } |
| 2169 member.kind = RawFunction::kFunction; | 2171 member.kind = RawFunction::kFunction; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2183 if (CurrentToken() == Token::kLPAREN) { | 2185 if (CurrentToken() == Token::kLPAREN) { |
| 2184 if (members->is_interface() && member.has_static) { | 2186 if (members->is_interface() && member.has_static) { |
| 2185 if (member.has_factory) { | 2187 if (member.has_factory) { |
| 2186 ErrorMsg("factory constructors are not allowed in interfaces"); | 2188 ErrorMsg("factory constructors are not allowed in interfaces"); |
| 2187 } else { | 2189 } else { |
| 2188 ErrorMsg("static methods are not allowed in interfaces"); | 2190 ErrorMsg("static methods are not allowed in interfaces"); |
| 2189 } | 2191 } |
| 2190 } | 2192 } |
| 2191 // Constructor or method. | 2193 // Constructor or method. |
| 2192 if (member.type == NULL) { | 2194 if (member.type == NULL) { |
| 2193 member.type = &Type::ZoneHandle(Type::VarType()); | 2195 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2194 } | 2196 } |
| 2195 ParseMethodOrConstructor(members, &member); | 2197 ParseMethodOrConstructor(members, &member); |
| 2196 } else if (CurrentToken() == Token::kSEMICOLON || | 2198 } else if (CurrentToken() == Token::kSEMICOLON || |
| 2197 CurrentToken() == Token::kCOMMA || | 2199 CurrentToken() == Token::kCOMMA || |
| 2198 CurrentToken() == Token::kASSIGN) { | 2200 CurrentToken() == Token::kASSIGN) { |
| 2199 // Field definition. | 2201 // Field definition. |
| 2200 if (member.type == NULL) { | 2202 if (member.type == NULL) { |
| 2201 if (member.has_final) { | 2203 if (member.has_final) { |
| 2202 member.type = &Type::ZoneHandle(Type::VarType()); | 2204 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2203 } else { | 2205 } else { |
| 2204 ErrorMsg("missing 'var', 'final' or type in field declaration"); | 2206 ErrorMsg("missing 'var', 'final' or type in field declaration"); |
| 2205 } | 2207 } |
| 2206 } | 2208 } |
| 2207 if (members->is_interface() && member.has_static && !member.has_final) { | 2209 if (members->is_interface() && member.has_static && !member.has_final) { |
| 2208 ErrorMsg("static non-final fields are not allowed in interfaces"); | 2210 ErrorMsg("static non-final fields are not allowed in interfaces"); |
| 2209 } | 2211 } |
| 2210 ParseFieldDefinition(members, &member); | 2212 ParseFieldDefinition(members, &member); |
| 2211 } else { | 2213 } else { |
| 2212 UnexpectedToken(); | 2214 UnexpectedToken(); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2359 } | 2361 } |
| 2360 SetPosition(saved_pos); | 2362 SetPosition(saved_pos); |
| 2361 return is_alias_name; | 2363 return is_alias_name; |
| 2362 } | 2364 } |
| 2363 | 2365 |
| 2364 | 2366 |
| 2365 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { | 2367 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { |
| 2366 TRACE_PARSER("ParseFunctionTypeAlias"); | 2368 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 2367 ExpectToken(Token::kTYPEDEF); | 2369 ExpectToken(Token::kTYPEDEF); |
| 2368 | 2370 |
| 2369 Type& result_type = Type::Handle(Type::VarType()); | 2371 Type& result_type = Type::Handle(Type::DynamicType()); |
| 2370 intptr_t result_type_pos = token_index_; | 2372 intptr_t result_type_pos = token_index_; |
| 2371 if (CurrentToken() == Token::kVOID) { | 2373 if (CurrentToken() == Token::kVOID) { |
| 2372 ConsumeToken(); | 2374 ConsumeToken(); |
| 2373 result_type = Type::VoidType(); | 2375 result_type = Type::VoidType(); |
| 2374 } else if (!IsFunctionTypeAliasName()) { | 2376 } else if (!IsFunctionTypeAliasName()) { |
| 2375 result_type = ParseType(kDoNotResolve); // No owner class yet. | 2377 result_type = ParseType(kDoNotResolve); // No owner class yet. |
| 2376 } | 2378 } |
| 2377 | 2379 |
| 2378 if (CurrentToken() != Token::kIDENT) { | 2380 if (CurrentToken() != Token::kIDENT) { |
| 2379 ErrorMsg("function alias name expected"); | 2381 ErrorMsg("function alias name expected"); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2580 if (CurrentToken() == Token::kLT) { | 2582 if (CurrentToken() == Token::kLT) { |
| 2581 GrowableArray<String*> type_parameters; | 2583 GrowableArray<String*> type_parameters; |
| 2582 GrowableArray<Type*> type_parameter_extends; | 2584 GrowableArray<Type*> type_parameter_extends; |
| 2583 do { | 2585 do { |
| 2584 ConsumeToken(); | 2586 ConsumeToken(); |
| 2585 if (CurrentToken() != Token::kIDENT) { | 2587 if (CurrentToken() != Token::kIDENT) { |
| 2586 ErrorMsg("type parameter name expected"); | 2588 ErrorMsg("type parameter name expected"); |
| 2587 } | 2589 } |
| 2588 String& type_parameter_name = *CurrentLiteral(); | 2590 String& type_parameter_name = *CurrentLiteral(); |
| 2589 ConsumeToken(); | 2591 ConsumeToken(); |
| 2590 Type& type_extends = Type::ZoneHandle(Type::VarType()); | 2592 Type& type_extends = Type::ZoneHandle(Type::DynamicType()); |
| 2591 if (CurrentToken() == Token::kEXTENDS) { | 2593 if (CurrentToken() == Token::kEXTENDS) { |
| 2592 ConsumeToken(); | 2594 ConsumeToken(); |
| 2593 type_extends = ParseType(kCanResolve); | 2595 type_extends = ParseType(kCanResolve); |
| 2594 } | 2596 } |
| 2595 type_parameters.Add(&type_parameter_name); | 2597 type_parameters.Add(&type_parameter_name); |
| 2596 type_parameter_extends.Add(&type_extends); | 2598 type_parameter_extends.Add(&type_extends); |
| 2597 } while (CurrentToken() == Token::kCOMMA); | 2599 } while (CurrentToken() == Token::kCOMMA); |
| 2598 Token::Kind token = CurrentToken(); | 2600 Token::Kind token = CurrentToken(); |
| 2599 if ((token == Token::kGT) || | 2601 if ((token == Token::kGT) || |
| 2600 (token == Token::kSAR) || | 2602 (token == Token::kSAR) || |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2717 ConsumeToken(); | 2719 ConsumeToken(); |
| 2718 break; | 2720 break; |
| 2719 } else { | 2721 } else { |
| 2720 ExpectSemicolon(); // Reports error. | 2722 ExpectSemicolon(); // Reports error. |
| 2721 } | 2723 } |
| 2722 } | 2724 } |
| 2723 } | 2725 } |
| 2724 | 2726 |
| 2725 | 2727 |
| 2726 void Parser::ParseTopLevelFunction(TopLevel* top_level) { | 2728 void Parser::ParseTopLevelFunction(TopLevel* top_level) { |
| 2727 Type& result_type = Type::Handle(Type::VarType()); | 2729 Type& result_type = Type::Handle(Type::DynamicType()); |
| 2728 const bool is_static = true; | 2730 const bool is_static = true; |
| 2729 if (CurrentToken() == Token::kVOID) { | 2731 if (CurrentToken() == Token::kVOID) { |
| 2730 ConsumeToken(); | 2732 ConsumeToken(); |
| 2731 result_type = Type::VoidType(); | 2733 result_type = Type::VoidType(); |
| 2732 } else { | 2734 } else { |
| 2733 // Parse optional type. | 2735 // Parse optional type. |
| 2734 if ((CurrentToken() == Token::kIDENT) && | 2736 if ((CurrentToken() == Token::kIDENT) && |
| 2735 (LookaheadToken(1) != Token::kLPAREN)) { | 2737 (LookaheadToken(1) != Token::kLPAREN)) { |
| 2736 result_type = ParseType(kCanResolve); | 2738 result_type = ParseType(kCanResolve); |
| 2737 } | 2739 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2772 } | 2774 } |
| 2773 | 2775 |
| 2774 | 2776 |
| 2775 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { | 2777 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { |
| 2776 const bool is_static = true; | 2778 const bool is_static = true; |
| 2777 Type& result_type = Type::Handle(); | 2779 Type& result_type = Type::Handle(); |
| 2778 bool is_getter = (CurrentToken() == Token::kGET); | 2780 bool is_getter = (CurrentToken() == Token::kGET); |
| 2779 if (CurrentToken() == Token::kGET || | 2781 if (CurrentToken() == Token::kGET || |
| 2780 CurrentToken() == Token::kSET) { | 2782 CurrentToken() == Token::kSET) { |
| 2781 ConsumeToken(); | 2783 ConsumeToken(); |
| 2782 result_type = Type::VarType(); | 2784 result_type = Type::DynamicType(); |
| 2783 } else { | 2785 } else { |
| 2784 if (CurrentToken() == Token::kVOID) { | 2786 if (CurrentToken() == Token::kVOID) { |
| 2785 ConsumeToken(); | 2787 ConsumeToken(); |
| 2786 result_type = Type::VoidType(); | 2788 result_type = Type::VoidType(); |
| 2787 } else { | 2789 } else { |
| 2788 result_type = ParseType(kCanResolve); | 2790 result_type = ParseType(kCanResolve); |
| 2789 } | 2791 } |
| 2790 is_getter = (CurrentToken() == Token::kGET); | 2792 is_getter = (CurrentToken() == Token::kGET); |
| 2791 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 2793 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
| 2792 ConsumeToken(); | 2794 ConsumeToken(); |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3257 | 3259 |
| 3258 // Parses ('var' | 'final' [type] | type). | 3260 // Parses ('var' | 'final' [type] | type). |
| 3259 // The presence of 'final' must be detected and remembered before the call. | 3261 // The presence of 'final' must be detected and remembered before the call. |
| 3260 // If type_specification is kIsOptional, and no type can be parsed, then return | 3262 // If type_specification is kIsOptional, and no type can be parsed, then return |
| 3261 // the VarType. | 3263 // the VarType. |
| 3262 // If a type is parsed, it is resolved (or not) according to type_resolution. | 3264 // If a type is parsed, it is resolved (or not) according to type_resolution. |
| 3263 RawType* Parser::ParseFinalVarOrType(TypeSpecification type_specification, | 3265 RawType* Parser::ParseFinalVarOrType(TypeSpecification type_specification, |
| 3264 TypeResolution type_resolution) { | 3266 TypeResolution type_resolution) { |
| 3265 if (CurrentToken() == Token::kVAR) { | 3267 if (CurrentToken() == Token::kVAR) { |
| 3266 ConsumeToken(); | 3268 ConsumeToken(); |
| 3267 return Type::VarType(); | 3269 return Type::DynamicType(); |
| 3268 } | 3270 } |
| 3269 if (CurrentToken() == Token::kFINAL) { | 3271 if (CurrentToken() == Token::kFINAL) { |
| 3270 ConsumeToken(); | 3272 ConsumeToken(); |
| 3271 type_specification = kIsOptional; | 3273 type_specification = kIsOptional; |
| 3272 } | 3274 } |
| 3273 if (CurrentToken() != Token::kIDENT) { | 3275 if (CurrentToken() != Token::kIDENT) { |
| 3274 if (type_specification == kIsOptional) { | 3276 if (type_specification == kIsOptional) { |
| 3275 return Type::VarType(); | 3277 return Type::DynamicType(); |
| 3276 } else { | 3278 } else { |
| 3277 ErrorMsg("identifier expected"); | 3279 ErrorMsg("identifier expected"); |
| 3278 } | 3280 } |
| 3279 } | 3281 } |
| 3280 if (type_specification == kIsOptional) { | 3282 if (type_specification == kIsOptional) { |
| 3281 Token::Kind follower = LookaheadToken(1); | 3283 Token::Kind follower = LookaheadToken(1); |
| 3282 // We have an identifier followed by a 'follower' token. | 3284 // We have an identifier followed by a 'follower' token. |
| 3283 // We either parse a type or return now. | 3285 // We either parse a type or return now. |
| 3284 if ((follower != Token::kLT) && // Parameterized type. | 3286 if ((follower != Token::kLT) && // Parameterized type. |
| 3285 (follower != Token::kPERIOD) && // Qualified class name of type. | 3287 (follower != Token::kPERIOD) && // Qualified class name of type. |
| 3286 (follower != Token::kIDENT) && // Variable name following a type. | 3288 (follower != Token::kIDENT) && // Variable name following a type. |
| 3287 (follower != Token::kTHIS)) { // Field parameter following a type. | 3289 (follower != Token::kTHIS)) { // Field parameter following a type. |
| 3288 return Type::VarType(); | 3290 return Type::DynamicType(); |
| 3289 } | 3291 } |
| 3290 } | 3292 } |
| 3291 return ParseType(type_resolution); | 3293 return ParseType(type_resolution); |
| 3292 } | 3294 } |
| 3293 | 3295 |
| 3294 | 3296 |
| 3295 // Returns ast nodes of the variable initialization, or NULL if variables | 3297 // Returns ast nodes of the variable initialization, or NULL if variables |
| 3296 // are not initialized. If several variables are declared and initialized, | 3298 // are not initialized. If several variables are declared and initialized, |
| 3297 // the individual initializers are collected in a sequence node. | 3299 // the individual initializers are collected in a sequence node. |
| 3298 AstNode* Parser::ParseVariableDeclarationList() { | 3300 AstNode* Parser::ParseVariableDeclarationList() { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3327 return initializers; | 3329 return initializers; |
| 3328 } | 3330 } |
| 3329 | 3331 |
| 3330 | 3332 |
| 3331 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 3333 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 3332 TRACE_PARSER("ParseFunctionStatement"); | 3334 TRACE_PARSER("ParseFunctionStatement"); |
| 3333 Type& result_type = Type::Handle(); | 3335 Type& result_type = Type::Handle(); |
| 3334 const String* variable_name = NULL; | 3336 const String* variable_name = NULL; |
| 3335 const String* function_name = NULL; | 3337 const String* function_name = NULL; |
| 3336 | 3338 |
| 3337 result_type = Type::VarType(); | 3339 result_type = Type::DynamicType(); |
| 3338 if (CurrentToken() == Token::kVOID) { | 3340 if (CurrentToken() == Token::kVOID) { |
| 3339 ConsumeToken(); | 3341 ConsumeToken(); |
| 3340 result_type = Type::VoidType(); | 3342 result_type = Type::VoidType(); |
| 3341 } else if ((CurrentToken() == Token::kIDENT) && | 3343 } else if ((CurrentToken() == Token::kIDENT) && |
| 3342 (LookaheadToken(1) != Token::kLPAREN)) { | 3344 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3343 result_type = ParseType(kMustResolve); | 3345 result_type = ParseType(kMustResolve); |
| 3344 } | 3346 } |
| 3345 intptr_t ident_pos = token_index_; | 3347 intptr_t ident_pos = token_index_; |
| 3346 if (CurrentToken() == Token::kIDENT) { | 3348 if (CurrentToken() == Token::kIDENT) { |
| 3347 variable_name = CurrentLiteral(); | 3349 variable_name = CurrentLiteral(); |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3877 ExpectToken(Token::kRPAREN); | 3879 ExpectToken(Token::kRPAREN); |
| 3878 } | 3880 } |
| 3879 ExpectToken(Token::kLBRACE); | 3881 ExpectToken(Token::kLBRACE); |
| 3880 OpenBlock(); | 3882 OpenBlock(); |
| 3881 current_block_->scope->AddLabel(label); | 3883 current_block_->scope->AddLabel(label); |
| 3882 | 3884 |
| 3883 // Store switch expression in temporary local variable. | 3885 // Store switch expression in temporary local variable. |
| 3884 LocalVariable* temp_variable = | 3886 LocalVariable* temp_variable = |
| 3885 new LocalVariable(expr_pos, | 3887 new LocalVariable(expr_pos, |
| 3886 String::ZoneHandle(String::NewSymbol(":switch_expr")), | 3888 String::ZoneHandle(String::NewSymbol(":switch_expr")), |
| 3887 Type::ZoneHandle(Type::VarType())); | 3889 Type::ZoneHandle(Type::DynamicType())); |
| 3888 current_block_->scope->AddVariable(temp_variable); | 3890 current_block_->scope->AddVariable(temp_variable); |
| 3889 AstNode* save_switch_expr = | 3891 AstNode* save_switch_expr = |
| 3890 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); | 3892 new StoreLocalNode(expr_pos, *temp_variable, switch_expr); |
| 3891 current_block_->statements->Add(save_switch_expr); | 3893 current_block_->statements->Add(save_switch_expr); |
| 3892 | 3894 |
| 3893 // Parse case clauses | 3895 // Parse case clauses |
| 3894 bool default_seen = false; | 3896 bool default_seen = false; |
| 3895 while (true) { | 3897 while (true) { |
| 3896 // Check for statement label | 3898 // Check for statement label |
| 3897 SourceLabel* case_label = NULL; | 3899 SourceLabel* case_label = NULL; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4009 OpenBlock(); // Implicit block around while loop. | 4011 OpenBlock(); // Implicit block around while loop. |
| 4010 | 4012 |
| 4011 // Generate implicit iterator variable and add to scope. | 4013 // Generate implicit iterator variable and add to scope. |
| 4012 const String& iterator_name = | 4014 const String& iterator_name = |
| 4013 String::ZoneHandle(String::NewSymbol(":for-in-iter")); | 4015 String::ZoneHandle(String::NewSymbol(":for-in-iter")); |
| 4014 // We could set the type of the implicit iterator variable to Iterator<T> | 4016 // We could set the type of the implicit iterator variable to Iterator<T> |
| 4015 // where T is the type of the for loop variable. However, the type error | 4017 // where T is the type of the for loop variable. However, the type error |
| 4016 // would refer to the compiler generated iterator and could confuse the user. | 4018 // would refer to the compiler generated iterator and could confuse the user. |
| 4017 // It is better to leave the iterator untyped and postpone the type error | 4019 // It is better to leave the iterator untyped and postpone the type error |
| 4018 // until the loop variable is assigned to. | 4020 // until the loop variable is assigned to. |
| 4019 const Type& iterator_type = Type::ZoneHandle(Type::VarType()); | 4021 const Type& iterator_type = Type::ZoneHandle(Type::DynamicType()); |
| 4020 LocalVariable* iterator_var = | 4022 LocalVariable* iterator_var = |
| 4021 new LocalVariable(collection_pos, iterator_name, iterator_type); | 4023 new LocalVariable(collection_pos, iterator_name, iterator_type); |
| 4022 current_block_->scope->AddVariable(iterator_var); | 4024 current_block_->scope->AddVariable(iterator_var); |
| 4023 | 4025 |
| 4024 // Generate initialization of iterator variable. | 4026 // Generate initialization of iterator variable. |
| 4025 const String& iterator_method_name = | 4027 const String& iterator_method_name = |
| 4026 String::ZoneHandle(String::NewSymbol(kGetIteratorName)); | 4028 String::ZoneHandle(String::NewSymbol(kGetIteratorName)); |
| 4027 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); | 4029 ArgumentListNode* no_args = new ArgumentListNode(collection_pos); |
| 4028 AstNode* get_iterator = new InstanceCallNode( | 4030 AstNode* get_iterator = new InstanceCallNode( |
| 4029 collection_pos, collection_expr, iterator_method_name, no_args); | 4031 collection_pos, collection_expr, iterator_method_name, no_args); |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4347 // :exception_var and :stacktrace_var get set with the exception object | 4349 // :exception_var and :stacktrace_var get set with the exception object |
| 4348 // and the stacktrace object when an exception is thrown. | 4350 // and the stacktrace object when an exception is thrown. |
| 4349 // These three implicit variables can never be captured variables. | 4351 // These three implicit variables can never be captured variables. |
| 4350 const String& context_var_name = | 4352 const String& context_var_name = |
| 4351 String::ZoneHandle(String::NewSymbol(":saved_context_var")); | 4353 String::ZoneHandle(String::NewSymbol(":saved_context_var")); |
| 4352 LocalVariable* context_var = | 4354 LocalVariable* context_var = |
| 4353 current_block_->scope->LocalLookupVariable(context_var_name); | 4355 current_block_->scope->LocalLookupVariable(context_var_name); |
| 4354 if (context_var == NULL) { | 4356 if (context_var == NULL) { |
| 4355 context_var = new LocalVariable(token_index_, | 4357 context_var = new LocalVariable(token_index_, |
| 4356 context_var_name, | 4358 context_var_name, |
| 4357 Type::ZoneHandle(Type::VarType())); | 4359 Type::ZoneHandle(Type::DynamicType())); |
| 4358 current_block_->scope->AddVariable(context_var); | 4360 current_block_->scope->AddVariable(context_var); |
| 4359 } | 4361 } |
| 4360 const String& catch_excp_var_name = | 4362 const String& catch_excp_var_name = |
| 4361 String::ZoneHandle(String::NewSymbol(":exception_var")); | 4363 String::ZoneHandle(String::NewSymbol(":exception_var")); |
| 4362 LocalVariable* catch_excp_var = | 4364 LocalVariable* catch_excp_var = |
| 4363 current_block_->scope->LocalLookupVariable(catch_excp_var_name); | 4365 current_block_->scope->LocalLookupVariable(catch_excp_var_name); |
| 4364 if (catch_excp_var == NULL) { | 4366 if (catch_excp_var == NULL) { |
| 4365 catch_excp_var = new LocalVariable(token_index_, | 4367 catch_excp_var = new LocalVariable(token_index_, |
| 4366 catch_excp_var_name, | 4368 catch_excp_var_name, |
| 4367 Type::ZoneHandle(Type::VarType())); | 4369 Type::ZoneHandle(Type::DynamicType())); |
| 4368 current_block_->scope->AddVariable(catch_excp_var); | 4370 current_block_->scope->AddVariable(catch_excp_var); |
| 4369 } | 4371 } |
| 4370 const String& catch_trace_var_name = | 4372 const String& catch_trace_var_name = |
| 4371 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); | 4373 String::ZoneHandle(String::NewSymbol(":stacktrace_var")); |
| 4372 LocalVariable* catch_trace_var = | 4374 LocalVariable* catch_trace_var = |
| 4373 current_block_->scope->LocalLookupVariable(catch_trace_var_name); | 4375 current_block_->scope->LocalLookupVariable(catch_trace_var_name); |
| 4374 if (catch_trace_var == NULL) { | 4376 if (catch_trace_var == NULL) { |
| 4375 catch_trace_var = new LocalVariable(token_index_, | 4377 catch_trace_var = new LocalVariable(token_index_, |
| 4376 catch_trace_var_name, | 4378 catch_trace_var_name, |
| 4377 Type::ZoneHandle(Type::VarType())); | 4379 Type::ZoneHandle(Type::DynamicType())); |
| 4378 current_block_->scope->AddVariable(catch_trace_var); | 4380 current_block_->scope->AddVariable(catch_trace_var); |
| 4379 } | 4381 } |
| 4380 | 4382 |
| 4381 intptr_t try_pos = token_index_; | 4383 intptr_t try_pos = token_index_; |
| 4382 ConsumeToken(); // Consume the 'try'. | 4384 ConsumeToken(); // Consume the 'try'. |
| 4383 | 4385 |
| 4384 SourceLabel* try_label = NULL; | 4386 SourceLabel* try_label = NULL; |
| 4385 if (label_name != NULL) { | 4387 if (label_name != NULL) { |
| 4386 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 4388 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
| 4387 OpenBlock(); | 4389 OpenBlock(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4465 *trace, | 4467 *trace, |
| 4466 new LoadLocalNode(catch_pos, *catch_trace_var))); | 4468 new LoadLocalNode(catch_pos, *catch_trace_var))); |
| 4467 } | 4469 } |
| 4468 | 4470 |
| 4469 ParseStatementSequence(); // Parse the catch handler code. | 4471 ParseStatementSequence(); // Parse the catch handler code. |
| 4470 current_block_->statements->Add( | 4472 current_block_->statements->Add( |
| 4471 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); | 4473 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); |
| 4472 SequenceNode* catch_handler = CloseBlock(); | 4474 SequenceNode* catch_handler = CloseBlock(); |
| 4473 ExpectToken(Token::kRBRACE); | 4475 ExpectToken(Token::kRBRACE); |
| 4474 | 4476 |
| 4475 if (!exception_param.type->IsVarType()) { // Has a type specification. | 4477 if (!exception_param.type->IsDynamicType()) { // Has a type specification. |
| 4476 // Now form an 'if type check' as an exception type exists in | 4478 // Now form an 'if type check' as an exception type exists in |
| 4477 // the catch specifier. | 4479 // the catch specifier. |
| 4478 if (!exception_param.type->IsInstantiated() && | 4480 if (!exception_param.type->IsInstantiated() && |
| 4479 (current_block_->scope->function_level() > 0)) { | 4481 (current_block_->scope->function_level() > 0)) { |
| 4480 // Make sure that the instantiator is captured. | 4482 // Make sure that the instantiator is captured. |
| 4481 CaptureReceiver(); | 4483 CaptureReceiver(); |
| 4482 } | 4484 } |
| 4483 AstNode* exception_type = new TypeNode(catch_pos, *exception_param.type); | 4485 AstNode* exception_type = new TypeNode(catch_pos, *exception_param.type); |
| 4484 AstNode* exception_var = new LoadLocalNode(catch_pos, *catch_excp_var); | 4486 AstNode* exception_var = new LoadLocalNode(catch_pos, *catch_excp_var); |
| 4485 AstNode* cond_expr = new ComparisonNode( | 4487 AstNode* cond_expr = new ComparisonNode( |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4957 | 4959 |
| 4958 | 4960 |
| 4959 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, | 4961 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_index, |
| 4960 intptr_t token_id, | 4962 intptr_t token_id, |
| 4961 const char* s) { | 4963 const char* s) { |
| 4962 char name[64]; | 4964 char name[64]; |
| 4963 OS::SNPrint(name, 64, "%s%d", s, token_id); | 4965 OS::SNPrint(name, 64, "%s%d", s, token_id); |
| 4964 LocalVariable* temp = | 4966 LocalVariable* temp = |
| 4965 new LocalVariable(token_index, | 4967 new LocalVariable(token_index, |
| 4966 String::ZoneHandle(String::NewSymbol(name)), | 4968 String::ZoneHandle(String::NewSymbol(name)), |
| 4967 Type::ZoneHandle(Type::VarType())); | 4969 Type::ZoneHandle(Type::DynamicType())); |
| 4968 temp->set_is_final(); | 4970 temp->set_is_final(); |
| 4969 current_block_->scope->AddVariable(temp); | 4971 current_block_->scope->AddVariable(temp); |
| 4970 return temp; | 4972 return temp; |
| 4971 } | 4973 } |
| 4972 | 4974 |
| 4973 | 4975 |
| 4974 // If 'node' can create side effects, store its result in a temporary variable | 4976 // If 'node' can create side effects, store its result in a temporary variable |
| 4975 // and return a LoadLocalNode instead. | 4977 // and return a LoadLocalNode instead. |
| 4976 // Side effect free nodes are LoadLocalNode and LiteralNode. | 4978 // Side effect free nodes are LoadLocalNode and LiteralNode. |
| 4977 AstNode* Parser::AsSideEffectFreeNode(AstNode* node) { | 4979 AstNode* Parser::AsSideEffectFreeNode(AstNode* node) { |
| (...skipping 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6135 // as one token of type Token::kINDEX. | 6137 // as one token of type Token::kINDEX. |
| 6136 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, | 6138 AstNode* Parser::ParseArrayLiteral(intptr_t type_pos, |
| 6137 bool is_const, | 6139 bool is_const, |
| 6138 const TypeArguments& type_arguments) { | 6140 const TypeArguments& type_arguments) { |
| 6139 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 6141 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 6140 intptr_t literal_pos = token_index_; | 6142 intptr_t literal_pos = token_index_; |
| 6141 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 6143 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| 6142 ConsumeToken(); | 6144 ConsumeToken(); |
| 6143 | 6145 |
| 6144 // If no type arguments are provided, leave them as null, which is equivalent | 6146 // If no type arguments are provided, leave them as null, which is equivalent |
| 6145 // to using Array<var>. See issue 4966724. | 6147 // to using Array<Dynamic>. See issue 4966724. |
| 6146 if (!type_arguments.IsNull()) { | 6148 if (!type_arguments.IsNull()) { |
| 6147 // For now, only check the number of type arguments. See issue 4975876. | 6149 // For now, only check the number of type arguments. See issue 4975876. |
| 6148 if (type_arguments.Length() != 1) { | 6150 if (type_arguments.Length() != 1) { |
| 6149 ASSERT(type_pos >= 0); | 6151 ASSERT(type_pos >= 0); |
| 6150 ErrorMsg(type_pos, "wrong number of type arguments for Array literal"); | 6152 ErrorMsg(type_pos, "wrong number of type arguments for Array literal"); |
| 6151 } | 6153 } |
| 6152 } | 6154 } |
| 6153 | 6155 |
| 6154 // Parse the array elements. Note: there may be an optional extra | 6156 // Parse the array elements. Note: there may be an optional extra |
| 6155 // comma after the last element. | 6157 // comma after the last element. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6249 ConsumeToken(); | 6251 ConsumeToken(); |
| 6250 | 6252 |
| 6251 String& map_class_name = String::Handle( | 6253 String& map_class_name = String::Handle( |
| 6252 String::NewSymbol(is_const ? kImmutableMapName : kMutableMapName)); | 6254 String::NewSymbol(is_const ? kImmutableMapName : kMutableMapName)); |
| 6253 const Class& map_class = Class::Handle(LookupImplClass(map_class_name)); | 6255 const Class& map_class = Class::Handle(LookupImplClass(map_class_name)); |
| 6254 ASSERT(!map_class.IsNull()); | 6256 ASSERT(!map_class.IsNull()); |
| 6255 | 6257 |
| 6256 TypeArguments& map_type_arguments = | 6258 TypeArguments& map_type_arguments = |
| 6257 TypeArguments::ZoneHandle(type_arguments.raw()); | 6259 TypeArguments::ZoneHandle(type_arguments.raw()); |
| 6258 // If no type arguments are provided, leave them as null, which is equivalent | 6260 // If no type arguments are provided, leave them as null, which is equivalent |
| 6259 // to using Map<var, var>. See issue 4966724. | 6261 // to using Map<Dynamic, Dynamic>. See issue 4966724. |
| 6260 if (!map_type_arguments.IsNull()) { | 6262 if (!map_type_arguments.IsNull()) { |
| 6261 // For now, only check the number of type arguments. See issue 4975876. | 6263 // For now, only check the number of type arguments. See issue 4975876. |
| 6262 if (map_type_arguments.Length() != 2) { | 6264 if (map_type_arguments.Length() != 2) { |
| 6263 ASSERT(type_pos >= 0); | 6265 ASSERT(type_pos >= 0); |
| 6264 ErrorMsg(type_pos, "wrong number of type arguments for Map literal"); | 6266 ErrorMsg(type_pos, "wrong number of type arguments for Map literal"); |
| 6265 } | 6267 } |
| 6266 } | 6268 } |
| 6267 | 6269 |
| 6268 // Parse the map entries. Note: there may be an optional extra | 6270 // Parse the map entries. Note: there may be an optional extra |
| 6269 // comma after the last entry. | 6271 // comma after the last entry. |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6994 } | 6996 } |
| 6995 | 6997 |
| 6996 | 6998 |
| 6997 void Parser::SkipNestedExpr() { | 6999 void Parser::SkipNestedExpr() { |
| 6998 const bool saved_mode = SetAllowFunctionLiterals(true); | 7000 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 6999 SkipExpr(); | 7001 SkipExpr(); |
| 7000 SetAllowFunctionLiterals(saved_mode); | 7002 SetAllowFunctionLiterals(saved_mode); |
| 7001 } | 7003 } |
| 7002 | 7004 |
| 7003 } // namespace dart | 7005 } // namespace dart |
| OLD | NEW |