| 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 2421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2432 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); | 2432 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); |
| 2433 } | 2433 } |
| 2434 if (method->has_final) { | 2434 if (method->has_final) { |
| 2435 ErrorMsg(method->name_pos, "'final' not allowed for methods"); | 2435 ErrorMsg(method->name_pos, "'final' not allowed for methods"); |
| 2436 } | 2436 } |
| 2437 if (method->has_abstract && method->has_static) { | 2437 if (method->has_abstract && method->has_static) { |
| 2438 ErrorMsg(method->name_pos, | 2438 ErrorMsg(method->name_pos, |
| 2439 "static method '%s' cannot be abstract", | 2439 "static method '%s' cannot be abstract", |
| 2440 method->name->ToCString()); | 2440 method->name->ToCString()); |
| 2441 } | 2441 } |
| 2442 if (method->has_const && !(method->IsConstructor() || method->IsFactory())) { | 2442 if (method->has_const && !method->IsFactoryOrConstructor()) { |
| 2443 ErrorMsg(method->name_pos, "'const' not allowed for methods"); | 2443 ErrorMsg(method->name_pos, "'const' not allowed for methods"); |
| 2444 } | 2444 } |
| 2445 if (method->IsFactoryOrConstructor() && method->has_abstract) { | 2445 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
| 2446 ErrorMsg(method->name_pos, "constructor cannot be abstract"); | 2446 ErrorMsg(method->name_pos, "constructor cannot be abstract"); |
| 2447 } | 2447 } |
| 2448 if (method->IsConstructor() && method->has_const) { | 2448 if (method->has_const && method->IsConstructor()) { |
| 2449 Class& cls = Class::Handle(library_.LookupClass(members->class_name())); | 2449 Class& cls = Class::Handle(library_.LookupClass(members->class_name())); |
| 2450 cls.set_is_const(); | 2450 cls.set_is_const(); |
| 2451 } | 2451 } |
| 2452 if (method->has_abstract && members->is_interface()) { | 2452 if (method->has_abstract && members->is_interface()) { |
| 2453 ErrorMsg(method->name_pos, | 2453 ErrorMsg(method->name_pos, |
| 2454 "'abstract' method only allowed in class definition"); | 2454 "'abstract' method only allowed in class definition"); |
| 2455 } | 2455 } |
| 2456 if (method->has_external && members->is_interface()) { | 2456 if (method->has_external && members->is_interface()) { |
| 2457 ErrorMsg(method->name_pos, | 2457 ErrorMsg(method->name_pos, |
| 2458 "'external' method only allowed in class definition"); | 2458 "'external' method only allowed in class definition"); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2605 if ((CurrentToken() == Token::kLBRACE) || | 2605 if ((CurrentToken() == Token::kLBRACE) || |
| 2606 (CurrentToken() == Token::kARROW)) { | 2606 (CurrentToken() == Token::kARROW)) { |
| 2607 if (method->has_abstract) { | 2607 if (method->has_abstract) { |
| 2608 ErrorMsg(method->name_pos, | 2608 ErrorMsg(method->name_pos, |
| 2609 "abstract method '%s' may not have a function body", | 2609 "abstract method '%s' may not have a function body", |
| 2610 method->name->ToCString()); | 2610 method->name->ToCString()); |
| 2611 } else if (method->has_external) { | 2611 } else if (method->has_external) { |
| 2612 ErrorMsg(method->name_pos, | 2612 ErrorMsg(method->name_pos, |
| 2613 "external method '%s' may not have a function body", | 2613 "external method '%s' may not have a function body", |
| 2614 method->name->ToCString()); | 2614 method->name->ToCString()); |
| 2615 } else if (method->IsConstructor() && method->has_const) { | 2615 } else if (method->IsFactoryOrConstructor() && method->has_const) { |
| 2616 ErrorMsg(method->name_pos, | 2616 ErrorMsg(method->name_pos, |
| 2617 "const constructor '%s' may not have a function body", | 2617 "const constructor or factory '%s' may not have a function body", |
| 2618 method->name->ToCString()); | |
| 2619 } else if (method->IsFactory() && method->has_const) { | |
| 2620 ErrorMsg(method->name_pos, | |
| 2621 "const factory '%s' may not have a function body", | |
| 2622 method->name->ToCString()); | 2618 method->name->ToCString()); |
| 2623 } else if (members->is_interface()) { | 2619 } else if (members->is_interface()) { |
| 2624 ErrorMsg(method->name_pos, | 2620 ErrorMsg(method->name_pos, |
| 2625 "function body not allowed in interface declaration"); | 2621 "function body not allowed in interface declaration"); |
| 2626 } | 2622 } |
| 2627 if (method->redirect_name != NULL) { | 2623 if (method->redirect_name != NULL) { |
| 2628 ErrorMsg(method->name_pos, | 2624 ErrorMsg(method->name_pos, |
| 2629 "Constructor with redirection may not have a function body"); | 2625 "Constructor with redirection may not have a function body"); |
| 2630 } | 2626 } |
| 2631 if (CurrentToken() == Token::kLBRACE) { | 2627 if (CurrentToken() == Token::kLBRACE) { |
| 2632 SkipBlock(); | 2628 SkipBlock(); |
| 2633 } else { | 2629 } else { |
| 2634 ConsumeToken(); | 2630 ConsumeToken(); |
| 2635 SkipExpr(); | 2631 SkipExpr(); |
| 2636 ExpectSemicolon(); | 2632 ExpectSemicolon(); |
| 2637 } | 2633 } |
| 2638 method_end_pos = TokenPos(); | 2634 method_end_pos = TokenPos(); |
| 2639 } else if (IsLiteral("native")) { | 2635 } else if (IsLiteral("native")) { |
| 2640 if (method->has_abstract) { | 2636 if (method->has_abstract) { |
| 2641 ErrorMsg(method->name_pos, | 2637 ErrorMsg(method->name_pos, |
| 2642 "abstract method '%s' may not have a function body", | 2638 "abstract method '%s' may not have a function body", |
| 2643 method->name->ToCString()); | 2639 method->name->ToCString()); |
| 2644 } else if (members->is_interface()) { | 2640 } else if (members->is_interface()) { |
| 2645 ErrorMsg(method->name_pos, | 2641 ErrorMsg(method->name_pos, |
| 2646 "function body not allowed in interface declaration"); | 2642 "function body not allowed in interface declaration"); |
| 2647 } else if (method->IsConstructor() && method->has_const) { | 2643 } else if (method->IsFactoryOrConstructor() && method->has_const) { |
| 2648 ErrorMsg(method->name_pos, | 2644 ErrorMsg(method->name_pos, |
| 2649 "const constructor '%s' may not have a function body", | 2645 "const constructor or factory '%s' may not be native", |
| 2650 method->name->ToCString()); | 2646 method->name->ToCString()); |
| 2651 } | 2647 } |
| 2652 if (method->redirect_name != NULL) { | 2648 if (method->redirect_name != NULL) { |
| 2653 ErrorMsg(method->name_pos, | 2649 ErrorMsg(method->name_pos, |
| 2654 "Constructor with redirection may not have a function body"); | 2650 "Constructor with redirection may not have a function body"); |
| 2655 } | 2651 } |
| 2656 ParseNativeDeclaration(); | 2652 ParseNativeDeclaration(); |
| 2657 } else { | 2653 } else { |
| 2658 // We haven't found a method body. Issue error if one is required. | 2654 // We haven't found a method body. Issue error if one is required. |
| 2659 const bool must_have_body = | 2655 const bool must_have_body = |
| (...skipping 5433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8093 | 8089 |
| 8094 | 8090 |
| 8095 RawObject* Parser::EvaluateConstConstructorCall( | 8091 RawObject* Parser::EvaluateConstConstructorCall( |
| 8096 const Class& type_class, | 8092 const Class& type_class, |
| 8097 const AbstractTypeArguments& type_arguments, | 8093 const AbstractTypeArguments& type_arguments, |
| 8098 const Function& constructor, | 8094 const Function& constructor, |
| 8099 ArgumentListNode* arguments) { | 8095 ArgumentListNode* arguments) { |
| 8100 // +2 for implicit receiver and construction phase arguments. | 8096 // +2 for implicit receiver and construction phase arguments. |
| 8101 GrowableArray<const Object*> arg_values(arguments->length() + 2); | 8097 GrowableArray<const Object*> arg_values(arguments->length() + 2); |
| 8102 Instance& instance = Instance::Handle(); | 8098 Instance& instance = Instance::Handle(); |
| 8103 if (!constructor.IsFactory()) { | 8099 ASSERT(!constructor.IsFactory()); |
| 8104 instance = Instance::New(type_class, Heap::kOld); | 8100 instance = Instance::New(type_class, Heap::kOld); |
| 8105 if (!type_arguments.IsNull()) { | 8101 if (!type_arguments.IsNull()) { |
| 8106 if (!type_arguments.IsInstantiated()) { | 8102 if (!type_arguments.IsInstantiated()) { |
| 8107 ErrorMsg("type must be constant in const constructor"); | 8103 ErrorMsg("type must be constant in const constructor"); |
| 8108 } | |
| 8109 instance.SetTypeArguments( | |
| 8110 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); | |
| 8111 } | 8104 } |
| 8112 arg_values.Add(&instance); | 8105 instance.SetTypeArguments( |
| 8113 arg_values.Add(&Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); | 8106 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); |
| 8114 } else { | |
| 8115 // Prepend type_arguments to list of arguments to factory. | |
| 8116 ASSERT(type_arguments.IsZoneHandle()); | |
| 8117 arg_values.Add(&type_arguments); | |
| 8118 } | 8107 } |
| 8108 arg_values.Add(&instance); |
| 8109 arg_values.Add(&Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))); |
| 8119 for (int i = 0; i < arguments->length(); i++) { | 8110 for (int i = 0; i < arguments->length(); i++) { |
| 8120 AstNode* arg = arguments->NodeAt(i); | 8111 AstNode* arg = arguments->NodeAt(i); |
| 8121 // Arguments have been evaluated to a literal value already. | 8112 // Arguments have been evaluated to a literal value already. |
| 8122 ASSERT(arg->IsLiteralNode()); | 8113 ASSERT(arg->IsLiteralNode()); |
| 8123 arg_values.Add(&arg->AsLiteralNode()->literal()); | 8114 arg_values.Add(&arg->AsLiteralNode()->literal()); |
| 8124 } | 8115 } |
| 8125 const Array& opt_arg_names = arguments->names(); | 8116 const Array& opt_arg_names = arguments->names(); |
| 8126 const Object& result = Object::Handle( | 8117 const Object& result = Object::Handle( |
| 8127 DartEntry::InvokeStatic(constructor, arg_values, opt_arg_names)); | 8118 DartEntry::InvokeStatic(constructor, arg_values, opt_arg_names)); |
| 8128 if (result.IsError()) { | 8119 if (result.IsError()) { |
| 8129 if (result.IsUnhandledException()) { | 8120 if (result.IsUnhandledException()) { |
| 8130 return result.raw(); | 8121 return result.raw(); |
| 8131 } else { | 8122 } else { |
| 8132 Isolate::Current()->long_jump_base()->Jump(1, Error::Cast(result)); | 8123 Isolate::Current()->long_jump_base()->Jump(1, Error::Cast(result)); |
| 8133 UNREACHABLE(); | 8124 UNREACHABLE(); |
| 8134 return Object::null(); | 8125 return Object::null(); |
| 8135 } | 8126 } |
| 8136 } else { | 8127 } else { |
| 8137 if (constructor.IsFactory()) { | |
| 8138 // The factory method returns the allocated object. | |
| 8139 instance ^= result.raw(); | |
| 8140 } | |
| 8141 if (!instance.IsNull()) { | 8128 if (!instance.IsNull()) { |
| 8142 instance ^= instance.Canonicalize(); | 8129 instance ^= instance.Canonicalize(); |
| 8143 } | 8130 } |
| 8144 return instance.raw(); | 8131 return instance.raw(); |
| 8145 } | 8132 } |
| 8146 } | 8133 } |
| 8147 | 8134 |
| 8148 | 8135 |
| 8149 // Do a lookup for the identifier in the block scope and the class scope | 8136 // Do a lookup for the identifier in the block scope and the class scope |
| 8150 // return true if the identifier is found, false otherwise. | 8137 // return true if the identifier is found, false otherwise. |
| (...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10011 void Parser::SkipQualIdent() { | 9998 void Parser::SkipQualIdent() { |
| 10012 ASSERT(IsIdentifier()); | 9999 ASSERT(IsIdentifier()); |
| 10013 ConsumeToken(); | 10000 ConsumeToken(); |
| 10014 if (CurrentToken() == Token::kPERIOD) { | 10001 if (CurrentToken() == Token::kPERIOD) { |
| 10015 ConsumeToken(); // Consume the kPERIOD token. | 10002 ConsumeToken(); // Consume the kPERIOD token. |
| 10016 ExpectIdentifier("identifier expected after '.'"); | 10003 ExpectIdentifier("identifier expected after '.'"); |
| 10017 } | 10004 } |
| 10018 } | 10005 } |
| 10019 | 10006 |
| 10020 } // namespace dart | 10007 } // namespace dart |
| OLD | NEW |