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

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

Issue 8403005: Add support for 'Dynamic' type in the VM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/token.h » ('j') | runtime/vm/token.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 parameter.is_final = true; 783 parameter.is_final = true;
784 } 784 }
785 if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) { 785 if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) {
786 ConsumeToken(); 786 ConsumeToken();
787 // This must later be changed to a closure type if we recognize 787 // This must later be changed to a closure type if we recognize
788 // a closure/function type parameter. We check this at the end 788 // a closure/function type parameter. We check this at the end
789 // of ParseFormalParameter. 789 // of ParseFormalParameter.
790 parameter.type = &Type::ZoneHandle(Type::VoidType()); 790 parameter.type = &Type::ZoneHandle(Type::VoidType());
791 } 791 }
792 if (parameter.type == NULL) { 792 if (parameter.type == NULL) {
793 // At this point, we must see an identifier for the type or the 793 // At this point, we must see 'Dynamic' or an identifier for the type or the
794 // function parameter. 794 // function parameter.
795 if (CurrentToken() != Token::kIDENT) { 795 if ((CurrentToken() != Token::kIDENT) &&
796 (CurrentToken() != Token::kDYNAMIC)) {
796 ErrorMsg("parameter name or type expected"); 797 ErrorMsg("parameter name or type expected");
797 } 798 }
798 // We have not seen a parameter type yet, so we check if the next 799 // We have not seen a parameter type yet, so we check if the next
799 // identifier could represent a type before parsing it. 800 // token could represent a type before parsing it.
800 Token::Kind follower = LookaheadToken(1); 801 Token::Kind follower = LookaheadToken(1);
801 // We have an identifier followed by a 'follower' token. 802 // We have 'Dynamic' or an identifier followed by a 'follower' token.
802 // We either parse a type or assume that no type is specified. 803 // We either parse a type or assume that no type is specified.
803 if ((follower == Token::kLT) || // Parameterized type. 804 if ((CurrentToken() == Token::kDYNAMIC) || // Dynamic type.
805 (follower == Token::kLT) || // Parameterized type.
804 (follower == Token::kPERIOD) || // Qualified class name of type. 806 (follower == Token::kPERIOD) || // Qualified class name of type.
805 (follower == Token::kIDENT) || // Parameter name following a type. 807 (follower == Token::kIDENT) || // Parameter name following a type.
806 (follower == Token::kTHIS)) { // Field parameter following a type. 808 (follower == Token::kTHIS)) { // Field parameter following a type.
807 parameter.type = &Type::ZoneHandle( 809 parameter.type = &Type::ZoneHandle(
808 ParseType(is_top_level_ ? kCanResolve : kMustResolve)); 810 ParseType(is_top_level_ ? kCanResolve : kMustResolve));
809 } else { 811 } else {
810 parameter.type = &Type::ZoneHandle(Type::DynamicType()); 812 parameter.type = &Type::ZoneHandle(Type::DynamicType());
811 } 813 }
812 } 814 }
813 if (!this_seen && (CurrentToken() == Token::kTHIS)) { 815 if (!this_seen && (CurrentToken() == Token::kTHIS)) {
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz()))); 2077 &Type::ZoneHandle(Type::NewRawType(Class::Handle(members->clazz())));
2076 } 2078 }
2077 // Optionally parse a type. 2079 // Optionally parse a type.
2078 if (CurrentToken() == Token::kVOID) { 2080 if (CurrentToken() == Token::kVOID) {
2079 if (member.has_var || member.has_factory) { 2081 if (member.has_var || member.has_factory) {
2080 ErrorMsg("void not expected"); 2082 ErrorMsg("void not expected");
2081 } 2083 }
2082 ConsumeToken(); 2084 ConsumeToken();
2083 ASSERT(member.type == NULL); 2085 ASSERT(member.type == NULL);
2084 member.type = &Type::ZoneHandle(Type::VoidType()); 2086 member.type = &Type::ZoneHandle(Type::VoidType());
2085 } else if (CurrentToken() == Token::kIDENT) { 2087 } else if ((CurrentToken() == Token::kIDENT) ||
2088 (CurrentToken() == Token::kDYNAMIC)) {
2086 // This is either a type name or the name of a method/constructor/field. 2089 // This is either a type name or the name of a method/constructor/field.
2087 if (member.type == NULL) { 2090 if (member.type == NULL) {
2088 // We have not seen a member type yet, so we check if the next 2091 // We have not seen a member type yet, so we check if the next
2089 // identifier could represent a type before parsing it. 2092 // identifier could represent a type before parsing it.
2090 Token::Kind follower = LookaheadToken(1); 2093 Token::Kind follower = LookaheadToken(1);
2091 // We have an identifier followed by a 'follower' token. 2094 // We have 'Dynamic' or an identifier followed by a 'follower' token.
2092 // We either parse a type or assume that no type is specified. 2095 // We either parse a type or assume that no type is specified.
2093 if ((follower == Token::kLT) || // Parameterized type. 2096 if ((CurrentToken() == Token::kDYNAMIC) || // Dynamic type.
2097 (follower == Token::kLT) || // Parameterized type.
2094 (follower == Token::kGET) || // Getter following a type. 2098 (follower == Token::kGET) || // Getter following a type.
2095 (follower == Token::kSET) || // Setter following a type. 2099 (follower == Token::kSET) || // Setter following a type.
2096 (follower == Token::kOPERATOR) || // Operator following a type. 2100 (follower == Token::kOPERATOR) || // Operator following a type.
2097 (follower == Token::kIDENT) || // Member name following a type. 2101 (follower == Token::kIDENT) || // Member name following a type.
2098 ((follower == Token::kPERIOD) && // Qualified class name of type, 2102 ((follower == Token::kPERIOD) && // Qualified class name of type,
2099 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. 2103 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr.
2100 ASSERT(is_top_level_); 2104 ASSERT(is_top_level_);
2101 member.type = &Type::ZoneHandle(ParseType(kCanResolve)); 2105 member.type = &Type::ZoneHandle(ParseType(kCanResolve));
2102 } 2106 }
2103 } 2107 }
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 } 2343 }
2340 } 2344 }
2341 } 2345 }
2342 2346
2343 2347
2344 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". 2348 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(".
2345 // We need this lookahead to distinguish between the optional return type 2349 // We need this lookahead to distinguish between the optional return type
2346 // and the alias name of a function type alias. 2350 // and the alias name of a function type alias.
2347 // Token position remains unchanged. 2351 // Token position remains unchanged.
2348 bool Parser::IsFunctionTypeAliasName() { 2352 bool Parser::IsFunctionTypeAliasName() {
2353 if (CurrentToken() == Token::kDYNAMIC) {
2354 return false;
2355 }
2349 if ((CurrentToken() == Token::kIDENT) && 2356 if ((CurrentToken() == Token::kIDENT) &&
2350 (LookaheadToken(1) == Token::kLPAREN)) { 2357 (LookaheadToken(1) == Token::kLPAREN)) {
2351 return true; 2358 return true;
2352 } 2359 }
2353 const intptr_t saved_pos = token_index_; 2360 const intptr_t saved_pos = token_index_;
2354 bool is_alias_name = false; 2361 bool is_alias_name = false;
2355 if ((CurrentToken() == Token::kIDENT) && 2362 if ((CurrentToken() == Token::kIDENT) &&
2356 (LookaheadToken(1) == Token::kLT)) { 2363 (LookaheadToken(1) == Token::kLT)) {
2357 ConsumeToken(); 2364 ConsumeToken();
2358 if (IsTypeParameter() && (CurrentToken() == Token::kLPAREN)) { 2365 if (IsTypeParameter() && (CurrentToken() == Token::kLPAREN)) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 } 2584 }
2578 } 2585 }
2579 2586
2580 2587
2581 void Parser::ParseTypeParameters(const Class& cls) { 2588 void Parser::ParseTypeParameters(const Class& cls) {
2582 if (CurrentToken() == Token::kLT) { 2589 if (CurrentToken() == Token::kLT) {
2583 GrowableArray<String*> type_parameters; 2590 GrowableArray<String*> type_parameters;
2584 GrowableArray<Type*> type_parameter_extends; 2591 GrowableArray<Type*> type_parameter_extends;
2585 do { 2592 do {
2586 ConsumeToken(); 2593 ConsumeToken();
2587 if (CurrentToken() != Token::kIDENT) { 2594 if ((CurrentToken() != Token::kDYNAMIC) &&
2595 (CurrentToken() != Token::kIDENT)) {
2588 ErrorMsg("type parameter name expected"); 2596 ErrorMsg("type parameter name expected");
2589 } 2597 }
2590 String& type_parameter_name = *CurrentLiteral(); 2598 String& type_parameter_name = *CurrentLiteral();
2591 ConsumeToken(); 2599 ConsumeToken();
2592 Type& type_extends = Type::ZoneHandle(Type::DynamicType()); 2600 Type& type_extends = Type::ZoneHandle(Type::DynamicType());
2593 if (CurrentToken() == Token::kEXTENDS) { 2601 if (CurrentToken() == Token::kEXTENDS) {
2594 ConsumeToken(); 2602 ConsumeToken();
2595 type_extends = ParseType(kCanResolve); 2603 type_extends = ParseType(kCanResolve);
2596 } 2604 }
2597 type_parameters.Add(&type_parameter_name); 2605 type_parameters.Add(&type_parameter_name);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2726 2734
2727 2735
2728 void Parser::ParseTopLevelFunction(TopLevel* top_level) { 2736 void Parser::ParseTopLevelFunction(TopLevel* top_level) {
2729 Type& result_type = Type::Handle(Type::DynamicType()); 2737 Type& result_type = Type::Handle(Type::DynamicType());
2730 const bool is_static = true; 2738 const bool is_static = true;
2731 if (CurrentToken() == Token::kVOID) { 2739 if (CurrentToken() == Token::kVOID) {
2732 ConsumeToken(); 2740 ConsumeToken();
2733 result_type = Type::VoidType(); 2741 result_type = Type::VoidType();
2734 } else { 2742 } else {
2735 // Parse optional type. 2743 // Parse optional type.
2736 if ((CurrentToken() == Token::kIDENT) && 2744 if ((CurrentToken() == Token::kDYNAMIC) ||
2737 (LookaheadToken(1) != Token::kLPAREN)) { 2745 ((CurrentToken() == Token::kIDENT) &&
2746 (LookaheadToken(1) != Token::kLPAREN))) {
2738 result_type = ParseType(kCanResolve); 2747 result_type = ParseType(kCanResolve);
2739 } 2748 }
2740 } 2749 }
2741 const intptr_t name_pos = token_index_; 2750 const intptr_t name_pos = token_index_;
2742 const String& func_name = *ExpectIdentifier("function name expected"); 2751 const String& func_name = *ExpectIdentifier("function name expected");
2743 2752
2744 if (library_.LookupObject(func_name) != Object::null()) { 2753 if (library_.LookupObject(func_name) != Object::null()) {
2745 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); 2754 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString());
2746 } 2755 }
2747 2756
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
3262 RawType* Parser::ParseFinalVarOrType(TypeSpecification type_specification, 3271 RawType* Parser::ParseFinalVarOrType(TypeSpecification type_specification,
3263 TypeResolution type_resolution) { 3272 TypeResolution type_resolution) {
3264 if (CurrentToken() == Token::kVAR) { 3273 if (CurrentToken() == Token::kVAR) {
3265 ConsumeToken(); 3274 ConsumeToken();
3266 return Type::DynamicType(); 3275 return Type::DynamicType();
3267 } 3276 }
3268 if (CurrentToken() == Token::kFINAL) { 3277 if (CurrentToken() == Token::kFINAL) {
3269 ConsumeToken(); 3278 ConsumeToken();
3270 type_specification = kIsOptional; 3279 type_specification = kIsOptional;
3271 } 3280 }
3281 if (CurrentToken() == Token::kDYNAMIC) {
3282 ConsumeToken();
3283 return Type::DynamicType();
3284 }
3272 if (CurrentToken() != Token::kIDENT) { 3285 if (CurrentToken() != Token::kIDENT) {
3273 if (type_specification == kIsOptional) { 3286 if (type_specification == kIsOptional) {
3274 return Type::DynamicType(); 3287 return Type::DynamicType();
3275 } else { 3288 } else {
3276 ErrorMsg("identifier expected"); 3289 ErrorMsg("identifier expected");
3277 } 3290 }
3278 } 3291 }
3279 if (type_specification == kIsOptional) { 3292 if (type_specification == kIsOptional) {
3280 Token::Kind follower = LookaheadToken(1); 3293 Token::Kind follower = LookaheadToken(1);
3281 // We have an identifier followed by a 'follower' token. 3294 // We have an identifier followed by a 'follower' token.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3330 AstNode* Parser::ParseFunctionStatement(bool is_literal) { 3343 AstNode* Parser::ParseFunctionStatement(bool is_literal) {
3331 TRACE_PARSER("ParseFunctionStatement"); 3344 TRACE_PARSER("ParseFunctionStatement");
3332 Type& result_type = Type::Handle(); 3345 Type& result_type = Type::Handle();
3333 const String* variable_name = NULL; 3346 const String* variable_name = NULL;
3334 const String* function_name = NULL; 3347 const String* function_name = NULL;
3335 3348
3336 result_type = Type::DynamicType(); 3349 result_type = Type::DynamicType();
3337 if (CurrentToken() == Token::kVOID) { 3350 if (CurrentToken() == Token::kVOID) {
3338 ConsumeToken(); 3351 ConsumeToken();
3339 result_type = Type::VoidType(); 3352 result_type = Type::VoidType();
3340 } else if ((CurrentToken() == Token::kIDENT) && 3353 } else if ((CurrentToken() == Token::kDYNAMIC) ||
3341 (LookaheadToken(1) != Token::kLPAREN)) { 3354 ((CurrentToken() == Token::kIDENT) &&
3355 (LookaheadToken(1) != Token::kLPAREN))) {
3342 result_type = ParseType(kMustResolve); 3356 result_type = ParseType(kMustResolve);
3343 } 3357 }
3344 intptr_t ident_pos = token_index_; 3358 intptr_t ident_pos = token_index_;
3345 if (CurrentToken() == Token::kIDENT) { 3359 if (CurrentToken() == Token::kIDENT) {
3346 variable_name = CurrentLiteral(); 3360 variable_name = CurrentLiteral();
3347 function_name = variable_name; 3361 function_name = variable_name;
3348 ConsumeToken(); 3362 ConsumeToken();
3349 } else { 3363 } else {
3350 if (!is_literal) { 3364 if (!is_literal) {
3351 ErrorMsg("function name expected"); 3365 ErrorMsg("function name expected");
(...skipping 2705 matching lines...) Expand 10 before | Expand all | Expand 10 after
6057 } else { 6071 } else {
6058 ASSERT(primary->primary().IsClass()); 6072 ASSERT(primary->primary().IsClass());
6059 ErrorMsg(ident_pos, "illegal reference to class or interface '%s'", 6073 ErrorMsg(ident_pos, "illegal reference to class or interface '%s'",
6060 ident.ToCString()); 6074 ident.ToCString());
6061 } 6075 }
6062 } 6076 }
6063 return var_or_field; 6077 return var_or_field;
6064 } 6078 }
6065 6079
6066 6080
6067 // Parses type = [ident "."] ident ["<" type { "," type } ">"]. 6081 // Parses type = "Dynamic" | ([ident "."] ident ["<" type { "," type } ">"]).
6068 // Returns the class object if the type can be resolved. Otherwise, either give 6082 // Returns the class object if the type can be resolved. Otherwise, either give
6069 // an error if type resolution was required, or return the unresolved name as a 6083 // an error if type resolution was required, or return the unresolved name as a
6070 // string object. 6084 // string object.
6071 RawType* Parser::ParseType(TypeResolution type_resolution) { 6085 RawType* Parser::ParseType(TypeResolution type_resolution) {
6086 if (CurrentToken() == Token::kDYNAMIC) {
6087 ConsumeToken();
6088 return Type::DynamicType();
6089 }
6072 if (CurrentToken() != Token::kIDENT) { 6090 if (CurrentToken() != Token::kIDENT) {
6073 ErrorMsg("type name expected"); 6091 ErrorMsg("type name expected");
6074 } 6092 }
6075 QualIdent type_name; 6093 QualIdent type_name;
6076 intptr_t type_pos = token_index_; 6094 intptr_t type_pos = token_index_;
6077 ParseQualIdent(&type_name); 6095 ParseQualIdent(&type_name);
6078 if (type_name.local_scope_ident) { 6096 if (type_name.local_scope_ident) {
6079 ErrorMsg(type_pos, "Using '%s' in this context is invalid", 6097 ErrorMsg(type_pos, "Using '%s' in this context is invalid",
6080 type_name.ident->ToCString()); 6098 type_name.ident->ToCString());
6081 } 6099 }
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
6390 if (CurrentToken() != Token::kIDENT) { 6408 if (CurrentToken() != Token::kIDENT) {
6391 ErrorMsg("type name expected"); 6409 ErrorMsg("type name expected");
6392 } 6410 }
6393 6411
6394 // The grammar allows for an optional ('.' identifier)?, which is a named 6412 // The grammar allows for an optional ('.' identifier)?, which is a named
6395 // constructor. For that reason, we cannot unconditionally call 6413 // constructor. For that reason, we cannot unconditionally call
6396 // ParseType(kMustResolve) after we see an identifier, because the named 6414 // ParseType(kMustResolve) after we see an identifier, because the named
6397 // constructor would be misinterpreted as a qualified type name. 6415 // constructor would be misinterpreted as a qualified type name.
6398 // TODO(regis): Revisit once we correctly support qualified identifiers. 6416 // TODO(regis): Revisit once we correctly support qualified identifiers.
6399 // For now, we inline a customized version of ParseType(kMustResolve). 6417 // For now, we inline a customized version of ParseType(kMustResolve).
6418 // Note that the inline version of ParseType correctly refuses 'Dynamic'.
6400 Type& type = Type::Handle(); 6419 Type& type = Type::Handle();
6401 Class& type_class = Class::ZoneHandle(); 6420 Class& type_class = Class::ZoneHandle();
6402 String& type_class_name = String::Handle(); 6421 String& type_class_name = String::Handle();
6403 TypeArguments& type_arguments = TypeArguments::ZoneHandle(); 6422 TypeArguments& type_arguments = TypeArguments::ZoneHandle();
6404 String* named_constructor = NULL; 6423 String* named_constructor = NULL;
6405 intptr_t type_pos = token_index_; 6424 intptr_t type_pos = token_index_;
6406 QualIdent type_name; 6425 QualIdent type_name;
6407 ParseQualIdent(&type_name); 6426 ParseQualIdent(&type_name);
6408 if (type_name.local_scope_ident) { 6427 if (type_name.local_scope_ident) {
6409 ErrorMsg(type_pos, "Using '%s' in this context is invalid", 6428 ErrorMsg(type_pos, "Using '%s' in this context is invalid",
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
6993 } 7012 }
6994 7013
6995 7014
6996 void Parser::SkipNestedExpr() { 7015 void Parser::SkipNestedExpr() {
6997 const bool saved_mode = SetAllowFunctionLiterals(true); 7016 const bool saved_mode = SetAllowFunctionLiterals(true);
6998 SkipExpr(); 7017 SkipExpr();
6999 SetAllowFunctionLiterals(saved_mode); 7018 SetAllowFunctionLiterals(saved_mode);
7000 } 7019 }
7001 7020
7002 } // namespace dart 7021 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/token.h » ('j') | runtime/vm/token.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698