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

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: 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 parser.SkipFunctionPreamble(func);
767 node_sequence = parser.ParseFunc(func, default_parameter_values); 769 node_sequence = parser.ParseFunc(func, default_parameter_values);
768 break; 770 break;
769 case RawFunction::kImplicitGetter: 771 case RawFunction::kImplicitGetter:
770 ASSERT(!func.is_static()); 772 ASSERT(!func.is_static());
771 node_sequence = parser.ParseInstanceGetter(func); 773 node_sequence = parser.ParseInstanceGetter(func);
772 break; 774 break;
773 case RawFunction::kImplicitSetter: 775 case RawFunction::kImplicitSetter:
774 ASSERT(!func.is_static()); 776 ASSERT(!func.is_static());
775 node_sequence = parser.ParseInstanceSetter(func); 777 node_sequence = parser.ParseInstanceSetter(func);
776 break; 778 break;
(...skipping 2051 matching lines...) Expand 10 before | Expand all | Expand 10 after
2828 } 2830 }
2829 } 2831 }
2830 } 2832 }
2831 } 2833 }
2832 } 2834 }
2833 2835
2834 2836
2835 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { 2837 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) {
2836 TRACE_PARSER("ParseMethodOrConstructor"); 2838 TRACE_PARSER("ParseMethodOrConstructor");
2837 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); 2839 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter());
2838 intptr_t method_pos = this->TokenPos();
2839 ASSERT(method->type != NULL); 2840 ASSERT(method->type != NULL);
2840 ASSERT(method->name_pos > 0); 2841 ASSERT(method->name_pos > 0);
2841 ASSERT(current_member_ == method); 2842 ASSERT(current_member_ == method);
2842 2843
2843 if (method->has_var) { 2844 if (method->has_var) {
2844 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); 2845 ErrorMsg(method->name_pos, "keyword var not allowed for methods");
2845 } 2846 }
2846 if (method->has_final) { 2847 if (method->has_final) {
2847 ErrorMsg(method->name_pos, "'final' not allowed for methods"); 2848 ErrorMsg(method->name_pos, "'final' not allowed for methods");
2848 } 2849 }
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
3082 function_kind = RawFunction::kRegularFunction; 3083 function_kind = RawFunction::kRegularFunction;
3083 } 3084 }
3084 Function& func = Function::Handle( 3085 Function& func = Function::Handle(
3085 Function::New(*method->name, 3086 Function::New(*method->name,
3086 function_kind, 3087 function_kind,
3087 method->has_static, 3088 method->has_static,
3088 method->has_const, 3089 method->has_const,
3089 method->has_abstract, 3090 method->has_abstract,
3090 method->has_external, 3091 method->has_external,
3091 current_class(), 3092 current_class(),
3092 method_pos)); 3093 method->decl_begin_pos));
3093 func.set_result_type(*method->type); 3094 func.set_result_type(*method->type);
3094 func.set_end_token_pos(method_end_pos); 3095 func.set_end_token_pos(method_end_pos);
3095 if (method->metadata_pos > 0) { 3096 if (method->metadata_pos > 0) {
3096 library_.AddFunctionMetadata(func, method->metadata_pos); 3097 library_.AddFunctionMetadata(func, method->metadata_pos);
3097 } 3098 }
3098 3099
3099 // If this method is a redirecting factory, set the redirection information. 3100 // If this method is a redirecting factory, set the redirection information.
3100 if (!redirection_type.IsNull()) { 3101 if (!redirection_type.IsNull()) {
3101 ASSERT(func.IsFactory()); 3102 ASSERT(func.IsFactory());
3102 func.SetRedirectionType(redirection_type); 3103 func.SetRedirectionType(redirection_type);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
3278 } 3279 }
3279 } 3280 }
3280 3281
3281 3282
3282 void Parser::ParseClassMemberDefinition(ClassDesc* members, 3283 void Parser::ParseClassMemberDefinition(ClassDesc* members,
3283 intptr_t metadata_pos) { 3284 intptr_t metadata_pos) {
3284 TRACE_PARSER("ParseClassMemberDefinition"); 3285 TRACE_PARSER("ParseClassMemberDefinition");
3285 MemberDesc member; 3286 MemberDesc member;
3286 current_member_ = &member; 3287 current_member_ = &member;
3287 member.metadata_pos = metadata_pos; 3288 member.metadata_pos = metadata_pos;
3289 member.decl_begin_pos = TokenPos();
3288 if ((CurrentToken() == Token::kEXTERNAL) && 3290 if ((CurrentToken() == Token::kEXTERNAL) &&
3289 (LookaheadToken(1) != Token::kLPAREN)) { 3291 (LookaheadToken(1) != Token::kLPAREN)) {
3290 ConsumeToken(); 3292 ConsumeToken();
3291 member.has_external = true; 3293 member.has_external = true;
3292 } 3294 }
3293 if ((CurrentToken() == Token::kSTATIC) && 3295 if ((CurrentToken() == Token::kSTATIC) &&
3294 (LookaheadToken(1) != Token::kLPAREN)) { 3296 (LookaheadToken(1) != Token::kLPAREN)) {
3295 ConsumeToken(); 3297 ConsumeToken();
3296 member.has_static = true; 3298 member.has_static = true;
3297 } 3299 }
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
4330 } else { 4332 } else {
4331 ExpectSemicolon(); // Reports error. 4333 ExpectSemicolon(); // Reports error.
4332 } 4334 }
4333 } 4335 }
4334 } 4336 }
4335 4337
4336 4338
4337 void Parser::ParseTopLevelFunction(TopLevel* top_level, 4339 void Parser::ParseTopLevelFunction(TopLevel* top_level,
4338 intptr_t metadata_pos) { 4340 intptr_t metadata_pos) {
4339 TRACE_PARSER("ParseTopLevelFunction"); 4341 TRACE_PARSER("ParseTopLevelFunction");
4342 const intptr_t decl_begin_pos = TokenPos();
4340 AbstractType& result_type = Type::Handle(Type::DynamicType()); 4343 AbstractType& result_type = Type::Handle(Type::DynamicType());
4341 const bool is_static = true; 4344 const bool is_static = true;
4342 bool is_external = false; 4345 bool is_external = false;
4343 bool is_patch = false; 4346 bool is_patch = false;
4344 if (is_patch_source() && 4347 if (is_patch_source() &&
4345 (CurrentToken() == Token::kIDENT) && 4348 (CurrentToken() == Token::kIDENT) &&
4346 CurrentLiteral()->Equals("patch") && 4349 CurrentLiteral()->Equals("patch") &&
4347 (LookaheadToken(1) != Token::kLPAREN)) { 4350 (LookaheadToken(1) != Token::kLPAREN)) {
4348 ConsumeToken(); 4351 ConsumeToken();
4349 is_patch = true; 4352 is_patch = true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4403 ErrorMsg("function block expected"); 4406 ErrorMsg("function block expected");
4404 } 4407 }
4405 Function& func = Function::Handle( 4408 Function& func = Function::Handle(
4406 Function::New(func_name, 4409 Function::New(func_name,
4407 RawFunction::kRegularFunction, 4410 RawFunction::kRegularFunction,
4408 is_static, 4411 is_static,
4409 /* is_const = */ false, 4412 /* is_const = */ false,
4410 /* is_abstract = */ false, 4413 /* is_abstract = */ false,
4411 is_external, 4414 is_external,
4412 current_class(), 4415 current_class(),
4413 function_pos)); 4416 decl_begin_pos));
4414 func.set_result_type(result_type); 4417 func.set_result_type(result_type);
4415 func.set_end_token_pos(function_end_pos); 4418 func.set_end_token_pos(function_end_pos);
4416 AddFormalParamsToFunction(&params, func); 4419 AddFormalParamsToFunction(&params, func);
4417 top_level->functions.Add(func); 4420 top_level->functions.Add(func);
4418 if (!is_patch) { 4421 if (!is_patch) {
4419 library_.AddObject(func, func_name); 4422 library_.AddObject(func, func_name);
4420 } else { 4423 } else {
4421 library_.ReplaceObject(func, func_name); 4424 library_.ReplaceObject(func, func_name);
4422 } 4425 }
4423 if (metadata_pos >= 0) { 4426 if (metadata_pos >= 0) {
4424 library_.AddFunctionMetadata(func, metadata_pos); 4427 library_.AddFunctionMetadata(func, metadata_pos);
4425 } 4428 }
4426 } 4429 }
4427 4430
4428 4431
4429 void Parser::ParseTopLevelAccessor(TopLevel* top_level, 4432 void Parser::ParseTopLevelAccessor(TopLevel* top_level,
4430 intptr_t metadata_pos) { 4433 intptr_t metadata_pos) {
4431 TRACE_PARSER("ParseTopLevelAccessor"); 4434 TRACE_PARSER("ParseTopLevelAccessor");
4435 const intptr_t decl_begin_pos = TokenPos();
4432 const bool is_static = true; 4436 const bool is_static = true;
4433 bool is_external = false; 4437 bool is_external = false;
4434 bool is_patch = false; 4438 bool is_patch = false;
4435 AbstractType& result_type = AbstractType::Handle(); 4439 AbstractType& result_type = AbstractType::Handle();
4436 if (is_patch_source() && 4440 if (is_patch_source() &&
4437 (CurrentToken() == Token::kIDENT) && 4441 (CurrentToken() == Token::kIDENT) &&
4438 CurrentLiteral()->Equals("patch")) { 4442 CurrentLiteral()->Equals("patch")) {
4439 ConsumeToken(); 4443 ConsumeToken();
4440 is_patch = true; 4444 is_patch = true;
4441 } else if (CurrentToken() == Token::kEXTERNAL) { 4445 } else if (CurrentToken() == Token::kEXTERNAL) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
4528 } 4532 }
4529 Function& func = Function::Handle( 4533 Function& func = Function::Handle(
4530 Function::New(accessor_name, 4534 Function::New(accessor_name,
4531 is_getter? RawFunction::kGetterFunction : 4535 is_getter? RawFunction::kGetterFunction :
4532 RawFunction::kSetterFunction, 4536 RawFunction::kSetterFunction,
4533 is_static, 4537 is_static,
4534 /* is_const = */ false, 4538 /* is_const = */ false,
4535 /* is_abstract = */ false, 4539 /* is_abstract = */ false,
4536 is_external, 4540 is_external,
4537 current_class(), 4541 current_class(),
4538 accessor_pos)); 4542 decl_begin_pos));
4539 func.set_result_type(result_type); 4543 func.set_result_type(result_type);
4540 func.set_end_token_pos(accessor_end_pos); 4544 func.set_end_token_pos(accessor_end_pos);
4541 AddFormalParamsToFunction(&params, func); 4545 AddFormalParamsToFunction(&params, func);
4542 top_level->functions.Add(func); 4546 top_level->functions.Add(func);
4543 if (!is_patch) { 4547 if (!is_patch) {
4544 library_.AddObject(func, accessor_name); 4548 library_.AddObject(func, accessor_name);
4545 } else { 4549 } else {
4546 library_.ReplaceObject(func, accessor_name); 4550 library_.ReplaceObject(func, accessor_name);
4547 } 4551 }
4548 if (metadata_pos >= 0) { 4552 if (metadata_pos >= 0) {
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
5242 ASSERT(CurrentToken() == Token::kLPAREN); 5246 ASSERT(CurrentToken() == Token::kLPAREN);
5243 function_name = &Symbols::AnonymousClosure(); 5247 function_name = &Symbols::AnonymousClosure();
5244 } else { 5248 } else {
5245 if (CurrentToken() == Token::kVOID) { 5249 if (CurrentToken() == Token::kVOID) {
5246 ConsumeToken(); 5250 ConsumeToken();
5247 result_type = Type::VoidType(); 5251 result_type = Type::VoidType();
5248 } else if ((CurrentToken() == Token::kIDENT) && 5252 } else if ((CurrentToken() == Token::kIDENT) &&
5249 (LookaheadToken(1) != Token::kLPAREN)) { 5253 (LookaheadToken(1) != Token::kLPAREN)) {
5250 result_type = ParseType(ClassFinalizer::kCanonicalize); 5254 result_type = ParseType(ClassFinalizer::kCanonicalize);
5251 } 5255 }
5252 ident_pos = TokenPos();
5253 variable_name = ExpectIdentifier("function name expected"); 5256 variable_name = ExpectIdentifier("function name expected");
5254 function_name = variable_name; 5257 function_name = variable_name;
5255 } 5258 }
5256 5259
5257 if (CurrentToken() != Token::kLPAREN) { 5260 if (CurrentToken() != Token::kLPAREN) {
5258 ErrorMsg("'(' expected"); 5261 ErrorMsg("'(' expected");
5259 } 5262 }
5260 intptr_t function_pos = TokenPos(); 5263 intptr_t function_pos = TokenPos();
5261 5264
5262 // Check whether we have parsed this closure function before, in a previous 5265 // Check whether we have parsed this closure function before, in a previous
5263 // compilation. If so, reuse the function object, else create a new one 5266 // compilation. If so, reuse the function object, else create a new one
5264 // and register it in the current class. 5267 // and register it in the current class.
5265 // Note that we cannot share the same closure function between the closurized 5268 // Note that we cannot share the same closure function between the closurized
5266 // and non-closurized versions of the same parent function. 5269 // and non-closurized versions of the same parent function.
5267 Function& function = Function::ZoneHandle(); 5270 Function& function = Function::ZoneHandle();
5268 bool is_new_closure = false; 5271 bool is_new_closure = false;
5269 // TODO(hausner): There could be two different closures at the given 5272 // TODO(hausner): There could be two different closures at the given
5270 // function_pos, one enclosed in a closurized function and one enclosed in the 5273 // function_pos, one enclosed in a closurized function and one enclosed in the
5271 // non-closurized version of this same function. 5274 // non-closurized version of this same function.
5272 function = current_class().LookupClosureFunction(function_pos); 5275 function = current_class().LookupClosureFunction(function_pos);
5273 if (function.IsNull() || (function.token_pos() != function_pos) || 5276 if (function.IsNull() || (function.token_pos() != function_pos) ||
5274 (function.parent_function() != innermost_function().raw())) { 5277 (function.parent_function() != innermost_function().raw())) {
5275 is_new_closure = true; 5278 is_new_closure = true;
5276 function = Function::NewClosureFunction(*function_name, 5279 function = Function::NewClosureFunction(*function_name,
5277 innermost_function(), 5280 innermost_function(),
5278 function_pos); 5281 ident_pos);
5279 function.set_result_type(result_type); 5282 function.set_result_type(result_type);
5280 current_class().AddClosureFunction(function); 5283 current_class().AddClosureFunction(function);
5281 } 5284 }
5282 5285
5283 // The function type needs to be finalized at compile time, since the closure 5286 // The function type needs to be finalized at compile time, since the closure
5284 // may be type checked at run time when assigned to a function variable, 5287 // may be type checked at run time when assigned to a function variable,
5285 // passed as a function argument, or returned as a function result. 5288 // passed as a function argument, or returned as a function result.
5286 5289
5287 LocalVariable* function_variable = NULL; 5290 LocalVariable* function_variable = NULL;
5288 Type& function_type = Type::ZoneHandle(); 5291 Type& function_type = Type::ZoneHandle();
(...skipping 4745 matching lines...) Expand 10 before | Expand all | Expand 10 after
10034 } 10037 }
10035 if (CurrentToken() == Token::kLBRACE) { 10038 if (CurrentToken() == Token::kLBRACE) {
10036 SkipBlock(); 10039 SkipBlock();
10037 } else if (CurrentToken() == Token::kARROW) { 10040 } else if (CurrentToken() == Token::kARROW) {
10038 ConsumeToken(); 10041 ConsumeToken();
10039 SkipExpr(); 10042 SkipExpr();
10040 } 10043 }
10041 } 10044 }
10042 10045
10043 10046
10047 // Skips function/method/constructor/getter/setter preambles until the formal
10048 // parameter list. It is enough to skip the tokens, since we have already
10049 // previously parsed the function.
10050 void Parser::SkipFunctionPreamble(const Function& func) {
10051 if (func.IsImplicitConstructor()) return;
Michael Lippautz (Google) 2013/08/13 18:07:35 Should this be hoisted out of the function and che
hausner 2013/08/13 19:29:52 Either way is fine. I see your point and maybe it
10052 while (true) {
10053 if (CurrentToken() == Token::kLPAREN ||
10054 CurrentToken() == Token::kARROW ||
10055 CurrentToken() == Token::kSEMICOLON ||
10056 CurrentToken() == Token::kLBRACE) {
10057 return;
10058 }
10059 // Case handles "native" keyword, but also return types of form
10060 // native.SomeType where native is the name of a library.
10061 if (CurrentToken() == Token::kIDENT &&
10062 LookaheadToken(1) != Token::kPERIOD) {
10063 if (CurrentLiteral()->raw() == Symbols::Native().raw()) {
10064 return;
10065 }
10066 }
10067 ConsumeToken();
10068 }
10069 }
10070
10071
10044 void Parser::SkipListLiteral() { 10072 void Parser::SkipListLiteral() {
10045 if (CurrentToken() == Token::kINDEX) { 10073 if (CurrentToken() == Token::kINDEX) {
10046 // Empty list literal. 10074 // Empty list literal.
10047 ConsumeToken(); 10075 ConsumeToken();
10048 return; 10076 return;
10049 } 10077 }
10050 ExpectToken(Token::kLBRACK); 10078 ExpectToken(Token::kLBRACK);
10051 while (CurrentToken() != Token::kRBRACK) { 10079 while (CurrentToken() != Token::kRBRACK) {
10052 SkipNestedExpr(); 10080 SkipNestedExpr();
10053 if (CurrentToken() == Token::kCOMMA) { 10081 if (CurrentToken() == Token::kCOMMA) {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
10294 void Parser::SkipQualIdent() { 10322 void Parser::SkipQualIdent() {
10295 ASSERT(IsIdentifier()); 10323 ASSERT(IsIdentifier());
10296 ConsumeToken(); 10324 ConsumeToken();
10297 if (CurrentToken() == Token::kPERIOD) { 10325 if (CurrentToken() == Token::kPERIOD) {
10298 ConsumeToken(); // Consume the kPERIOD token. 10326 ConsumeToken(); // Consume the kPERIOD token.
10299 ExpectIdentifier("identifier expected after '.'"); 10327 ExpectIdentifier("identifier expected after '.'");
10300 } 10328 }
10301 } 10329 }
10302 10330
10303 } // namespace dart 10331 } // 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