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

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

Issue 22916006: Move the begin token of explicit functions to the start of the function declaration. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase + hoist out func check Created 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('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 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/bigint_operations.h" 8 #include "vm/bigint_operations.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 bool has_final; 519 bool has_final;
520 bool has_const; 520 bool has_const;
521 bool has_static; 521 bool has_static;
522 bool has_var; 522 bool has_var;
523 bool has_factory; 523 bool has_factory;
524 bool has_operator; 524 bool has_operator;
525 intptr_t metadata_pos; 525 intptr_t metadata_pos;
526 Token::Kind operator_token; 526 Token::Kind operator_token;
527 const AbstractType* type; 527 const AbstractType* type;
528 intptr_t name_pos; 528 intptr_t name_pos;
529 intptr_t decl_begin_pos;
529 String* name; 530 String* name;
530 // For constructors: NULL or name of redirected to constructor. 531 // For constructors: NULL or name of redirected to constructor.
531 String* redirect_name; 532 String* redirect_name;
532 // For constructors: NULL for unnamed constructor, 533 // For constructors: NULL for unnamed constructor,
533 // identifier after classname for named constructors. 534 // identifier after classname for named constructors.
534 String* constructor_name; 535 String* constructor_name;
535 ParamList params; 536 ParamList params;
536 RawFunction::Kind kind; 537 RawFunction::Kind kind;
537 }; 538 };
538 539
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 SequenceNode* node_sequence = NULL; 758 SequenceNode* node_sequence = NULL;
758 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); 759 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null());
759 switch (func.kind()) { 760 switch (func.kind()) {
760 case RawFunction::kRegularFunction: 761 case RawFunction::kRegularFunction:
761 case RawFunction::kClosureFunction: 762 case RawFunction::kClosureFunction:
762 case RawFunction::kGetterFunction: 763 case RawFunction::kGetterFunction:
763 case RawFunction::kSetterFunction: 764 case RawFunction::kSetterFunction:
764 case RawFunction::kConstructor: 765 case RawFunction::kConstructor:
765 // The call to a redirecting factory is redirected. 766 // The call to a redirecting factory is redirected.
766 ASSERT(!func.IsRedirectingFactory()); 767 ASSERT(!func.IsRedirectingFactory());
768 if (!func.IsImplicitConstructor()) {
769 parser.SkipFunctionPreamble();
770 }
767 node_sequence = parser.ParseFunc(func, default_parameter_values); 771 node_sequence = parser.ParseFunc(func, default_parameter_values);
768 break; 772 break;
769 case RawFunction::kImplicitGetter: 773 case RawFunction::kImplicitGetter:
770 ASSERT(!func.is_static()); 774 ASSERT(!func.is_static());
771 node_sequence = parser.ParseInstanceGetter(func); 775 node_sequence = parser.ParseInstanceGetter(func);
772 break; 776 break;
773 case RawFunction::kImplicitSetter: 777 case RawFunction::kImplicitSetter:
774 ASSERT(!func.is_static()); 778 ASSERT(!func.is_static());
775 node_sequence = parser.ParseInstanceSetter(func); 779 node_sequence = parser.ParseInstanceSetter(func);
776 break; 780 break;
(...skipping 2048 matching lines...) Expand 10 before | Expand all | Expand 10 after
2825 } 2829 }
2826 } 2830 }
2827 } 2831 }
2828 } 2832 }
2829 } 2833 }
2830 2834
2831 2835
2832 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { 2836 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
2833 TRACE_PARSER("ParseMethodOrConstructor"); 2837 TRACE_PARSER("ParseMethodOrConstructor");
2834 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); 2838 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter());
2835 intptr_t method_pos = this->TokenPos();
2836 ASSERT(method->type != NULL); 2839 ASSERT(method->type != NULL);
2837 ASSERT(method->name_pos > 0); 2840 ASSERT(method->name_pos > 0);
2838 ASSERT(current_member_ == method); 2841 ASSERT(current_member_ == method);
2839 2842
2840 if (method->has_var) { 2843 if (method->has_var) {
2841 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); 2844 ErrorMsg(method->name_pos, "keyword var not allowed for methods");
2842 } 2845 }
2843 if (method->has_final) { 2846 if (method->has_final) {
2844 ErrorMsg(method->name_pos, "'final' not allowed for methods"); 2847 ErrorMsg(method->name_pos, "'final' not allowed for methods");
2845 } 2848 }
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3079 function_kind = RawFunction::kRegularFunction; 3082 function_kind = RawFunction::kRegularFunction;
3080 } 3083 }
3081 Function& func = Function::Handle( 3084 Function& func = Function::Handle(
3082 Function::New(*method->name, 3085 Function::New(*method->name,
3083 function_kind, 3086 function_kind,
3084 method->has_static, 3087 method->has_static,
3085 method->has_const, 3088 method->has_const,
3086 method->has_abstract, 3089 method->has_abstract,
3087 method->has_external, 3090 method->has_external,
3088 current_class(), 3091 current_class(),
3089 method_pos)); 3092 method->decl_begin_pos));
3090 func.set_result_type(*method->type); 3093 func.set_result_type(*method->type);
3091 func.set_end_token_pos(method_end_pos); 3094 func.set_end_token_pos(method_end_pos);
3092 if (method->metadata_pos > 0) { 3095 if (method->metadata_pos > 0) {
3093 library_.AddFunctionMetadata(func, method->metadata_pos); 3096 library_.AddFunctionMetadata(func, method->metadata_pos);
3094 } 3097 }
3095 3098
3096 // If this method is a redirecting factory, set the redirection information. 3099 // If this method is a redirecting factory, set the redirection information.
3097 if (!redirection_type.IsNull()) { 3100 if (!redirection_type.IsNull()) {
3098 ASSERT(func.IsFactory()); 3101 ASSERT(func.IsFactory());
3099 func.SetRedirectionType(redirection_type); 3102 func.SetRedirectionType(redirection_type);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3275 } 3278 }
3276 } 3279 }
3277 3280
3278 3281
3279 void Parser::ParseClassMemberDefinition(ClassDesc* members, 3282 void Parser::ParseClassMemberDefinition(ClassDesc* members,
3280 intptr_t metadata_pos) { 3283 intptr_t metadata_pos) {
3281 TRACE_PARSER("ParseClassMemberDefinition"); 3284 TRACE_PARSER("ParseClassMemberDefinition");
3282 MemberDesc member; 3285 MemberDesc member;
3283 current_member_ = &member; 3286 current_member_ = &member;
3284 member.metadata_pos = metadata_pos; 3287 member.metadata_pos = metadata_pos;
3288 member.decl_begin_pos = TokenPos();
3285 if ((CurrentToken() == Token::kEXTERNAL) && 3289 if ((CurrentToken() == Token::kEXTERNAL) &&
3286 (LookaheadToken(1) != Token::kLPAREN)) { 3290 (LookaheadToken(1) != Token::kLPAREN)) {
3287 ConsumeToken(); 3291 ConsumeToken();
3288 member.has_external = true; 3292 member.has_external = true;
3289 } 3293 }
3290 if ((CurrentToken() == Token::kSTATIC) && 3294 if ((CurrentToken() == Token::kSTATIC) &&
3291 (LookaheadToken(1) != Token::kLPAREN)) { 3295 (LookaheadToken(1) != Token::kLPAREN)) {
3292 ConsumeToken(); 3296 ConsumeToken();
3293 member.has_static = true; 3297 member.has_static = true;
3294 } 3298 }
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 } else { 4325 } else {
4322 ExpectSemicolon(); // Reports error. 4326 ExpectSemicolon(); // Reports error.
4323 } 4327 }
4324 } 4328 }
4325 } 4329 }
4326 4330
4327 4331
4328 void Parser::ParseTopLevelFunction(TopLevel* top_level, 4332 void Parser::ParseTopLevelFunction(TopLevel* top_level,
4329 intptr_t metadata_pos) { 4333 intptr_t metadata_pos) {
4330 TRACE_PARSER("ParseTopLevelFunction"); 4334 TRACE_PARSER("ParseTopLevelFunction");
4335 const intptr_t decl_begin_pos = TokenPos();
4331 AbstractType& result_type = Type::Handle(Type::DynamicType()); 4336 AbstractType& result_type = Type::Handle(Type::DynamicType());
4332 const bool is_static = true; 4337 const bool is_static = true;
4333 bool is_external = false; 4338 bool is_external = false;
4334 bool is_patch = false; 4339 bool is_patch = false;
4335 if (is_patch_source() && 4340 if (is_patch_source() &&
4336 (CurrentToken() == Token::kIDENT) && 4341 (CurrentToken() == Token::kIDENT) &&
4337 CurrentLiteral()->Equals("patch") && 4342 CurrentLiteral()->Equals("patch") &&
4338 (LookaheadToken(1) != Token::kLPAREN)) { 4343 (LookaheadToken(1) != Token::kLPAREN)) {
4339 ConsumeToken(); 4344 ConsumeToken();
4340 is_patch = true; 4345 is_patch = true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4394 ErrorMsg("function block expected"); 4399 ErrorMsg("function block expected");
4395 } 4400 }
4396 Function& func = Function::Handle( 4401 Function& func = Function::Handle(
4397 Function::New(func_name, 4402 Function::New(func_name,
4398 RawFunction::kRegularFunction, 4403 RawFunction::kRegularFunction,
4399 is_static, 4404 is_static,
4400 /* is_const = */ false, 4405 /* is_const = */ false,
4401 /* is_abstract = */ false, 4406 /* is_abstract = */ false,
4402 is_external, 4407 is_external,
4403 current_class(), 4408 current_class(),
4404 function_pos)); 4409 decl_begin_pos));
4405 func.set_result_type(result_type); 4410 func.set_result_type(result_type);
4406 func.set_end_token_pos(function_end_pos); 4411 func.set_end_token_pos(function_end_pos);
4407 AddFormalParamsToFunction(&params, func); 4412 AddFormalParamsToFunction(&params, func);
4408 top_level->functions.Add(func); 4413 top_level->functions.Add(func);
4409 if (!is_patch) { 4414 if (!is_patch) {
4410 library_.AddObject(func, func_name); 4415 library_.AddObject(func, func_name);
4411 } else { 4416 } else {
4412 library_.ReplaceObject(func, func_name); 4417 library_.ReplaceObject(func, func_name);
4413 } 4418 }
4414 if (metadata_pos >= 0) { 4419 if (metadata_pos >= 0) {
4415 library_.AddFunctionMetadata(func, metadata_pos); 4420 library_.AddFunctionMetadata(func, metadata_pos);
4416 } 4421 }
4417 } 4422 }
4418 4423
4419 4424
4420 void Parser::ParseTopLevelAccessor(TopLevel* top_level, 4425 void Parser::ParseTopLevelAccessor(TopLevel* top_level,
4421 intptr_t metadata_pos) { 4426 intptr_t metadata_pos) {
4422 TRACE_PARSER("ParseTopLevelAccessor"); 4427 TRACE_PARSER("ParseTopLevelAccessor");
4428 const intptr_t decl_begin_pos = TokenPos();
4423 const bool is_static = true; 4429 const bool is_static = true;
4424 bool is_external = false; 4430 bool is_external = false;
4425 bool is_patch = false; 4431 bool is_patch = false;
4426 AbstractType& result_type = AbstractType::Handle(); 4432 AbstractType& result_type = AbstractType::Handle();
4427 if (is_patch_source() && 4433 if (is_patch_source() &&
4428 (CurrentToken() == Token::kIDENT) && 4434 (CurrentToken() == Token::kIDENT) &&
4429 CurrentLiteral()->Equals("patch")) { 4435 CurrentLiteral()->Equals("patch")) {
4430 ConsumeToken(); 4436 ConsumeToken();
4431 is_patch = true; 4437 is_patch = true;
4432 } else if (CurrentToken() == Token::kEXTERNAL) { 4438 } else if (CurrentToken() == Token::kEXTERNAL) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
4519 } 4525 }
4520 Function& func = Function::Handle( 4526 Function& func = Function::Handle(
4521 Function::New(accessor_name, 4527 Function::New(accessor_name,
4522 is_getter? RawFunction::kGetterFunction : 4528 is_getter? RawFunction::kGetterFunction :
4523 RawFunction::kSetterFunction, 4529 RawFunction::kSetterFunction,
4524 is_static, 4530 is_static,
4525 /* is_const = */ false, 4531 /* is_const = */ false,
4526 /* is_abstract = */ false, 4532 /* is_abstract = */ false,
4527 is_external, 4533 is_external,
4528 current_class(), 4534 current_class(),
4529 accessor_pos)); 4535 decl_begin_pos));
4530 func.set_result_type(result_type); 4536 func.set_result_type(result_type);
4531 func.set_end_token_pos(accessor_end_pos); 4537 func.set_end_token_pos(accessor_end_pos);
4532 AddFormalParamsToFunction(&params, func); 4538 AddFormalParamsToFunction(&params, func);
4533 top_level->functions.Add(func); 4539 top_level->functions.Add(func);
4534 if (!is_patch) { 4540 if (!is_patch) {
4535 library_.AddObject(func, accessor_name); 4541 library_.AddObject(func, accessor_name);
4536 } else { 4542 } else {
4537 library_.ReplaceObject(func, accessor_name); 4543 library_.ReplaceObject(func, accessor_name);
4538 } 4544 }
4539 if (metadata_pos >= 0) { 4545 if (metadata_pos >= 0) {
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
5235 ASSERT(CurrentToken() == Token::kLPAREN); 5241 ASSERT(CurrentToken() == Token::kLPAREN);
5236 function_name = &Symbols::AnonymousClosure(); 5242 function_name = &Symbols::AnonymousClosure();
5237 } else { 5243 } else {
5238 if (CurrentToken() == Token::kVOID) { 5244 if (CurrentToken() == Token::kVOID) {
5239 ConsumeToken(); 5245 ConsumeToken();
5240 result_type = Type::VoidType(); 5246 result_type = Type::VoidType();
5241 } else if ((CurrentToken() == Token::kIDENT) && 5247 } else if ((CurrentToken() == Token::kIDENT) &&
5242 (LookaheadToken(1) != Token::kLPAREN)) { 5248 (LookaheadToken(1) != Token::kLPAREN)) {
5243 result_type = ParseType(ClassFinalizer::kCanonicalize); 5249 result_type = ParseType(ClassFinalizer::kCanonicalize);
5244 } 5250 }
5245 ident_pos = TokenPos();
5246 variable_name = ExpectIdentifier("function name expected"); 5251 variable_name = ExpectIdentifier("function name expected");
5247 function_name = variable_name; 5252 function_name = variable_name;
5248 } 5253 }
5249 5254
5250 if (CurrentToken() != Token::kLPAREN) { 5255 if (CurrentToken() != Token::kLPAREN) {
5251 ErrorMsg("'(' expected"); 5256 ErrorMsg("'(' expected");
5252 } 5257 }
5253 intptr_t function_pos = TokenPos(); 5258 intptr_t function_pos = TokenPos();
5254 5259
5255 // Check whether we have parsed this closure function before, in a previous 5260 // Check whether we have parsed this closure function before, in a previous
5256 // compilation. If so, reuse the function object, else create a new one 5261 // compilation. If so, reuse the function object, else create a new one
5257 // and register it in the current class. 5262 // and register it in the current class.
5258 // Note that we cannot share the same closure function between the closurized 5263 // Note that we cannot share the same closure function between the closurized
5259 // and non-closurized versions of the same parent function. 5264 // and non-closurized versions of the same parent function.
5260 Function& function = Function::ZoneHandle(); 5265 Function& function = Function::ZoneHandle();
5261 bool is_new_closure = false; 5266 bool is_new_closure = false;
5262 // TODO(hausner): There could be two different closures at the given 5267 // TODO(hausner): There could be two different closures at the given
5263 // function_pos, one enclosed in a closurized function and one enclosed in the 5268 // function_pos, one enclosed in a closurized function and one enclosed in the
5264 // non-closurized version of this same function. 5269 // non-closurized version of this same function.
5265 function = current_class().LookupClosureFunction(function_pos); 5270 function = current_class().LookupClosureFunction(function_pos);
5266 if (function.IsNull() || (function.token_pos() != function_pos) || 5271 if (function.IsNull() || (function.token_pos() != function_pos) ||
5267 (function.parent_function() != innermost_function().raw())) { 5272 (function.parent_function() != innermost_function().raw())) {
5268 is_new_closure = true; 5273 is_new_closure = true;
5269 function = Function::NewClosureFunction(*function_name, 5274 function = Function::NewClosureFunction(*function_name,
5270 innermost_function(), 5275 innermost_function(),
5271 function_pos); 5276 ident_pos);
5272 function.set_result_type(result_type); 5277 function.set_result_type(result_type);
5273 current_class().AddClosureFunction(function); 5278 current_class().AddClosureFunction(function);
5274 } 5279 }
5275 5280
5276 // The function type needs to be finalized at compile time, since the closure 5281 // The function type needs to be finalized at compile time, since the closure
5277 // may be type checked at run time when assigned to a function variable, 5282 // may be type checked at run time when assigned to a function variable,
5278 // passed as a function argument, or returned as a function result. 5283 // passed as a function argument, or returned as a function result.
5279 5284
5280 LocalVariable* function_variable = NULL; 5285 LocalVariable* function_variable = NULL;
5281 Type& function_type = Type::ZoneHandle(); 5286 Type& function_type = Type::ZoneHandle();
(...skipping 4746 matching lines...) Expand 10 before | Expand all | Expand 10 after
10028 } 10033 }
10029 if (CurrentToken() == Token::kLBRACE) { 10034 if (CurrentToken() == Token::kLBRACE) {
10030 SkipBlock(); 10035 SkipBlock();
10031 } else if (CurrentToken() == Token::kARROW) { 10036 } else if (CurrentToken() == Token::kARROW) {
10032 ConsumeToken(); 10037 ConsumeToken();
10033 SkipExpr(); 10038 SkipExpr();
10034 } 10039 }
10035 } 10040 }
10036 10041
10037 10042
10043 // Skips function/method/constructor/getter/setter preambles until the formal
10044 // parameter list. It is enough to skip the tokens, since we have already
10045 // previously parsed the function.
10046 void Parser::SkipFunctionPreamble() {
10047 while (true) {
10048 if (CurrentToken() == Token::kLPAREN ||
10049 CurrentToken() == Token::kARROW ||
10050 CurrentToken() == Token::kSEMICOLON ||
10051 CurrentToken() == Token::kLBRACE) {
10052 return;
10053 }
10054 // Case handles "native" keyword, but also return types of form
10055 // native.SomeType where native is the name of a library.
10056 if (CurrentToken() == Token::kIDENT &&
10057 LookaheadToken(1) != Token::kPERIOD) {
10058 if (CurrentLiteral()->raw() == Symbols::Native().raw()) {
10059 return;
10060 }
10061 }
10062 ConsumeToken();
10063 }
10064 }
10065
10066
10038 void Parser::SkipListLiteral() { 10067 void Parser::SkipListLiteral() {
10039 if (CurrentToken() == Token::kINDEX) { 10068 if (CurrentToken() == Token::kINDEX) {
10040 // Empty list literal. 10069 // Empty list literal.
10041 ConsumeToken(); 10070 ConsumeToken();
10042 return; 10071 return;
10043 } 10072 }
10044 ExpectToken(Token::kLBRACK); 10073 ExpectToken(Token::kLBRACK);
10045 while (CurrentToken() != Token::kRBRACK) { 10074 while (CurrentToken() != Token::kRBRACK) {
10046 SkipNestedExpr(); 10075 SkipNestedExpr();
10047 if (CurrentToken() == Token::kCOMMA) { 10076 if (CurrentToken() == Token::kCOMMA) {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
10288 void Parser::SkipQualIdent() { 10317 void Parser::SkipQualIdent() {
10289 ASSERT(IsIdentifier()); 10318 ASSERT(IsIdentifier());
10290 ConsumeToken(); 10319 ConsumeToken();
10291 if (CurrentToken() == Token::kPERIOD) { 10320 if (CurrentToken() == Token::kPERIOD) {
10292 ConsumeToken(); // Consume the kPERIOD token. 10321 ConsumeToken(); // Consume the kPERIOD token.
10293 ExpectIdentifier("identifier expected after '.'"); 10322 ExpectIdentifier("identifier expected after '.'");
10294 } 10323 }
10295 } 10324 }
10296 10325
10297 } // namespace dart 10326 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/symbols.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698