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 3167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3178 if ((CurrentToken() == Token::kLBRACE) || | 3178 if ((CurrentToken() == Token::kLBRACE) || |
3179 (CurrentToken() == Token::kARROW)) { | 3179 (CurrentToken() == Token::kARROW)) { |
3180 if (method->has_abstract) { | 3180 if (method->has_abstract) { |
3181 ErrorMsg(method->name_pos, | 3181 ErrorMsg(method->name_pos, |
3182 "abstract method '%s' may not have a function body", | 3182 "abstract method '%s' may not have a function body", |
3183 method->name->ToCString()); | 3183 method->name->ToCString()); |
3184 } else if (method->has_external) { | 3184 } else if (method->has_external) { |
3185 ErrorMsg(method->name_pos, | 3185 ErrorMsg(method->name_pos, |
3186 "external method '%s' may not have a function body", | 3186 "external method '%s' may not have a function body", |
3187 method->name->ToCString()); | 3187 method->name->ToCString()); |
3188 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3188 } else if (method->IsConstructor() && method->has_const) { |
3189 ErrorMsg(method->name_pos, | 3189 ErrorMsg(method->name_pos, |
3190 "const constructor or factory '%s' may not have a function body", | 3190 "const constructor '%s' may not have a function body", |
| 3191 method->name->ToCString()); |
| 3192 } else if (method->IsFactory() && method->has_const) { |
| 3193 ErrorMsg(method->name_pos, |
| 3194 "const factory '%s' may not have a function body", |
3191 method->name->ToCString()); | 3195 method->name->ToCString()); |
3192 } | 3196 } |
3193 if (method->redirect_name != NULL) { | 3197 if (method->redirect_name != NULL) { |
3194 ErrorMsg(method->name_pos, | 3198 ErrorMsg(method->name_pos, |
3195 "Constructor with redirection may not have a function body"); | 3199 "Constructor with redirection may not have a function body"); |
3196 } | 3200 } |
3197 if (CurrentToken() == Token::kLBRACE) { | 3201 if (CurrentToken() == Token::kLBRACE) { |
3198 SkipBlock(); | 3202 SkipBlock(); |
3199 method_end_pos = TokenPos(); | 3203 method_end_pos = TokenPos(); |
3200 ExpectToken(Token::kRBRACE); | 3204 ExpectToken(Token::kRBRACE); |
3201 } else { | 3205 } else { |
3202 ConsumeToken(); | 3206 ConsumeToken(); |
3203 SkipExpr(); | 3207 SkipExpr(); |
3204 method_end_pos = TokenPos(); | 3208 method_end_pos = TokenPos(); |
3205 ExpectSemicolon(); | 3209 ExpectSemicolon(); |
3206 } | 3210 } |
3207 } else if (IsLiteral("native")) { | 3211 } else if (IsLiteral("native")) { |
3208 if (method->has_abstract) { | 3212 if (method->has_abstract) { |
3209 ErrorMsg(method->name_pos, | 3213 ErrorMsg(method->name_pos, |
3210 "abstract method '%s' may not have a function body", | 3214 "abstract method '%s' may not have a function body", |
3211 method->name->ToCString()); | 3215 method->name->ToCString()); |
3212 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3216 } else if (method->IsConstructor() && method->has_const) { |
3213 ErrorMsg(method->name_pos, | 3217 ErrorMsg(method->name_pos, |
3214 "const constructor or factory '%s' may not be native", | 3218 "const constructor '%s' may not be native", |
3215 method->name->ToCString()); | 3219 method->name->ToCString()); |
3216 } | 3220 } |
3217 if (method->redirect_name != NULL) { | 3221 if (method->redirect_name != NULL) { |
3218 ErrorMsg(method->name_pos, | 3222 ErrorMsg(method->name_pos, |
3219 "Constructor with redirection may not have a function body"); | 3223 "Constructor with redirection may not have a function body"); |
3220 } | 3224 } |
3221 ParseNativeDeclaration(); | 3225 ParseNativeDeclaration(); |
3222 method_end_pos = TokenPos(); | 3226 method_end_pos = TokenPos(); |
3223 ExpectSemicolon(); | 3227 ExpectSemicolon(); |
3224 } else { | 3228 } else { |
(...skipping 5539 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 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9928 external_constructor_name.ToCString()); | 9943 external_constructor_name.ToCString()); |
9929 } | 9944 } |
9930 const Object& constructor_result = Object::Handle( | 9945 const Object& constructor_result = Object::Handle( |
9931 EvaluateConstConstructorCall(type_class, | 9946 EvaluateConstConstructorCall(type_class, |
9932 type_arguments, | 9947 type_arguments, |
9933 constructor, | 9948 constructor, |
9934 arguments)); | 9949 arguments)); |
9935 if (constructor_result.IsUnhandledException()) { | 9950 if (constructor_result.IsUnhandledException()) { |
9936 new_object = GenerateRethrow(new_pos, constructor_result); | 9951 new_object = GenerateRethrow(new_pos, constructor_result); |
9937 } else { | 9952 } else { |
9938 const Instance& const_instance = Instance::Cast(constructor_result); | 9953 // Const constructors can return null in the case where a const native |
| 9954 // factory returns a null value. Thus we cannot use a Instance::Cast here. |
| 9955 Instance& const_instance = Instance::Handle(); |
| 9956 const_instance ^= constructor_result.raw(); |
9939 new_object = new LiteralNode(new_pos, | 9957 new_object = new LiteralNode(new_pos, |
9940 Instance::ZoneHandle(const_instance.raw())); | 9958 Instance::ZoneHandle(const_instance.raw())); |
9941 if (!type_bound.IsNull()) { | 9959 if (!type_bound.IsNull()) { |
9942 ASSERT(!type_bound.IsMalformed()); | 9960 ASSERT(!type_bound.IsMalformed()); |
9943 Error& malformed_error = Error::Handle(); | 9961 Error& malformed_error = Error::Handle(); |
9944 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9962 ASSERT(!is_top_level_); // We cannot check unresolved types. |
9945 if (!const_instance.IsInstanceOf(type_bound, | 9963 if (!const_instance.IsInstanceOf(type_bound, |
9946 TypeArguments::Handle(), | 9964 TypeArguments::Handle(), |
9947 &malformed_error)) { | 9965 &malformed_error)) { |
9948 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 9966 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10603 void Parser::SkipQualIdent() { | 10621 void Parser::SkipQualIdent() { |
10604 ASSERT(IsIdentifier()); | 10622 ASSERT(IsIdentifier()); |
10605 ConsumeToken(); | 10623 ConsumeToken(); |
10606 if (CurrentToken() == Token::kPERIOD) { | 10624 if (CurrentToken() == Token::kPERIOD) { |
10607 ConsumeToken(); // Consume the kPERIOD token. | 10625 ConsumeToken(); // Consume the kPERIOD token. |
10608 ExpectIdentifier("identifier expected after '.'"); | 10626 ExpectIdentifier("identifier expected after '.'"); |
10609 } | 10627 } |
10610 } | 10628 } |
10611 | 10629 |
10612 } // namespace dart | 10630 } // namespace dart |
OLD | NEW |