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 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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(¶ms, func); | 2170 ParseNativeFunctionBlock(¶ms, 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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(¶ms, getter); | 2569 AddFormalParamsToFunction(¶ms, 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(¶ms, setter); | 2583 AddFormalParamsToFunction(¶ms, setter); |
2563 members->AddFunction(setter); | 2584 members->AddFunction(setter); |
2564 } | 2585 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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, ¶ms); | 3560 ParseFormalParameterList(allow_explicit_default_values, ¶ms); |
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(¶ms, func); | 3583 AddFormalParamsToFunction(¶ms, 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 Loading... | |
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(¶ms, func); | 3664 AddFormalParamsToFunction(¶ms, 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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |