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

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
« no previous file with comments | « runtime/vm/object_test.cc ('k') | runtime/vm/raw_object.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 "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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 ParamList func_params; 1062 ParamList func_params;
1061 const bool no_explicit_default_values = false; 1063 const bool no_explicit_default_values = false;
1062 ParseFormalParameterList(no_explicit_default_values, &func_params); 1064 ParseFormalParameterList(no_explicit_default_values, &func_params);
1063 1065
1064 // The field 'is_static' has no meaning for signature functions. 1066 // The field 'is_static' has no meaning for signature functions.
1065 const Function& signature_function = Function::Handle( 1067 const Function& signature_function = Function::Handle(
1066 Function::New(*parameter.name, 1068 Function::New(*parameter.name,
1067 RawFunction::kSignatureFunction, 1069 RawFunction::kSignatureFunction,
1068 /* is_static = */ false, 1070 /* is_static = */ false,
1069 /* is_const = */ false, 1071 /* is_const = */ false,
1072 /* is_external = */ false,
1070 parameter.name_pos)); 1073 parameter.name_pos));
1071 signature_function.set_owner(current_class()); 1074 signature_function.set_owner(current_class());
1072 signature_function.set_result_type(result_type); 1075 signature_function.set_result_type(result_type);
1073 AddFormalParamsToFunction(&func_params, signature_function); 1076 AddFormalParamsToFunction(&func_params, signature_function);
1074 const String& signature = String::Handle(signature_function.Signature()); 1077 const String& signature = String::Handle(signature_function.Signature());
1075 // Lookup the signature class, i.e. the class whose name is the signature. 1078 // Lookup the signature class, i.e. the class whose name is the signature.
1076 // We only lookup in the current library, but not in its imports, and only 1079 // We only lookup in the current library, but not in its imports, and only
1077 // create a new canonical signature class if it does not exist yet. 1080 // create a new canonical signature class if it does not exist yet.
1078 Class& signature_class = Class::ZoneHandle( 1081 Class& signature_class = Class::ZoneHandle(
1079 library_.LookupLocalClass(signature)); 1082 library_.LookupLocalClass(signature));
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
2160 ParseStatementSequence(); 2163 ParseStatementSequence();
2161 ExpectToken(Token::kRBRACE); 2164 ExpectToken(Token::kRBRACE);
2162 } else if (CurrentToken() == Token::kARROW) { 2165 } else if (CurrentToken() == Token::kARROW) {
2163 ConsumeToken(); 2166 ConsumeToken();
2164 const intptr_t expr_pos = TokenPos(); 2167 const intptr_t expr_pos = TokenPos();
2165 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); 2168 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
2166 ASSERT(expr != NULL); 2169 ASSERT(expr != NULL);
2167 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); 2170 current_block_->statements->Add(new ReturnNode(expr_pos, expr));
2168 } else if (IsLiteral("native")) { 2171 } else if (IsLiteral("native")) {
2169 ParseNativeFunctionBlock(&params, func); 2172 ParseNativeFunctionBlock(&params, func);
2173 } else if (func.is_external()) {
2174 // Body of an external method contains a single throw.
2175 current_block_->statements->Add(
2176 new ThrowNode(TokenPos(),
2177 new LiteralNode(TokenPos(),
2178 String::ZoneHandle(
2179 Symbols::New("External implementation missing."))), NULL));
2170 } else { 2180 } else {
2171 UnexpectedToken(); 2181 UnexpectedToken();
2172 } 2182 }
2173 SequenceNode* body = CloseBlock(); 2183 SequenceNode* body = CloseBlock();
2174 current_block_->statements->Add(body); 2184 current_block_->statements->Add(body);
2175 innermost_function_ = saved_innermost_function.raw(); 2185 innermost_function_ = saved_innermost_function.raw();
2176 return CloseBlock(); 2186 return CloseBlock();
2177 } 2187 }
2178 2188
2179 2189
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 ErrorMsg(method->name_pos, "constructor cannot be 'static'"); 2298 ErrorMsg(method->name_pos, "constructor cannot be 'static'");
2289 } 2299 }
2290 if (method->IsConstructor() && method->has_const) { 2300 if (method->IsConstructor() && method->has_const) {
2291 Class& cls = Class::ZoneHandle(library_.LookupClass(members->class_name())); 2301 Class& cls = Class::ZoneHandle(library_.LookupClass(members->class_name()));
2292 cls.set_is_const(); 2302 cls.set_is_const();
2293 } 2303 }
2294 if (method->has_abstract && members->is_interface()) { 2304 if (method->has_abstract && members->is_interface()) {
2295 ErrorMsg(method->name_pos, 2305 ErrorMsg(method->name_pos,
2296 "'abstract' method only allowed in class definition"); 2306 "'abstract' method only allowed in class definition");
2297 } 2307 }
2308 if (method->has_external && members->is_interface()) {
2309 ErrorMsg(method->name_pos,
2310 "'external' method only allowed in class definition");
2311 }
2298 2312
2299 if (members->FunctionNameExists(*method->name, method->kind)) { 2313 if (members->FunctionNameExists(*method->name, method->kind)) {
2300 ErrorMsg(method->name_pos, 2314 ErrorMsg(method->name_pos,
2301 "field or method '%s' already defined", method->name->ToCString()); 2315 "field or method '%s' already defined", method->name->ToCString());
2302 } 2316 }
2303 2317
2304 // Parse the formal parameters. 2318 // Parse the formal parameters.
2305 // The first parameter of factory methods is an implicit parameter called 2319 // The first parameter of factory methods is an implicit parameter called
2306 // 'this' of type AbstractTypeArguments. 2320 // 'this' of type AbstractTypeArguments.
2307 const bool has_this_param = 2321 const bool has_this_param =
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2379 // Only constructors can redirect to another method. 2393 // Only constructors can redirect to another method.
2380 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); 2394 ASSERT((method->redirect_name == NULL) || method->IsConstructor());
2381 2395
2382 intptr_t method_end_pos = method_pos; 2396 intptr_t method_end_pos = method_pos;
2383 if ((CurrentToken() == Token::kLBRACE) || 2397 if ((CurrentToken() == Token::kLBRACE) ||
2384 (CurrentToken() == Token::kARROW)) { 2398 (CurrentToken() == Token::kARROW)) {
2385 if (method->has_abstract) { 2399 if (method->has_abstract) {
2386 ErrorMsg(method->name_pos, 2400 ErrorMsg(method->name_pos,
2387 "abstract method '%s' may not have a function body", 2401 "abstract method '%s' may not have a function body",
2388 method->name->ToCString()); 2402 method->name->ToCString());
2403 } else if (method->has_external) {
2404 ErrorMsg(method->name_pos,
2405 "external method '%s' may not have a function body",
2406 method->name->ToCString());
2389 } else if (method->IsConstructor() && method->has_const) { 2407 } else if (method->IsConstructor() && method->has_const) {
2390 ErrorMsg(method->name_pos, 2408 ErrorMsg(method->name_pos,
2391 "const constructor '%s' may not have a function body", 2409 "const constructor '%s' may not have a function body",
2392 method->name->ToCString()); 2410 method->name->ToCString());
2393 } else if (method->IsFactory() && method->has_const) { 2411 } else if (method->IsFactory() && method->has_const) {
2394 ErrorMsg(method->name_pos, 2412 ErrorMsg(method->name_pos,
2395 "const factory '%s' may not have a function body", 2413 "const factory '%s' may not have a function body",
2396 method->name->ToCString()); 2414 method->name->ToCString());
2397 } else if (members->is_interface()) { 2415 } else if (members->is_interface()) {
2398 ErrorMsg(method->name_pos, 2416 ErrorMsg(method->name_pos,
(...skipping 25 matching lines...) Expand all
2424 method->name->ToCString()); 2442 method->name->ToCString());
2425 } 2443 }
2426 if (method->redirect_name != NULL) { 2444 if (method->redirect_name != NULL) {
2427 ErrorMsg(method->name_pos, 2445 ErrorMsg(method->name_pos,
2428 "Constructor with redirection may not have a function body"); 2446 "Constructor with redirection may not have a function body");
2429 } 2447 }
2430 ParseNativeDeclaration(); 2448 ParseNativeDeclaration();
2431 } else if (CurrentToken() == Token::kSEMICOLON) { 2449 } else if (CurrentToken() == Token::kSEMICOLON) {
2432 if (members->is_interface() || 2450 if (members->is_interface() ||
2433 method->has_abstract || 2451 method->has_abstract ||
2452 method->has_external ||
2434 (method->redirect_name != NULL) || 2453 (method->redirect_name != NULL) ||
2435 method->IsConstructor()) { 2454 method->IsConstructor()) {
2436 ConsumeToken(); 2455 ConsumeToken();
2437 } else { 2456 } else {
2438 ErrorMsg(method->name_pos, 2457 ErrorMsg(method->name_pos,
2439 "function body expected for method '%s'", 2458 "function body expected for method '%s'",
2440 method->name->ToCString()); 2459 method->name->ToCString());
2441 } 2460 }
2442 } else { 2461 } else {
2443 if (members->is_interface() || 2462 if (members->is_interface() ||
2444 method->has_abstract || 2463 method->has_abstract ||
2464 method->has_external ||
2445 (method->redirect_name != NULL) || 2465 (method->redirect_name != NULL) ||
2446 (method->IsConstructor() && method->has_const)) { 2466 (method->IsConstructor() && method->has_const)) {
2447 ExpectSemicolon(); 2467 ExpectSemicolon();
2448 } else { 2468 } else {
2449 ErrorMsg(method->name_pos, 2469 ErrorMsg(method->name_pos,
2450 "function body expected for method '%s'", 2470 "function body expected for method '%s'",
2451 method->name->ToCString()); 2471 method->name->ToCString());
2452 } 2472 }
2453 } 2473 }
2454 2474
2455 RawFunction::Kind function_kind; 2475 RawFunction::Kind function_kind;
2456 if (method->IsFactoryOrConstructor()) { 2476 if (method->IsFactoryOrConstructor()) {
2457 function_kind = RawFunction::kConstructor; 2477 function_kind = RawFunction::kConstructor;
2458 } else if (method->has_abstract) { 2478 } else if (method->has_abstract) {
2459 function_kind = RawFunction::kAbstract; 2479 function_kind = RawFunction::kAbstract;
2460 } else if (method->IsGetter()) { 2480 } else if (method->IsGetter()) {
2461 function_kind = RawFunction::kGetterFunction; 2481 function_kind = RawFunction::kGetterFunction;
2462 } else if (method->IsSetter()) { 2482 } else if (method->IsSetter()) {
2463 function_kind = RawFunction::kSetterFunction; 2483 function_kind = RawFunction::kSetterFunction;
2464 } else { 2484 } else {
2465 function_kind = RawFunction::kRegularFunction; 2485 function_kind = RawFunction::kRegularFunction;
2466 } 2486 }
2467 Function& func = Function::Handle( 2487 Function& func = Function::Handle(
2468 Function::New(*method->name, 2488 Function::New(*method->name,
2469 function_kind, 2489 function_kind,
2470 method->has_static, 2490 method->has_static,
2471 method->has_const, 2491 method->has_const,
2492 method->has_external,
2472 method_pos)); 2493 method_pos));
2473 func.set_result_type(*method->type); 2494 func.set_result_type(*method->type);
2474 func.set_end_token_pos(method_end_pos); 2495 func.set_end_token_pos(method_end_pos);
2475 2496
2476 // No need to resolve parameter types yet, or add parameters to local scope. 2497 // No need to resolve parameter types yet, or add parameters to local scope.
2477 ASSERT(is_top_level_); 2498 ASSERT(is_top_level_);
2478 AddFormalParamsToFunction(&method->params, func); 2499 AddFormalParamsToFunction(&method->params, func);
2479 members->AddFunction(func); 2500 members->AddFunction(func);
2480 } 2501 }
2481 2502
2482 2503
2483 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { 2504 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) {
2484 TRACE_PARSER("ParseFieldDefinition"); 2505 TRACE_PARSER("ParseFieldDefinition");
2485 // The parser has read the first field name and is now at the token 2506 // The parser has read the first field name and is now at the token
2486 // after the field name. 2507 // after the field name.
2487 ASSERT(CurrentToken() == Token::kSEMICOLON || 2508 ASSERT(CurrentToken() == Token::kSEMICOLON ||
2488 CurrentToken() == Token::kCOMMA || 2509 CurrentToken() == Token::kCOMMA ||
2489 CurrentToken() == Token::kASSIGN); 2510 CurrentToken() == Token::kASSIGN);
2490 ASSERT(field->type != NULL); 2511 ASSERT(field->type != NULL);
2491 ASSERT(field->name_pos > 0); 2512 ASSERT(field->name_pos > 0);
2492 ASSERT(current_member_ == field); 2513 ASSERT(current_member_ == field);
2493 ASSERT(!field->has_const || field->has_final); 2514 ASSERT(!field->has_const || field->has_final);
2494 2515
2495 if (field->has_abstract) { 2516 if (field->has_abstract) {
2496 ErrorMsg("keyword 'abstract' not allowed in field declaration"); 2517 ErrorMsg("keyword 'abstract' not allowed in field declaration");
2497 } 2518 }
2519 if (field->has_external) {
2520 ErrorMsg("keyword 'external' not allowed in field declaration");
2521 }
2498 if (field->has_factory) { 2522 if (field->has_factory) {
2499 ErrorMsg("keyword 'factory' not allowed in field declaration"); 2523 ErrorMsg("keyword 'factory' not allowed in field declaration");
2500 } 2524 }
2501 if (members->FieldNameExists(*field->name)) { 2525 if (members->FieldNameExists(*field->name)) {
2502 ErrorMsg(field->name_pos, 2526 ErrorMsg(field->name_pos,
2503 "'%s' field/method already defined\n", field->name->ToCString()); 2527 "'%s' field/method already defined\n", field->name->ToCString());
2504 } 2528 }
2505 Function& getter = Function::Handle(); 2529 Function& getter = Function::Handle();
2506 Function& setter = Function::Handle(); 2530 Function& setter = Function::Handle();
2507 Field& class_field = Field::Handle(); 2531 Field& class_field = Field::Handle();
(...skipping 28 matching lines...) Expand all
2536 class_field.set_type(*field->type); 2560 class_field.set_type(*field->type);
2537 class_field.set_has_initializer(has_initializer); 2561 class_field.set_has_initializer(has_initializer);
2538 members->AddField(class_field); 2562 members->AddField(class_field);
2539 2563
2540 // For static final fields, set value to "uninitialized" and 2564 // For static final fields, set value to "uninitialized" and
2541 // create a kConstImplicitGetter getter method. 2565 // create a kConstImplicitGetter getter method.
2542 if (field->has_static && has_initializer) { 2566 if (field->has_static && has_initializer) {
2543 class_field.set_value(Instance::Handle(Object::sentinel())); 2567 class_field.set_value(Instance::Handle(Object::sentinel()));
2544 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); 2568 String& getter_name = String::Handle(Field::GetterSymbol(*field->name));
2545 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter, 2569 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter,
2546 field->has_static, field->has_final, 2570 field->has_static, field->has_final, false,
2547 field->name_pos); 2571 field->name_pos);
2548 getter.set_result_type(*field->type); 2572 getter.set_result_type(*field->type);
2549 members->AddFunction(getter); 2573 members->AddFunction(getter);
2550 } 2574 }
2551 2575
2552 // For instance fields, we create implicit getter and setter methods. 2576 // For instance fields, we create implicit getter and setter methods.
2553 if (!field->has_static) { 2577 if (!field->has_static) {
2554 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); 2578 String& getter_name = String::Handle(Field::GetterSymbol(*field->name));
2555 getter = Function::New(getter_name, RawFunction::kImplicitGetter, 2579 getter = Function::New(getter_name, RawFunction::kImplicitGetter,
2556 field->has_static, field->has_final, 2580 field->has_static, field->has_final, false,
2557 field->name_pos); 2581 field->name_pos);
2558 ParamList params; 2582 ParamList params;
2559 params.AddReceiver(TokenPos()); 2583 params.AddReceiver(TokenPos());
2560 getter.set_result_type(*field->type); 2584 getter.set_result_type(*field->type);
2561 AddFormalParamsToFunction(&params, getter); 2585 AddFormalParamsToFunction(&params, getter);
2562 members->AddFunction(getter); 2586 members->AddFunction(getter);
2563 if (!field->has_final) { 2587 if (!field->has_final) {
2564 // Build a setter accessor for non-const fields. 2588 // Build a setter accessor for non-const fields.
2565 String& setter_name = String::Handle(Field::SetterSymbol(*field->name)); 2589 String& setter_name = String::Handle(Field::SetterSymbol(*field->name));
2566 setter = Function::New(setter_name, RawFunction::kImplicitSetter, 2590 setter = Function::New(setter_name, RawFunction::kImplicitSetter,
2567 field->has_static, field->has_final, 2591 field->has_static, field->has_final, false,
2568 field->name_pos); 2592 field->name_pos);
2569 ParamList params; 2593 ParamList params;
2570 params.AddReceiver(TokenPos()); 2594 params.AddReceiver(TokenPos());
2571 params.AddFinalParameter(TokenPos(), 2595 params.AddFinalParameter(TokenPos(),
2572 &String::ZoneHandle(Symbols::Value()), 2596 &String::ZoneHandle(Symbols::Value()),
2573 field->type); 2597 field->type);
2574 setter.set_result_type(Type::Handle(Type::VoidType())); 2598 setter.set_result_type(Type::Handle(Type::VoidType()));
2575 AddFormalParamsToFunction(&params, setter); 2599 AddFormalParamsToFunction(&params, setter);
2576 members->AddFunction(setter); 2600 members->AddFunction(setter);
2577 } 2601 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2611 2635
2612 void Parser::ParseClassMemberDefinition(ClassDesc* members) { 2636 void Parser::ParseClassMemberDefinition(ClassDesc* members) {
2613 TRACE_PARSER("ParseClassMemberDefinition"); 2637 TRACE_PARSER("ParseClassMemberDefinition");
2614 MemberDesc member; 2638 MemberDesc member;
2615 current_member_ = &member; 2639 current_member_ = &member;
2616 if ((CurrentToken() == Token::kABSTRACT) && 2640 if ((CurrentToken() == Token::kABSTRACT) &&
2617 (LookaheadToken(1) != Token::kLPAREN)) { 2641 (LookaheadToken(1) != Token::kLPAREN)) {
2618 ConsumeToken(); 2642 ConsumeToken();
2619 member.has_abstract = true; 2643 member.has_abstract = true;
2620 } 2644 }
2645 if ((CurrentToken() == Token::kEXTERNAL) &&
2646 (LookaheadToken(1) != Token::kLPAREN)) {
2647 ConsumeToken();
2648 member.has_external = true;
2649 }
2621 if ((CurrentToken() == Token::kSTATIC) && 2650 if ((CurrentToken() == Token::kSTATIC) &&
2622 (LookaheadToken(1) != Token::kLPAREN)) { 2651 (LookaheadToken(1) != Token::kLPAREN)) {
2623 ConsumeToken(); 2652 ConsumeToken();
2624 member.has_static = true; 2653 member.has_static = true;
2625 } 2654 }
2626 if (CurrentToken() == Token::kCONST) { 2655 if (CurrentToken() == Token::kCONST) {
2627 ConsumeToken(); 2656 ConsumeToken();
2628 member.has_const = true; 2657 member.has_const = true;
2629 } else if (CurrentToken() == Token::kFINAL) { 2658 } else if (CurrentToken() == Token::kFINAL) {
2630 ConsumeToken(); 2659 ConsumeToken();
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
2932 String::Concat(class_desc->class_name(), 2961 String::Concat(class_desc->class_name(),
2933 String::Handle(Symbols::Dot()))); 2962 String::Handle(Symbols::Dot())));
2934 ctor_name = Symbols::New(ctor_name); 2963 ctor_name = Symbols::New(ctor_name);
2935 // The token position for the implicit constructor is the 'class' 2964 // The token position for the implicit constructor is the 'class'
2936 // keyword of the constructor's class. 2965 // keyword of the constructor's class.
2937 Function& ctor = Function::Handle( 2966 Function& ctor = Function::Handle(
2938 Function::New(ctor_name, 2967 Function::New(ctor_name,
2939 RawFunction::kConstructor, 2968 RawFunction::kConstructor,
2940 /* is_static = */ false, 2969 /* is_static = */ false,
2941 /* is_const = */ false, 2970 /* is_const = */ false,
2971 /* is_external = */ false,
2942 class_desc->token_pos())); 2972 class_desc->token_pos()));
2943 ParamList params; 2973 ParamList params;
2944 // Add implicit 'this' parameter. 2974 // Add implicit 'this' parameter.
2945 params.AddReceiver(TokenPos()); 2975 params.AddReceiver(TokenPos());
2946 // Add implicit parameter for construction phase. 2976 // Add implicit parameter for construction phase.
2947 params.AddFinalParameter( 2977 params.AddFinalParameter(
2948 TokenPos(), 2978 TokenPos(),
2949 &String::ZoneHandle(Symbols::PhaseParameter()), 2979 &String::ZoneHandle(Symbols::PhaseParameter()),
2950 &Type::ZoneHandle(Type::DynamicType())); 2980 &Type::ZoneHandle(Type::DynamicType()));
2951 2981
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3050 } 3080 }
3051 ParamList func_params; 3081 ParamList func_params;
3052 const bool no_explicit_default_values = false; 3082 const bool no_explicit_default_values = false;
3053 ParseFormalParameterList(no_explicit_default_values, &func_params); 3083 ParseFormalParameterList(no_explicit_default_values, &func_params);
3054 // The field 'is_static' has no meaning for signature functions. 3084 // The field 'is_static' has no meaning for signature functions.
3055 Function& signature_function = Function::Handle( 3085 Function& signature_function = Function::Handle(
3056 Function::New(*alias_name, 3086 Function::New(*alias_name,
3057 RawFunction::kSignatureFunction, 3087 RawFunction::kSignatureFunction,
3058 /* is_static = */ false, 3088 /* is_static = */ false,
3059 /* is_const = */ false, 3089 /* is_const = */ false,
3090 /* is_external = */ false,
3060 alias_name_pos)); 3091 alias_name_pos));
3061 signature_function.set_owner(alias_owner); 3092 signature_function.set_owner(alias_owner);
3062 signature_function.set_result_type(result_type); 3093 signature_function.set_result_type(result_type);
3063 AddFormalParamsToFunction(&func_params, signature_function); 3094 AddFormalParamsToFunction(&func_params, signature_function);
3064 const String& signature = String::Handle(signature_function.Signature()); 3095 const String& signature = String::Handle(signature_function.Signature());
3065 if (FLAG_trace_parser) { 3096 if (FLAG_trace_parser) {
3066 OS::Print("TopLevel parsing function type alias '%s'\n", 3097 OS::Print("TopLevel parsing function type alias '%s'\n",
3067 signature.ToCString()); 3098 signature.ToCString());
3068 } 3099 }
3069 // Lookup the signature class, i.e. the class whose name is the signature. 3100 // Lookup the signature class, i.e. the class whose name is the signature.
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 field.set_value(Instance::Handle(Instance::null())); 3512 field.set_value(Instance::Handle(Instance::null()));
3482 top_level->fields.Add(field); 3513 top_level->fields.Add(field);
3483 library_.AddObject(field, var_name); 3514 library_.AddObject(field, var_name);
3484 if (CurrentToken() == Token::kASSIGN) { 3515 if (CurrentToken() == Token::kASSIGN) {
3485 ConsumeToken(); 3516 ConsumeToken();
3486 SkipExpr(); 3517 SkipExpr();
3487 field.set_value(Instance::Handle(Object::sentinel())); 3518 field.set_value(Instance::Handle(Object::sentinel()));
3488 // Create a static const getter. 3519 // Create a static const getter.
3489 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); 3520 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name));
3490 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter, 3521 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter,
3491 is_static, is_final, name_pos); 3522 is_static, is_final, false, name_pos);
3492 getter.set_result_type(type); 3523 getter.set_result_type(type);
3493 top_level->functions.Add(getter); 3524 top_level->functions.Add(getter);
3494 } else if (is_final || is_const) { 3525 } else if (is_final || is_const) {
3495 ErrorMsg(name_pos, "missing initializer for final or const variable"); 3526 ErrorMsg(name_pos, "missing initializer for final or const variable");
3496 } 3527 }
3497 3528
3498 if (CurrentToken() == Token::kCOMMA) { 3529 if (CurrentToken() == Token::kCOMMA) {
3499 ConsumeToken(); 3530 ConsumeToken();
3500 } else if (CurrentToken() == Token::kSEMICOLON) { 3531 } else if (CurrentToken() == Token::kSEMICOLON) {
3501 ConsumeToken(); 3532 ConsumeToken();
3502 break; 3533 break;
3503 } else { 3534 } else {
3504 ExpectSemicolon(); // Reports error. 3535 ExpectSemicolon(); // Reports error.
3505 } 3536 }
3506 } 3537 }
3507 } 3538 }
3508 3539
3509 3540
3510 void Parser::ParseTopLevelFunction(TopLevel* top_level) { 3541 void Parser::ParseTopLevelFunction(TopLevel* top_level) {
3511 TRACE_PARSER("ParseTopLevelFunction"); 3542 TRACE_PARSER("ParseTopLevelFunction");
3512 AbstractType& result_type = Type::Handle(Type::DynamicType()); 3543 AbstractType& result_type = Type::Handle(Type::DynamicType());
3513 const bool is_static = true; 3544 const bool is_static = true;
3545 bool is_external = false;
3546 if (CurrentToken() == Token::kEXTERNAL) {
3547 ConsumeToken();
3548 is_external = true;
3549 }
3514 if (CurrentToken() == Token::kVOID) { 3550 if (CurrentToken() == Token::kVOID) {
3515 ConsumeToken(); 3551 ConsumeToken();
3516 result_type = Type::VoidType(); 3552 result_type = Type::VoidType();
3517 } else { 3553 } else {
3518 // Parse optional type. 3554 // Parse optional type.
3519 if ((CurrentToken() == Token::kIDENT) && 3555 if ((CurrentToken() == Token::kIDENT) &&
3520 (LookaheadToken(1) != Token::kLPAREN)) { 3556 (LookaheadToken(1) != Token::kLPAREN)) {
3521 result_type = ParseType(ClassFinalizer::kTryResolve); 3557 result_type = ParseType(ClassFinalizer::kTryResolve);
3522 } 3558 }
3523 } 3559 }
(...skipping 16 matching lines...) Expand all
3540 3576
3541 if (CurrentToken() != Token::kLPAREN) { 3577 if (CurrentToken() != Token::kLPAREN) {
3542 ErrorMsg("'(' expected"); 3578 ErrorMsg("'(' expected");
3543 } 3579 }
3544 const intptr_t function_pos = TokenPos(); 3580 const intptr_t function_pos = TokenPos();
3545 ParamList params; 3581 ParamList params;
3546 const bool allow_explicit_default_values = true; 3582 const bool allow_explicit_default_values = true;
3547 ParseFormalParameterList(allow_explicit_default_values, &params); 3583 ParseFormalParameterList(allow_explicit_default_values, &params);
3548 3584
3549 intptr_t function_end_pos = function_pos; 3585 intptr_t function_end_pos = function_pos;
3550 if (CurrentToken() == Token::kLBRACE) { 3586 if (is_external) {
3587 ExpectSemicolon();
3588 } else if (CurrentToken() == Token::kLBRACE) {
3551 SkipBlock(); 3589 SkipBlock();
3552 function_end_pos = TokenPos(); 3590 function_end_pos = TokenPos();
3553 } else if (CurrentToken() == Token::kARROW) { 3591 } else if (CurrentToken() == Token::kARROW) {
3554 ConsumeToken(); 3592 ConsumeToken();
3555 SkipExpr(); 3593 SkipExpr();
3556 ExpectSemicolon(); 3594 ExpectSemicolon();
3557 function_end_pos = TokenPos(); 3595 function_end_pos = TokenPos();
3558 } else if (IsLiteral("native")) { 3596 } else if (IsLiteral("native")) {
3559 ParseNativeDeclaration(); 3597 ParseNativeDeclaration();
3560 } else { 3598 } else {
3561 ErrorMsg("function block expected"); 3599 ErrorMsg("function block expected");
3562 } 3600 }
3563 Function& func = Function::Handle( 3601 Function& func = Function::Handle(
3564 Function::New(func_name, RawFunction::kRegularFunction, 3602 Function::New(func_name, RawFunction::kRegularFunction,
3565 is_static, false, function_pos)); 3603 is_static, false, is_external, function_pos));
3566 func.set_result_type(result_type); 3604 func.set_result_type(result_type);
3567 func.set_end_token_pos(function_end_pos); 3605 func.set_end_token_pos(function_end_pos);
3568 AddFormalParamsToFunction(&params, func); 3606 AddFormalParamsToFunction(&params, func);
3569 top_level->functions.Add(func); 3607 top_level->functions.Add(func);
3570 library_.AddObject(func, func_name); 3608 library_.AddObject(func, func_name);
3571 } 3609 }
3572 3610
3573 3611
3574 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { 3612 void Parser::ParseTopLevelAccessor(TopLevel* top_level) {
3575 TRACE_PARSER("ParseTopLevelAccessor"); 3613 TRACE_PARSER("ParseTopLevelAccessor");
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 ExpectSemicolon(); 3675 ExpectSemicolon();
3638 } else if (IsLiteral("native")) { 3676 } else if (IsLiteral("native")) {
3639 ParseNativeDeclaration(); 3677 ParseNativeDeclaration();
3640 } else { 3678 } else {
3641 ErrorMsg("function block expected"); 3679 ErrorMsg("function block expected");
3642 } 3680 }
3643 Function& func = Function::Handle( 3681 Function& func = Function::Handle(
3644 Function::New(accessor_name, 3682 Function::New(accessor_name,
3645 is_getter? RawFunction::kGetterFunction : 3683 is_getter? RawFunction::kGetterFunction :
3646 RawFunction::kSetterFunction, 3684 RawFunction::kSetterFunction,
3647 is_static, false, accessor_pos)); 3685 is_static, false, false, accessor_pos));
3648 func.set_result_type(result_type); 3686 func.set_result_type(result_type);
3649 AddFormalParamsToFunction(&params, func); 3687 AddFormalParamsToFunction(&params, func);
3650 top_level->functions.Add(func); 3688 top_level->functions.Add(func);
3651 library_.AddObject(func, accessor_name); 3689 library_.AddObject(func, accessor_name);
3652 } 3690 }
3653 3691
3654 3692
3655 void Parser::ParseLibraryName() { 3693 void Parser::ParseLibraryName() {
3656 TRACE_PARSER("ParseLibraryName"); 3694 TRACE_PARSER("ParseLibraryName");
3657 if ((script_.kind() == RawScript::kLibraryTag) && 3695 if ((script_.kind() == RawScript::kLibraryTag) &&
(...skipping 848 matching lines...) Expand 10 before | Expand all | Expand 10 after
4506 } 4544 }
4507 SetPosition(saved_pos); 4545 SetPosition(saved_pos);
4508 return is_var_decl; 4546 return is_var_decl;
4509 } 4547 }
4510 4548
4511 4549
4512 // Look ahead to detect whether the next tokens should be parsed as 4550 // Look ahead to detect whether the next tokens should be parsed as
4513 // a function declaration. Token position remains unchanged. 4551 // a function declaration. Token position remains unchanged.
4514 bool Parser::IsFunctionDeclaration() { 4552 bool Parser::IsFunctionDeclaration() {
4515 const intptr_t saved_pos = TokenPos(); 4553 const intptr_t saved_pos = TokenPos();
4554 bool is_external = false;
4555 if (is_top_level_ && (CurrentToken() == Token::kEXTERNAL)) {
4556 // Skip over 'external' for top-level function declarations.
4557 is_external = true;
4558 ConsumeToken();
4559 }
4516 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { 4560 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
4517 // Possibly a function without explicit return type. 4561 // Possibly a function without explicit return type.
4518 ConsumeToken(); // Consume function identifier. 4562 ConsumeToken(); // Consume function identifier.
4519 } else if (TryParseReturnType()) { 4563 } else if (TryParseReturnType()) {
4520 if (!IsIdentifier()) { 4564 if (!IsIdentifier()) {
4521 SetPosition(saved_pos); 4565 SetPosition(saved_pos);
4522 return false; 4566 return false;
4523 } 4567 }
4524 ConsumeToken(); // Consume function identifier. 4568 ConsumeToken(); // Consume function identifier.
4525 } else { 4569 } else {
4526 SetPosition(saved_pos); 4570 SetPosition(saved_pos);
4527 return false; 4571 return false;
4528 } 4572 }
4529 // Check parameter list and the following token. 4573 // Check parameter list and the following token.
4530 if (CurrentToken() == Token::kLPAREN) { 4574 if (CurrentToken() == Token::kLPAREN) {
4531 SkipToMatchingParenthesis(); 4575 SkipToMatchingParenthesis();
4532 if ((CurrentToken() == Token::kLBRACE) || 4576 if ((CurrentToken() == Token::kLBRACE) ||
4533 (CurrentToken() == Token::kARROW) || 4577 (CurrentToken() == Token::kARROW) ||
4534 (is_top_level_ && IsLiteral("native"))) { 4578 (is_top_level_ && IsLiteral("native")) ||
4579 is_external) {
4535 SetPosition(saved_pos); 4580 SetPosition(saved_pos);
4536 return true; 4581 return true;
4537 } 4582 }
4538 } 4583 }
4539 SetPosition(saved_pos); 4584 SetPosition(saved_pos);
4540 return false; 4585 return false;
4541 } 4586 }
4542 4587
4543 4588
4544 bool Parser::IsTopLevelAccessor() { 4589 bool Parser::IsTopLevelAccessor() {
(...skipping 4194 matching lines...) Expand 10 before | Expand all | Expand 10 after
8739 void Parser::SkipQualIdent() { 8784 void Parser::SkipQualIdent() {
8740 ASSERT(IsIdentifier()); 8785 ASSERT(IsIdentifier());
8741 ConsumeToken(); 8786 ConsumeToken();
8742 if (CurrentToken() == Token::kPERIOD) { 8787 if (CurrentToken() == Token::kPERIOD) {
8743 ConsumeToken(); // Consume the kPERIOD token. 8788 ConsumeToken(); // Consume the kPERIOD token.
8744 ExpectIdentifier("identifier expected after '.'"); 8789 ExpectIdentifier("identifier expected after '.'");
8745 } 8790 }
8746 } 8791 }
8747 8792
8748 } // namespace dart 8793 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object_test.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698