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 |