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

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

Issue 10821076: - Allow parsing of external methods. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
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 "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 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 ZoneGrowableArray<ParamDesc>* parameters; 445 ZoneGrowableArray<ParamDesc>* parameters;
446 }; 446 };
447 447
448 448
449 struct MemberDesc { 449 struct MemberDesc {
450 MemberDesc() { 450 MemberDesc() {
451 Clear(); 451 Clear();
452 } 452 }
453 void Clear() { 453 void Clear() {
454 has_abstract = false; 454 has_abstract = false;
455 has_external = false;
455 has_final = false; 456 has_final = false;
456 has_const = false; 457 has_const = false;
457 has_static = false; 458 has_static = false;
458 has_var = false; 459 has_var = false;
459 has_factory = false; 460 has_factory = false;
460 type = NULL; 461 type = NULL;
461 name_pos = 0; 462 name_pos = 0;
462 name = NULL; 463 name = NULL;
463 redirect_name = NULL; 464 redirect_name = NULL;
464 params.Clear(); 465 params.Clear();
465 kind = RawFunction::kRegularFunction; 466 kind = RawFunction::kRegularFunction;
466 } 467 }
467 bool IsConstructor() const { 468 bool IsConstructor() const {
468 return (kind == RawFunction::kConstructor) && !has_static; 469 return (kind == RawFunction::kConstructor) && !has_static;
469 } 470 }
470 bool IsFactory() const { 471 bool IsFactory() const {
471 return (kind == RawFunction::kConstructor) && has_static; 472 return (kind == RawFunction::kConstructor) && has_static;
472 } 473 }
473 bool IsFactoryOrConstructor() const { 474 bool IsFactoryOrConstructor() const {
474 return (kind == RawFunction::kConstructor); 475 return (kind == RawFunction::kConstructor);
475 } 476 }
476 bool IsGetter() const { 477 bool IsGetter() const {
477 return kind == RawFunction::kGetterFunction; 478 return kind == RawFunction::kGetterFunction;
478 } 479 }
479 bool IsSetter() const { 480 bool IsSetter() const {
480 return kind == RawFunction::kSetterFunction; 481 return kind == RawFunction::kSetterFunction;
481 } 482 }
482 bool has_abstract; 483 bool has_abstract;
484 bool has_external;
483 bool has_final; 485 bool has_final;
484 bool has_const; 486 bool has_const;
485 bool has_static; 487 bool has_static;
486 bool has_var; 488 bool has_var;
487 bool has_factory; 489 bool has_factory;
488 const AbstractType* type; 490 const AbstractType* type;
489 intptr_t name_pos; 491 intptr_t name_pos;
490 String* name; 492 String* name;
491 String* redirect_name; // For constructors: NULL or redirected constructor. 493 String* redirect_name; // For constructors: NULL or redirected constructor.
492 ParamList params; 494 ParamList params;
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 ParamList func_params; 1060 ParamList func_params;
1059 const bool no_explicit_default_values = false; 1061 const bool no_explicit_default_values = false;
1060 ParseFormalParameterList(no_explicit_default_values, &func_params); 1062 ParseFormalParameterList(no_explicit_default_values, &func_params);
1061 1063
1062 // The field 'is_static' has no meaning for signature functions. 1064 // The field 'is_static' has no meaning for signature functions.
1063 const Function& signature_function = Function::Handle( 1065 const Function& signature_function = Function::Handle(
1064 Function::New(*parameter.name, 1066 Function::New(*parameter.name,
1065 RawFunction::kSignatureFunction, 1067 RawFunction::kSignatureFunction,
1066 /* is_static = */ false, 1068 /* is_static = */ false,
1067 /* is_const = */ false, 1069 /* is_const = */ false,
1070 /* is_external = */ false,
1068 parameter.name_pos)); 1071 parameter.name_pos));
1069 signature_function.set_owner(current_class()); 1072 signature_function.set_owner(current_class());
1070 signature_function.set_result_type(result_type); 1073 signature_function.set_result_type(result_type);
1071 AddFormalParamsToFunction(&func_params, signature_function); 1074 AddFormalParamsToFunction(&func_params, signature_function);
1072 const String& signature = String::Handle(signature_function.Signature()); 1075 const String& signature = String::Handle(signature_function.Signature());
1073 // Lookup the signature class, i.e. the class whose name is the signature. 1076 // Lookup the signature class, i.e. the class whose name is the signature.
1074 // We only lookup in the current library, but not in its imports, and only 1077 // We only lookup in the current library, but not in its imports, and only
1075 // create a new canonical signature class if it does not exist yet. 1078 // create a new canonical signature class if it does not exist yet.
1076 Class& signature_class = Class::ZoneHandle( 1079 Class& signature_class = Class::ZoneHandle(
1077 library_.LookupLocalClass(signature)); 1080 library_.LookupLocalClass(signature));
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
2158 ParseStatementSequence(); 2161 ParseStatementSequence();
2159 ExpectToken(Token::kRBRACE); 2162 ExpectToken(Token::kRBRACE);
2160 } else if (CurrentToken() == Token::kARROW) { 2163 } else if (CurrentToken() == Token::kARROW) {
2161 ConsumeToken(); 2164 ConsumeToken();
2162 const intptr_t expr_pos = TokenPos(); 2165 const intptr_t expr_pos = TokenPos();
2163 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 2166 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
2164 ASSERT(expr != NULL); 2167 ASSERT(expr != NULL);
2165 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 2168 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
2166 } else if (IsLiteral("native")) { 2169 } else if (IsLiteral("native")) {
2167 ParseNativeFunctionBlock(&params, func); 2170 ParseNativeFunctionBlock(&params, func);
2171 } else if (func.is_external()) {
2172 // Body of an external method contains a single throw.
2173 current_block_->statements->Add(
2174 new ThrowNode(TokenPos(),
2175 new LiteralNode(TokenPos(),
2176 String::ZoneHandle(
2177 Symbols::New("External implementation missing."))), NULL));
2168 } else { 2178 } else {
2169 UnexpectedToken(); 2179 UnexpectedToken();
2170 } 2180 }
2171 SequenceNode* body = CloseBlock(); 2181 SequenceNode* body = CloseBlock();
2172 current_block_->statements->Add(body); 2182 current_block_->statements->Add(body);
2173 innermost_function_ = saved_innermost_function.raw(); 2183 innermost_function_ = saved_innermost_function.raw();
2174 return CloseBlock(); 2184 return CloseBlock();
2175 } 2185 }
2176 2186
2177 2187
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 ErrorMsg(method->name_pos, "constructor cannot be 'static'"); 2296 ErrorMsg(method->name_pos, "constructor cannot be 'static'");
2287 } 2297 }
2288 if (method->IsConstructor() && method->has_const) { 2298 if (method->IsConstructor() && method->has_const) {
2289 Class& cls = Class::ZoneHandle(library_.LookupClass(members->class_name())); 2299 Class& cls = Class::ZoneHandle(library_.LookupClass(members->class_name()));
2290 cls.set_is_const(); 2300 cls.set_is_const();
2291 } 2301 }
2292 if (method->has_abstract && members->is_interface()) { 2302 if (method->has_abstract && members->is_interface()) {
2293 ErrorMsg(method->name_pos, 2303 ErrorMsg(method->name_pos,
2294 "'abstract' method only allowed in class definition"); 2304 "'abstract' method only allowed in class definition");
2295 } 2305 }
2306 if (method->has_external && members->is_interface()) {
2307 ErrorMsg(method->name_pos,
2308 "'external' method only allowed in class definition");
2309 }
2296 2310
2297 if (members->FunctionNameExists(*method->name, method->kind)) { 2311 if (members->FunctionNameExists(*method->name, method->kind)) {
2298 ErrorMsg(method->name_pos, 2312 ErrorMsg(method->name_pos,
2299 "field or method '%s' already defined", method->name->ToCString()); 2313 "field or method '%s' already defined", method->name->ToCString());
2300 } 2314 }
2301 2315
2302 // Parse the formal parameters. 2316 // Parse the formal parameters.
2303 // The first parameter of factory methods is an implicit parameter called 2317 // The first parameter of factory methods is an implicit parameter called
2304 // 'this' of type AbstractTypeArguments. 2318 // 'this' of type AbstractTypeArguments.
2305 const bool has_this_param = 2319 const bool has_this_param =
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 // Only constructors can redirect to another method. 2391 // Only constructors can redirect to another method.
2378 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); 2392 ASSERT((method->redirect_name == NULL) || method->IsConstructor());
2379 2393
2380 intptr_t method_end_pos = method_pos; 2394 intptr_t method_end_pos = method_pos;
2381 if ((CurrentToken() == Token::kLBRACE) || 2395 if ((CurrentToken() == Token::kLBRACE) ||
2382 (CurrentToken() == Token::kARROW)) { 2396 (CurrentToken() == Token::kARROW)) {
2383 if (method->has_abstract) { 2397 if (method->has_abstract) {
2384 ErrorMsg(method->name_pos, 2398 ErrorMsg(method->name_pos,
2385 "abstract method '%s' may not have function body", 2399 "abstract method '%s' may not have function body",
2386 method->name->ToCString()); 2400 method->name->ToCString());
2401 } else if (method->has_external) {
2402 ErrorMsg(method->name_pos,
2403 "external method '%s' may not have function body",
2404 method->name->ToCString());
2387 } else if (method->IsConstructor() && method->has_const) { 2405 } else if (method->IsConstructor() && method->has_const) {
2388 ErrorMsg(method->name_pos, 2406 ErrorMsg(method->name_pos,
2389 "const constructor '%s' may not have function body", 2407 "const constructor '%s' may not have function body",
2390 method->name->ToCString()); 2408 method->name->ToCString());
2391 } else if (method->IsFactory() && method->has_const) { 2409 } else if (method->IsFactory() && method->has_const) {
2392 ErrorMsg(method->name_pos, 2410 ErrorMsg(method->name_pos,
2393 "const factory '%s' may not have function body", 2411 "const factory '%s' may not have function body",
2394 method->name->ToCString()); 2412 method->name->ToCString());
2395 } else if (members->is_interface()) { 2413 } else if (members->is_interface()) {
2396 ErrorMsg(method->name_pos, 2414 ErrorMsg(method->name_pos,
(...skipping 17 matching lines...) Expand all
2414 "function body not allowed in interface declaration"); 2432 "function body not allowed in interface declaration");
2415 } else if (method->IsConstructor() && method->has_const) { 2433 } else if (method->IsConstructor() && method->has_const) {
2416 ErrorMsg(method->name_pos, 2434 ErrorMsg(method->name_pos,
2417 "const constructor '%s' may not have function body", 2435 "const constructor '%s' may not have function body",
2418 method->name->ToCString()); 2436 method->name->ToCString());
2419 } 2437 }
2420 ParseNativeDeclaration(); 2438 ParseNativeDeclaration();
2421 } else if (CurrentToken() == Token::kSEMICOLON) { 2439 } else if (CurrentToken() == Token::kSEMICOLON) {
2422 if (members->is_interface() || 2440 if (members->is_interface() ||
2423 method->has_abstract || 2441 method->has_abstract ||
2442 method->has_external ||
2424 (method->redirect_name != NULL) || 2443 (method->redirect_name != NULL) ||
2425 method->IsConstructor()) { 2444 method->IsConstructor()) {
2426 ConsumeToken(); 2445 ConsumeToken();
2427 } else { 2446 } else {
2428 ErrorMsg(method->name_pos, 2447 ErrorMsg(method->name_pos,
2429 "function body expected for method '%s'", 2448 "function body expected for method '%s'",
2430 method->name->ToCString()); 2449 method->name->ToCString());
2431 } 2450 }
2432 } else { 2451 } else {
2433 if (members->is_interface() || 2452 if (members->is_interface() ||
2434 method->has_abstract || 2453 method->has_abstract ||
2454 method->has_external ||
2435 (method->redirect_name != NULL) || 2455 (method->redirect_name != NULL) ||
2436 (method->IsConstructor() && method->has_const)) { 2456 (method->IsConstructor() && method->has_const)) {
2437 ExpectSemicolon(); 2457 ExpectSemicolon();
2438 } else { 2458 } else {
2439 ErrorMsg(method->name_pos, 2459 ErrorMsg(method->name_pos,
2440 "function body expected for method '%s'", 2460 "function body expected for method '%s'",
2441 method->name->ToCString()); 2461 method->name->ToCString());
2442 } 2462 }
2443 } 2463 }
2444 2464
2445 RawFunction::Kind function_kind; 2465 RawFunction::Kind function_kind;
2446 if (method->IsFactoryOrConstructor()) { 2466 if (method->IsFactoryOrConstructor()) {
2447 function_kind = RawFunction::kConstructor; 2467 function_kind = RawFunction::kConstructor;
2448 } else if (method->has_abstract) { 2468 } else if (method->has_abstract) {
2449 function_kind = RawFunction::kAbstract; 2469 function_kind = RawFunction::kAbstract;
2450 } else if (method->IsGetter()) { 2470 } else if (method->IsGetter()) {
2451 function_kind = RawFunction::kGetterFunction; 2471 function_kind = RawFunction::kGetterFunction;
2452 } else if (method->IsSetter()) { 2472 } else if (method->IsSetter()) {
2453 function_kind = RawFunction::kSetterFunction; 2473 function_kind = RawFunction::kSetterFunction;
2454 } else { 2474 } else {
2455 function_kind = RawFunction::kRegularFunction; 2475 function_kind = RawFunction::kRegularFunction;
2456 } 2476 }
2457 Function& func = Function::Handle( 2477 Function& func = Function::Handle(
2458 Function::New(*method->name, 2478 Function::New(*method->name,
2459 function_kind, 2479 function_kind,
2460 method->has_static, 2480 method->has_static,
2461 method->has_const, 2481 method->has_const,
2482 method->has_external,
2462 method_pos)); 2483 method_pos));
2463 func.set_result_type(*method->type); 2484 func.set_result_type(*method->type);
2464 func.set_end_token_pos(method_end_pos); 2485 func.set_end_token_pos(method_end_pos);
2465 2486
2466 // No need to resolve parameter types yet, or add parameters to local scope. 2487 // No need to resolve parameter types yet, or add parameters to local scope.
2467 ASSERT(is_top_level_); 2488 ASSERT(is_top_level_);
2468 AddFormalParamsToFunction(&method->params, func); 2489 AddFormalParamsToFunction(&method->params, func);
2469 members->AddFunction(func); 2490 members->AddFunction(func);
2470 } 2491 }
2471 2492
2472 2493
2473 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { 2494 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
2474 TRACE_PARSER("ParseFieldDefinition"); 2495 TRACE_PARSER("ParseFieldDefinition");
2475 // The parser has read the first field name and is now at the token 2496 // The parser has read the first field name and is now at the token
2476 // after the field name. 2497 // after the field name.
2477 ASSERT(CurrentToken() == Token::kSEMICOLON || 2498 ASSERT(CurrentToken() == Token::kSEMICOLON ||
2478 CurrentToken() == Token::kCOMMA || 2499 CurrentToken() == Token::kCOMMA ||
2479 CurrentToken() == Token::kASSIGN); 2500 CurrentToken() == Token::kASSIGN);
2480 ASSERT(field->type != NULL); 2501 ASSERT(field->type != NULL);
2481 ASSERT(field->name_pos > 0); 2502 ASSERT(field->name_pos > 0);
2482 ASSERT(current_member_ == field); 2503 ASSERT(current_member_ == field);
2483 2504
hausner 2012/07/30 16:25:59 Can a field be external? If not, this needs to be
Ivan Posva 2012/07/30 22:33:33 Done.
2484 if (field->has_const) { 2505 if (field->has_const) {
2485 ErrorMsg("keyword 'const' not allowed in field declaration"); 2506 ErrorMsg("keyword 'const' not allowed in field declaration");
2486 } 2507 }
2487 if (field->has_abstract) { 2508 if (field->has_abstract) {
2488 ErrorMsg("keyword 'abstract' not allowed in field declaration"); 2509 ErrorMsg("keyword 'abstract' not allowed in field declaration");
2489 } 2510 }
2490 if (field->has_factory) { 2511 if (field->has_factory) {
2491 ErrorMsg("keyword 'factory' not allowed in field declaration"); 2512 ErrorMsg("keyword 'factory' not allowed in field declaration");
2492 } 2513 }
2493 if (members->FieldNameExists(*field->name)) { 2514 if (members->FieldNameExists(*field->name)) {
(...skipping 29 matching lines...) Expand all
2523 class_field.set_type(*field->type); 2544 class_field.set_type(*field->type);
2524 class_field.set_has_initializer(has_initializer); 2545 class_field.set_has_initializer(has_initializer);
2525 members->AddField(class_field); 2546 members->AddField(class_field);
2526 2547
2527 // For static final fields, set value to "uninitialized" and 2548 // For static final fields, set value to "uninitialized" and
2528 // create a kConstImplicitGetter getter method. 2549 // create a kConstImplicitGetter getter method.
2529 if (field->has_static && has_initializer) { 2550 if (field->has_static && has_initializer) {
2530 class_field.set_value(Instance::Handle(Object::sentinel())); 2551 class_field.set_value(Instance::Handle(Object::sentinel()));
2531 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); 2552 String& getter_name = String::Handle(Field::GetterSymbol(*field->name));
2532 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter, 2553 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter,
2533 field->has_static, field->has_final, 2554 field->has_static, field->has_final, false,
2534 field->name_pos); 2555 field->name_pos);
2535 getter.set_result_type(*field->type); 2556 getter.set_result_type(*field->type);
2536 members->AddFunction(getter); 2557 members->AddFunction(getter);
2537 } 2558 }
2538 2559
2539 // For instance fields, we create implicit getter and setter methods. 2560 // For instance fields, we create implicit getter and setter methods.
2540 if (!field->has_static) { 2561 if (!field->has_static) {
2541 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); 2562 String& getter_name = String::Handle(Field::GetterSymbol(*field->name));
2542 getter = Function::New(getter_name, RawFunction::kImplicitGetter, 2563 getter = Function::New(getter_name, RawFunction::kImplicitGetter,
2543 field->has_static, field->has_final, 2564 field->has_static, field->has_final, false,
2544 field->name_pos); 2565 field->name_pos);
2545 ParamList params; 2566 ParamList params;
2546 params.AddReceiver(TokenPos()); 2567 params.AddReceiver(TokenPos());
2547 getter.set_result_type(*field->type); 2568 getter.set_result_type(*field->type);
2548 AddFormalParamsToFunction(&params, getter); 2569 AddFormalParamsToFunction(&params, getter);
2549 members->AddFunction(getter); 2570 members->AddFunction(getter);
2550 if (!field->has_final) { 2571 if (!field->has_final) {
2551 // Build a setter accessor for non-const fields. 2572 // Build a setter accessor for non-const fields.
2552 String& setter_name = String::Handle(Field::SetterSymbol(*field->name)); 2573 String& setter_name = String::Handle(Field::SetterSymbol(*field->name));
2553 setter = Function::New(setter_name, RawFunction::kImplicitSetter, 2574 setter = Function::New(setter_name, RawFunction::kImplicitSetter,
2554 field->has_static, field->has_final, 2575 field->has_static, field->has_final, false,
2555 field->name_pos); 2576 field->name_pos);
2556 ParamList params; 2577 ParamList params;
2557 params.AddReceiver(TokenPos()); 2578 params.AddReceiver(TokenPos());
2558 params.AddFinalParameter(TokenPos(), 2579 params.AddFinalParameter(TokenPos(),
2559 &String::ZoneHandle(Symbols::Value()), 2580 &String::ZoneHandle(Symbols::Value()),
2560 field->type); 2581 field->type);
2561 setter.set_result_type(Type::Handle(Type::VoidType())); 2582 setter.set_result_type(Type::Handle(Type::VoidType()));
2562 AddFormalParamsToFunction(&params, setter); 2583 AddFormalParamsToFunction(&params, setter);
2563 members->AddFunction(setter); 2584 members->AddFunction(setter);
2564 } 2585 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2598 2619
2599 void Parser::ParseClassMemberDefinition(ClassDesc* members) { 2620 void Parser::ParseClassMemberDefinition(ClassDesc* members) {
2600 TRACE_PARSER("ParseClassMemberDefinition"); 2621 TRACE_PARSER("ParseClassMemberDefinition");
2601 MemberDesc member; 2622 MemberDesc member;
2602 current_member_ = &member; 2623 current_member_ = &member;
2603 if ((CurrentToken() == Token::kABSTRACT) && 2624 if ((CurrentToken() == Token::kABSTRACT) &&
2604 (LookaheadToken(1) != Token::kLPAREN)) { 2625 (LookaheadToken(1) != Token::kLPAREN)) {
2605 ConsumeToken(); 2626 ConsumeToken();
2606 member.has_abstract = true; 2627 member.has_abstract = true;
2607 } 2628 }
2629 if ((CurrentToken() == Token::kEXTERNAL) &&
2630 (LookaheadToken(1) != Token::kLPAREN)) {
2631 ConsumeToken();
2632 member.has_external = true;
2633 }
2608 if ((CurrentToken() == Token::kSTATIC) && 2634 if ((CurrentToken() == Token::kSTATIC) &&
2609 (LookaheadToken(1) != Token::kLPAREN)) { 2635 (LookaheadToken(1) != Token::kLPAREN)) {
2610 ConsumeToken(); 2636 ConsumeToken();
2611 member.has_static = true; 2637 member.has_static = true;
2612 } 2638 }
2613 if (CurrentToken() == Token::kCONST) { 2639 if (CurrentToken() == Token::kCONST) {
2614 ConsumeToken(); 2640 ConsumeToken();
2615 member.has_const = true; 2641 member.has_const = true;
2616 } else if (CurrentToken() == Token::kFINAL) { 2642 } else if (CurrentToken() == Token::kFINAL) {
2617 ConsumeToken(); 2643 ConsumeToken();
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 String::Concat(class_desc->class_name(), 2940 String::Concat(class_desc->class_name(),
2915 String::Handle(Symbols::Dot()))); 2941 String::Handle(Symbols::Dot())));
2916 ctor_name = Symbols::New(ctor_name); 2942 ctor_name = Symbols::New(ctor_name);
2917 // The token position for the implicit constructor is the 'class' 2943 // The token position for the implicit constructor is the 'class'
2918 // keyword of the constructor's class. 2944 // keyword of the constructor's class.
2919 Function& ctor = Function::Handle( 2945 Function& ctor = Function::Handle(
2920 Function::New(ctor_name, 2946 Function::New(ctor_name,
2921 RawFunction::kConstructor, 2947 RawFunction::kConstructor,
2922 /* is_static = */ false, 2948 /* is_static = */ false,
2923 /* is_const = */ false, 2949 /* is_const = */ false,
2950 /* is_external = */ false,
2924 class_desc->token_pos())); 2951 class_desc->token_pos()));
2925 ParamList params; 2952 ParamList params;
2926 // Add implicit 'this' parameter. 2953 // Add implicit 'this' parameter.
2927 params.AddReceiver(TokenPos()); 2954 params.AddReceiver(TokenPos());
2928 // Add implicit parameter for construction phase. 2955 // Add implicit parameter for construction phase.
2929 params.AddFinalParameter( 2956 params.AddFinalParameter(
2930 TokenPos(), 2957 TokenPos(),
2931 &String::ZoneHandle(Symbols::PhaseParameter()), 2958 &String::ZoneHandle(Symbols::PhaseParameter()),
2932 &Type::ZoneHandle(Type::DynamicType())); 2959 &Type::ZoneHandle(Type::DynamicType()));
2933 2960
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3032 } 3059 }
3033 ParamList func_params; 3060 ParamList func_params;
3034 const bool no_explicit_default_values = false; 3061 const bool no_explicit_default_values = false;
3035 ParseFormalParameterList(no_explicit_default_values, &func_params); 3062 ParseFormalParameterList(no_explicit_default_values, &func_params);
3036 // The field 'is_static' has no meaning for signature functions. 3063 // The field 'is_static' has no meaning for signature functions.
3037 Function& signature_function = Function::Handle( 3064 Function& signature_function = Function::Handle(
3038 Function::New(*alias_name, 3065 Function::New(*alias_name,
3039 RawFunction::kSignatureFunction, 3066 RawFunction::kSignatureFunction,
3040 /* is_static = */ false, 3067 /* is_static = */ false,
3041 /* is_const = */ false, 3068 /* is_const = */ false,
3069 /* is_external = */ false,
3042 alias_name_pos)); 3070 alias_name_pos));
3043 signature_function.set_owner(alias_owner); 3071 signature_function.set_owner(alias_owner);
3044 signature_function.set_result_type(result_type); 3072 signature_function.set_result_type(result_type);
3045 AddFormalParamsToFunction(&func_params, signature_function); 3073 AddFormalParamsToFunction(&func_params, signature_function);
3046 const String& signature = String::Handle(signature_function.Signature()); 3074 const String& signature = String::Handle(signature_function.Signature());
3047 if (FLAG_trace_parser) { 3075 if (FLAG_trace_parser) {
3048 OS::Print("TopLevel parsing function type alias '%s'\n", 3076 OS::Print("TopLevel parsing function type alias '%s'\n",
3049 signature.ToCString()); 3077 signature.ToCString());
3050 } 3078 }
3051 // Lookup the signature class, i.e. the class whose name is the signature. 3079 // Lookup the signature class, i.e. the class whose name is the signature.
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
3461 field.set_value(Instance::Handle(Instance::null())); 3489 field.set_value(Instance::Handle(Instance::null()));
3462 top_level->fields.Add(field); 3490 top_level->fields.Add(field);
3463 library_.AddObject(field, var_name); 3491 library_.AddObject(field, var_name);
3464 if (CurrentToken() == Token::kASSIGN) { 3492 if (CurrentToken() == Token::kASSIGN) {
3465 ConsumeToken(); 3493 ConsumeToken();
3466 SkipExpr(); 3494 SkipExpr();
3467 field.set_value(Instance::Handle(Object::sentinel())); 3495 field.set_value(Instance::Handle(Object::sentinel()));
3468 // Create a static const getter. 3496 // Create a static const getter.
3469 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); 3497 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name));
3470 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter, 3498 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter,
3471 is_static, is_final, name_pos); 3499 is_static, is_final, false, name_pos);
3472 getter.set_result_type(type); 3500 getter.set_result_type(type);
3473 top_level->functions.Add(getter); 3501 top_level->functions.Add(getter);
3474 } else if (is_final) { 3502 } else if (is_final) {
3475 ErrorMsg(name_pos, "missing initializer for final variable"); 3503 ErrorMsg(name_pos, "missing initializer for final variable");
3476 } 3504 }
3477 3505
3478 if (CurrentToken() == Token::kCOMMA) { 3506 if (CurrentToken() == Token::kCOMMA) {
3479 ConsumeToken(); 3507 ConsumeToken();
3480 } else if (CurrentToken() == Token::kSEMICOLON) { 3508 } else if (CurrentToken() == Token::kSEMICOLON) {
3481 ConsumeToken(); 3509 ConsumeToken();
3482 break; 3510 break;
3483 } else { 3511 } else {
3484 ExpectSemicolon(); // Reports error. 3512 ExpectSemicolon(); // Reports error.
3485 } 3513 }
3486 } 3514 }
3487 } 3515 }
3488 3516
3489 3517
3490 void Parser::ParseTopLevelFunction(TopLevel* top_level) { 3518 void Parser::ParseTopLevelFunction(TopLevel* top_level) {
3491 TRACE_PARSER("ParseTopLevelFunction"); 3519 TRACE_PARSER("ParseTopLevelFunction");
3492 AbstractType& result_type = Type::Handle(Type::DynamicType()); 3520 AbstractType& result_type = Type::Handle(Type::DynamicType());
3493 const bool is_static = true; 3521 const bool is_static = true;
3522 bool is_external = false;
3523 if (CurrentToken() == Token::kEXTERNAL) {
3524 ConsumeToken();
3525 is_external = true;
3526 }
3494 if (CurrentToken() == Token::kVOID) { 3527 if (CurrentToken() == Token::kVOID) {
3495 ConsumeToken(); 3528 ConsumeToken();
3496 result_type = Type::VoidType(); 3529 result_type = Type::VoidType();
3497 } else { 3530 } else {
3498 // Parse optional type. 3531 // Parse optional type.
3499 if ((CurrentToken() == Token::kIDENT) && 3532 if ((CurrentToken() == Token::kIDENT) &&
3500 (LookaheadToken(1) != Token::kLPAREN)) { 3533 (LookaheadToken(1) != Token::kLPAREN)) {
3501 result_type = ParseType(ClassFinalizer::kTryResolve); 3534 result_type = ParseType(ClassFinalizer::kTryResolve);
3502 } 3535 }
3503 } 3536 }
(...skipping 16 matching lines...) Expand all
3520 3553
3521 if (CurrentToken() != Token::kLPAREN) { 3554 if (CurrentToken() != Token::kLPAREN) {
3522 ErrorMsg("'(' expected"); 3555 ErrorMsg("'(' expected");
3523 } 3556 }
3524 const intptr_t function_pos = TokenPos(); 3557 const intptr_t function_pos = TokenPos();
3525 ParamList params; 3558 ParamList params;
3526 const bool allow_explicit_default_values = true; 3559 const bool allow_explicit_default_values = true;
3527 ParseFormalParameterList(allow_explicit_default_values, &params); 3560 ParseFormalParameterList(allow_explicit_default_values, &params);
3528 3561
3529 intptr_t function_end_pos = function_pos; 3562 intptr_t function_end_pos = function_pos;
3530 if (CurrentToken() == Token::kLBRACE) { 3563 if (is_external) {
3564 ExpectSemicolon();
3565 } else if (CurrentToken() == Token::kLBRACE) {
3531 SkipBlock(); 3566 SkipBlock();
3532 function_end_pos = TokenPos(); 3567 function_end_pos = TokenPos();
3533 } else if (CurrentToken() == Token::kARROW) { 3568 } else if (CurrentToken() == Token::kARROW) {
3534 ConsumeToken(); 3569 ConsumeToken();
3535 SkipExpr(); 3570 SkipExpr();
3536 ExpectSemicolon(); 3571 ExpectSemicolon();
3537 function_end_pos = TokenPos(); 3572 function_end_pos = TokenPos();
3538 } else if (IsLiteral("native")) { 3573 } else if (IsLiteral("native")) {
3539 ParseNativeDeclaration(); 3574 ParseNativeDeclaration();
3540 } else { 3575 } else {
3541 ErrorMsg("function block expected"); 3576 ErrorMsg("function block expected");
3542 } 3577 }
3543 Function& func = Function::Handle( 3578 Function& func = Function::Handle(
3544 Function::New(func_name, RawFunction::kRegularFunction, 3579 Function::New(func_name, RawFunction::kRegularFunction,
3545 is_static, false, function_pos)); 3580 is_static, false, is_external, function_pos));
3546 func.set_result_type(result_type); 3581 func.set_result_type(result_type);
3547 func.set_end_token_pos(function_end_pos); 3582 func.set_end_token_pos(function_end_pos);
3548 AddFormalParamsToFunction(&params, func); 3583 AddFormalParamsToFunction(&params, func);
3549 top_level->functions.Add(func); 3584 top_level->functions.Add(func);
3550 library_.AddObject(func, func_name); 3585 library_.AddObject(func, func_name);
3551 } 3586 }
3552 3587
3553 3588
3554 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { 3589 void Parser::ParseTopLevelAccessor(TopLevel* top_level) {
3555 TRACE_PARSER("ParseTopLevelAccessor"); 3590 TRACE_PARSER("ParseTopLevelAccessor");
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3617 ExpectSemicolon(); 3652 ExpectSemicolon();
3618 } else if (IsLiteral("native")) { 3653 } else if (IsLiteral("native")) {
3619 ParseNativeDeclaration(); 3654 ParseNativeDeclaration();
3620 } else { 3655 } else {
3621 ErrorMsg("function block expected"); 3656 ErrorMsg("function block expected");
3622 } 3657 }
3623 Function& func = Function::Handle( 3658 Function& func = Function::Handle(
3624 Function::New(accessor_name, 3659 Function::New(accessor_name,
3625 is_getter? RawFunction::kGetterFunction : 3660 is_getter? RawFunction::kGetterFunction :
3626 RawFunction::kSetterFunction, 3661 RawFunction::kSetterFunction,
3627 is_static, false, accessor_pos)); 3662 is_static, false, false, accessor_pos));
3628 func.set_result_type(result_type); 3663 func.set_result_type(result_type);
3629 AddFormalParamsToFunction(&params, func); 3664 AddFormalParamsToFunction(&params, func);
3630 top_level->functions.Add(func); 3665 top_level->functions.Add(func);
3631 library_.AddObject(func, accessor_name); 3666 library_.AddObject(func, accessor_name);
3632 } 3667 }
3633 3668
3634 3669
3635 void Parser::ParseLibraryName() { 3670 void Parser::ParseLibraryName() {
3636 TRACE_PARSER("ParseLibraryName"); 3671 TRACE_PARSER("ParseLibraryName");
3637 if ((script_.kind() == RawScript::kLibraryTag) && 3672 if ((script_.kind() == RawScript::kLibraryTag) &&
(...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after
4463 } 4498 }
4464 SetPosition(saved_pos); 4499 SetPosition(saved_pos);
4465 return is_var_decl; 4500 return is_var_decl;
4466 } 4501 }
4467 4502
4468 4503
4469 // Look ahead to detect whether the next tokens should be parsed as 4504 // Look ahead to detect whether the next tokens should be parsed as
4470 // a function declaration. Token position remains unchanged. 4505 // a function declaration. Token position remains unchanged.
4471 bool Parser::IsFunctionDeclaration() { 4506 bool Parser::IsFunctionDeclaration() {
4472 const intptr_t saved_pos = TokenPos(); 4507 const intptr_t saved_pos = TokenPos();
4508 bool is_external = false;
4509 if (is_top_level_ && (CurrentToken() == Token::kEXTERNAL)) {
4510 // Skip over 'external' for top-level function declarations.
4511 is_external = true;
4512 ConsumeToken();
4513 }
4473 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { 4514 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
4474 // Possibly a function without explicit return type. 4515 // Possibly a function without explicit return type.
4475 ConsumeToken(); // Consume function identifier. 4516 ConsumeToken(); // Consume function identifier.
4476 } else if (TryParseReturnType()) { 4517 } else if (TryParseReturnType()) {
4477 if (!IsIdentifier()) { 4518 if (!IsIdentifier()) {
4478 SetPosition(saved_pos); 4519 SetPosition(saved_pos);
4479 return false; 4520 return false;
4480 } 4521 }
4481 ConsumeToken(); // Consume function identifier. 4522 ConsumeToken(); // Consume function identifier.
4482 } else { 4523 } else {
4483 SetPosition(saved_pos); 4524 SetPosition(saved_pos);
4484 return false; 4525 return false;
4485 } 4526 }
4486 // Check parameter list and the following token. 4527 // Check parameter list and the following token.
4487 if (CurrentToken() == Token::kLPAREN) { 4528 if (CurrentToken() == Token::kLPAREN) {
4488 SkipToMatchingParenthesis(); 4529 SkipToMatchingParenthesis();
4489 if ((CurrentToken() == Token::kLBRACE) || 4530 if ((CurrentToken() == Token::kLBRACE) ||
4490 (CurrentToken() == Token::kARROW) || 4531 (CurrentToken() == Token::kARROW) ||
4491 (is_top_level_ && IsLiteral("native"))) { 4532 (is_top_level_ && IsLiteral("native")) ||
4533 (is_external && (CurrentToken() == Token::kSEMICOLON))) {
hausner 2012/07/30 16:22:41 I don't think you need to check for the semicolon
Ivan Posva 2012/07/30 22:33:33 Done.
4492 SetPosition(saved_pos); 4534 SetPosition(saved_pos);
4493 return true; 4535 return true;
4494 } 4536 }
4495 } 4537 }
4496 SetPosition(saved_pos); 4538 SetPosition(saved_pos);
4497 return false; 4539 return false;
4498 } 4540 }
4499 4541
4500 4542
4501 bool Parser::IsTopLevelAccessor() { 4543 bool Parser::IsTopLevelAccessor() {
(...skipping 4176 matching lines...) Expand 10 before | Expand all | Expand 10 after
8678 void Parser::SkipQualIdent() { 8720 void Parser::SkipQualIdent() {
8679 ASSERT(IsIdentifier()); 8721 ASSERT(IsIdentifier());
8680 ConsumeToken(); 8722 ConsumeToken();
8681 if (CurrentToken() == Token::kPERIOD) { 8723 if (CurrentToken() == Token::kPERIOD) {
8682 ConsumeToken(); // Consume the kPERIOD token. 8724 ConsumeToken(); // Consume the kPERIOD token.
8683 ExpectIdentifier("identifier expected after '.'"); 8725 ExpectIdentifier("identifier expected after '.'");
8684 } 8726 }
8685 } 8727 }
8686 8728
8687 } // namespace dart 8729 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698