| 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 3177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3188 if ((CurrentToken() == Token::kLBRACE) || | 3188 if ((CurrentToken() == Token::kLBRACE) || |
| 3189 (CurrentToken() == Token::kARROW)) { | 3189 (CurrentToken() == Token::kARROW)) { |
| 3190 if (method->has_abstract) { | 3190 if (method->has_abstract) { |
| 3191 ErrorMsg(method->name_pos, | 3191 ErrorMsg(method->name_pos, |
| 3192 "abstract method '%s' may not have a function body", | 3192 "abstract method '%s' may not have a function body", |
| 3193 method->name->ToCString()); | 3193 method->name->ToCString()); |
| 3194 } else if (method->has_external) { | 3194 } else if (method->has_external) { |
| 3195 ErrorMsg(method->name_pos, | 3195 ErrorMsg(method->name_pos, |
| 3196 "external method '%s' may not have a function body", | 3196 "external method '%s' may not have a function body", |
| 3197 method->name->ToCString()); | 3197 method->name->ToCString()); |
| 3198 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3198 } else if (method->IsConstructor() && method->has_const) { |
| 3199 ErrorMsg(method->name_pos, | 3199 ErrorMsg(method->name_pos, |
| 3200 "const constructor or factory '%s' may not have a function body", | 3200 "const constructor '%s' may not have a function body", |
| 3201 method->name->ToCString()); |
| 3202 } else if (method->IsFactory() && method->has_const) { |
| 3203 ErrorMsg(method->name_pos, |
| 3204 "const factory '%s' may not have a function body", |
| 3201 method->name->ToCString()); | 3205 method->name->ToCString()); |
| 3202 } | 3206 } |
| 3203 if (method->redirect_name != NULL) { | 3207 if (method->redirect_name != NULL) { |
| 3204 ErrorMsg(method->name_pos, | 3208 ErrorMsg(method->name_pos, |
| 3205 "Constructor with redirection may not have a function body"); | 3209 "Constructor with redirection may not have a function body"); |
| 3206 } | 3210 } |
| 3207 if (CurrentToken() == Token::kLBRACE) { | 3211 if (CurrentToken() == Token::kLBRACE) { |
| 3208 SkipBlock(); | 3212 SkipBlock(); |
| 3209 method_end_pos = TokenPos(); | 3213 method_end_pos = TokenPos(); |
| 3210 ExpectToken(Token::kRBRACE); | 3214 ExpectToken(Token::kRBRACE); |
| 3211 } else { | 3215 } else { |
| 3212 ConsumeToken(); | 3216 ConsumeToken(); |
| 3213 SkipExpr(); | 3217 SkipExpr(); |
| 3214 method_end_pos = TokenPos(); | 3218 method_end_pos = TokenPos(); |
| 3215 ExpectSemicolon(); | 3219 ExpectSemicolon(); |
| 3216 } | 3220 } |
| 3217 } else if (IsLiteral("native")) { | 3221 } else if (IsLiteral("native")) { |
| 3218 if (method->has_abstract) { | 3222 if (method->has_abstract) { |
| 3219 ErrorMsg(method->name_pos, | 3223 ErrorMsg(method->name_pos, |
| 3220 "abstract method '%s' may not have a function body", | 3224 "abstract method '%s' may not have a function body", |
| 3221 method->name->ToCString()); | 3225 method->name->ToCString()); |
| 3222 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3226 } else if (method->IsConstructor() && method->has_const) { |
| 3223 ErrorMsg(method->name_pos, | 3227 ErrorMsg(method->name_pos, |
| 3224 "const constructor or factory '%s' may not be native", | 3228 "const constructor '%s' may not be native", |
| 3225 method->name->ToCString()); | 3229 method->name->ToCString()); |
| 3226 } | 3230 } |
| 3227 if (method->redirect_name != NULL) { | 3231 if (method->redirect_name != NULL) { |
| 3228 ErrorMsg(method->name_pos, | 3232 ErrorMsg(method->name_pos, |
| 3229 "Constructor with redirection may not have a function body"); | 3233 "Constructor with redirection may not have a function body"); |
| 3230 } | 3234 } |
| 3231 ParseNativeDeclaration(); | 3235 ParseNativeDeclaration(); |
| 3232 method_end_pos = TokenPos(); | 3236 method_end_pos = TokenPos(); |
| 3233 ExpectSemicolon(); | 3237 ExpectSemicolon(); |
| 3234 } else { | 3238 } else { |
| (...skipping 5529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8764 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 8768 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
| 8765 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); | 8769 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); |
| 8766 } | 8770 } |
| 8767 | 8771 |
| 8768 | 8772 |
| 8769 RawObject* Parser::EvaluateConstConstructorCall( | 8773 RawObject* Parser::EvaluateConstConstructorCall( |
| 8770 const Class& type_class, | 8774 const Class& type_class, |
| 8771 const AbstractTypeArguments& type_arguments, | 8775 const AbstractTypeArguments& type_arguments, |
| 8772 const Function& constructor, | 8776 const Function& constructor, |
| 8773 ArgumentListNode* arguments) { | 8777 ArgumentListNode* arguments) { |
| 8774 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. | 8778 // Factories have one extra argument: the type arguments. |
| 8779 // Constructors have 2 extra arguments: rcvr and construction phase. |
| 8780 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; |
| 8775 const int num_arguments = arguments->length() + kNumExtraArgs; | 8781 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 8776 const Array& arg_values = Array::Handle(Array::New(num_arguments)); | 8782 const Array& arg_values = Array::Handle(Array::New(num_arguments)); |
| 8777 Instance& instance = Instance::Handle(); | 8783 Instance& instance = Instance::Handle(); |
| 8778 ASSERT(!constructor.IsFactory()); | 8784 if (!constructor.IsFactory()) { |
| 8779 instance = Instance::New(type_class, Heap::kOld); | 8785 instance = Instance::New(type_class, Heap::kOld); |
| 8780 if (!type_arguments.IsNull()) { | 8786 if (!type_arguments.IsNull()) { |
| 8781 if (!type_arguments.IsInstantiated()) { | 8787 if (!type_arguments.IsInstantiated()) { |
| 8782 ErrorMsg("type must be constant in const constructor"); | 8788 ErrorMsg("type must be constant in const constructor"); |
| 8789 } |
| 8790 instance.SetTypeArguments( |
| 8791 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); |
| 8783 } | 8792 } |
| 8784 instance.SetTypeArguments( | 8793 arg_values.SetAt(0, instance); |
| 8785 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); | 8794 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 8795 } else { |
| 8796 // Prepend type_arguments to list of arguments to factory. |
| 8797 ASSERT(type_arguments.IsZoneHandle()); |
| 8798 arg_values.SetAt(0, type_arguments); |
| 8786 } | 8799 } |
| 8787 arg_values.SetAt(0, instance); | |
| 8788 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | |
| 8789 for (int i = 0; i < arguments->length(); i++) { | 8800 for (int i = 0; i < arguments->length(); i++) { |
| 8790 AstNode* arg = arguments->NodeAt(i); | 8801 AstNode* arg = arguments->NodeAt(i); |
| 8791 // Arguments have been evaluated to a literal value already. | 8802 // Arguments have been evaluated to a literal value already. |
| 8792 ASSERT(arg->IsLiteralNode()); | 8803 ASSERT(arg->IsLiteralNode()); |
| 8793 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 8804 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
| 8794 } | 8805 } |
| 8795 const Array& args_descriptor = | 8806 const Array& args_descriptor = |
| 8796 Array::Handle(ArgumentsDescriptor::New(num_arguments, | 8807 Array::Handle(ArgumentsDescriptor::New(num_arguments, |
| 8797 arguments->names())); | 8808 arguments->names())); |
| 8798 const Object& result = | 8809 const Object& result = |
| 8799 Object::Handle(DartEntry::InvokeFunction(constructor, | 8810 Object::Handle(DartEntry::InvokeFunction(constructor, |
| 8800 arg_values, | 8811 arg_values, |
| 8801 args_descriptor)); | 8812 args_descriptor)); |
| 8802 if (result.IsError()) { | 8813 if (result.IsError()) { |
| 8803 // An exception may not occur in every parse attempt, i.e., the | 8814 // An exception may not occur in every parse attempt, i.e., the |
| 8804 // generated AST is not deterministic. Therefore mark the function as | 8815 // generated AST is not deterministic. Therefore mark the function as |
| 8805 // not optimizable. | 8816 // not optimizable. |
| 8806 current_function().set_is_optimizable(false); | 8817 current_function().set_is_optimizable(false); |
| 8807 if (result.IsUnhandledException()) { | 8818 if (result.IsUnhandledException()) { |
| 8808 return result.raw(); | 8819 return result.raw(); |
| 8809 } else { | 8820 } else { |
| 8810 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 8821 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); |
| 8811 UNREACHABLE(); | 8822 UNREACHABLE(); |
| 8812 return Object::null(); | 8823 return Object::null(); |
| 8813 } | 8824 } |
| 8814 } else { | 8825 } else { |
| 8826 if (constructor.IsFactory()) { |
| 8827 // The factory method returns the allocated object. |
| 8828 instance ^= result.raw(); |
| 8829 } |
| 8815 return TryCanonicalize(instance, TokenPos()); | 8830 return TryCanonicalize(instance, TokenPos()); |
| 8816 } | 8831 } |
| 8817 } | 8832 } |
| 8818 | 8833 |
| 8819 | 8834 |
| 8820 // Do a lookup for the identifier in the block scope and the class scope | 8835 // Do a lookup for the identifier in the block scope and the class scope |
| 8821 // return true if the identifier is found, false otherwise. | 8836 // return true if the identifier is found, false otherwise. |
| 8822 // If node is non NULL return an AST node corresponding to the identifier. | 8837 // If node is non NULL return an AST node corresponding to the identifier. |
| 8823 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 8838 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
| 8824 const String &ident, | 8839 const String &ident, |
| (...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9940 external_constructor_name.ToCString()); | 9955 external_constructor_name.ToCString()); |
| 9941 } | 9956 } |
| 9942 const Object& constructor_result = Object::Handle( | 9957 const Object& constructor_result = Object::Handle( |
| 9943 EvaluateConstConstructorCall(type_class, | 9958 EvaluateConstConstructorCall(type_class, |
| 9944 type_arguments, | 9959 type_arguments, |
| 9945 constructor, | 9960 constructor, |
| 9946 arguments)); | 9961 arguments)); |
| 9947 if (constructor_result.IsUnhandledException()) { | 9962 if (constructor_result.IsUnhandledException()) { |
| 9948 new_object = GenerateRethrow(new_pos, constructor_result); | 9963 new_object = GenerateRethrow(new_pos, constructor_result); |
| 9949 } else { | 9964 } else { |
| 9950 const Instance& const_instance = Instance::Cast(constructor_result); | 9965 // Const constructors can return null in the case where a const native |
| 9966 // factory returns a null value. Thus we cannot use a Instance::Cast here. |
| 9967 Instance& const_instance = Instance::Handle(); |
| 9968 const_instance ^= constructor_result.raw(); |
| 9951 new_object = new LiteralNode(new_pos, | 9969 new_object = new LiteralNode(new_pos, |
| 9952 Instance::ZoneHandle(const_instance.raw())); | 9970 Instance::ZoneHandle(const_instance.raw())); |
| 9953 if (!type_bound.IsNull()) { | 9971 if (!type_bound.IsNull()) { |
| 9954 ASSERT(!type_bound.IsMalformed()); | 9972 ASSERT(!type_bound.IsMalformed()); |
| 9955 Error& malformed_error = Error::Handle(); | 9973 Error& malformed_error = Error::Handle(); |
| 9956 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9974 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 9957 if (!const_instance.IsInstanceOf(type_bound, | 9975 if (!const_instance.IsInstanceOf(type_bound, |
| 9958 TypeArguments::Handle(), | 9976 TypeArguments::Handle(), |
| 9959 &malformed_error)) { | 9977 &malformed_error)) { |
| 9960 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 9978 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
| (...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10619 void Parser::SkipQualIdent() { | 10637 void Parser::SkipQualIdent() { |
| 10620 ASSERT(IsIdentifier()); | 10638 ASSERT(IsIdentifier()); |
| 10621 ConsumeToken(); | 10639 ConsumeToken(); |
| 10622 if (CurrentToken() == Token::kPERIOD) { | 10640 if (CurrentToken() == Token::kPERIOD) { |
| 10623 ConsumeToken(); // Consume the kPERIOD token. | 10641 ConsumeToken(); // Consume the kPERIOD token. |
| 10624 ExpectIdentifier("identifier expected after '.'"); | 10642 ExpectIdentifier("identifier expected after '.'"); |
| 10625 } | 10643 } |
| 10626 } | 10644 } |
| 10627 | 10645 |
| 10628 } // namespace dart | 10646 } // namespace dart |
| OLD | NEW |