OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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(¶ms, func); | 2172 ParseNativeFunctionBlock(¶ms, 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¶ms, getter); | 2585 AddFormalParamsToFunction(¶ms, 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(¶ms, setter); | 2599 AddFormalParamsToFunction(¶ms, setter); |
2576 members->AddFunction(setter); | 2600 members->AddFunction(setter); |
2577 } | 2601 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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, ¶ms); | 3583 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
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(¶ms, func); | 3606 AddFormalParamsToFunction(¶ms, 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 Loading... |
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(¶ms, func); | 3687 AddFormalParamsToFunction(¶ms, 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 Loading... |
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 Loading... |
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 |
OLD | NEW |