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 3086 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3097 if ((CurrentToken() == Token::kLBRACE) || | 3097 if ((CurrentToken() == Token::kLBRACE) || |
3098 (CurrentToken() == Token::kARROW)) { | 3098 (CurrentToken() == Token::kARROW)) { |
3099 if (method->has_abstract) { | 3099 if (method->has_abstract) { |
3100 ErrorMsg(method->name_pos, | 3100 ErrorMsg(method->name_pos, |
3101 "abstract method '%s' may not have a function body", | 3101 "abstract method '%s' may not have a function body", |
3102 method->name->ToCString()); | 3102 method->name->ToCString()); |
3103 } else if (method->has_external) { | 3103 } else if (method->has_external) { |
3104 ErrorMsg(method->name_pos, | 3104 ErrorMsg(method->name_pos, |
3105 "external method '%s' may not have a function body", | 3105 "external method '%s' may not have a function body", |
3106 method->name->ToCString()); | 3106 method->name->ToCString()); |
3107 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3107 } else if (method->IsConstructor() && method->has_const) { |
3108 ErrorMsg(method->name_pos, | 3108 ErrorMsg(method->name_pos, |
3109 "const constructor or factory '%s' may not have a function body", | 3109 "const constructor '%s' may not have a function body", |
| 3110 method->name->ToCString()); |
| 3111 } else if (method->IsFactory() && method->has_const) { |
| 3112 ErrorMsg(method->name_pos, |
| 3113 "const factory '%s' may not have a function body", |
3110 method->name->ToCString()); | 3114 method->name->ToCString()); |
3111 } | 3115 } |
3112 if (method->redirect_name != NULL) { | 3116 if (method->redirect_name != NULL) { |
3113 ErrorMsg(method->name_pos, | 3117 ErrorMsg(method->name_pos, |
3114 "Constructor with redirection may not have a function body"); | 3118 "Constructor with redirection may not have a function body"); |
3115 } | 3119 } |
3116 if (CurrentToken() == Token::kLBRACE) { | 3120 if (CurrentToken() == Token::kLBRACE) { |
3117 SkipBlock(); | 3121 SkipBlock(); |
3118 method_end_pos = TokenPos(); | 3122 method_end_pos = TokenPos(); |
3119 ExpectToken(Token::kRBRACE); | 3123 ExpectToken(Token::kRBRACE); |
3120 } else { | 3124 } else { |
3121 ConsumeToken(); | 3125 ConsumeToken(); |
3122 SkipExpr(); | 3126 SkipExpr(); |
3123 method_end_pos = TokenPos(); | 3127 method_end_pos = TokenPos(); |
3124 ExpectSemicolon(); | 3128 ExpectSemicolon(); |
3125 } | 3129 } |
3126 } else if (IsLiteral("native")) { | 3130 } else if (IsLiteral("native")) { |
3127 if (method->has_abstract) { | 3131 if (method->has_abstract) { |
3128 ErrorMsg(method->name_pos, | 3132 ErrorMsg(method->name_pos, |
3129 "abstract method '%s' may not have a function body", | 3133 "abstract method '%s' may not have a function body", |
3130 method->name->ToCString()); | 3134 method->name->ToCString()); |
3131 } else if (method->IsFactoryOrConstructor() && method->has_const) { | 3135 } else if (method->IsConstructor() && method->has_const) { |
3132 ErrorMsg(method->name_pos, | 3136 ErrorMsg(method->name_pos, |
3133 "const constructor or factory '%s' may not be native", | 3137 "const constructor '%s' may not be native", |
3134 method->name->ToCString()); | 3138 method->name->ToCString()); |
3135 } | 3139 } |
3136 if (method->redirect_name != NULL) { | 3140 if (method->redirect_name != NULL) { |
3137 ErrorMsg(method->name_pos, | 3141 ErrorMsg(method->name_pos, |
3138 "Constructor with redirection may not have a function body"); | 3142 "Constructor with redirection may not have a function body"); |
3139 } | 3143 } |
3140 ParseNativeDeclaration(); | 3144 ParseNativeDeclaration(); |
3141 method_end_pos = TokenPos(); | 3145 method_end_pos = TokenPos(); |
3142 ExpectSemicolon(); | 3146 ExpectSemicolon(); |
3143 } else { | 3147 } else { |
(...skipping 5555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8699 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 8703 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
8700 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); | 8704 return new StaticGetterNode(TokenPos(), NULL, false, field_owner, field_name); |
8701 } | 8705 } |
8702 | 8706 |
8703 | 8707 |
8704 RawObject* Parser::EvaluateConstConstructorCall( | 8708 RawObject* Parser::EvaluateConstConstructorCall( |
8705 const Class& type_class, | 8709 const Class& type_class, |
8706 const AbstractTypeArguments& type_arguments, | 8710 const AbstractTypeArguments& type_arguments, |
8707 const Function& constructor, | 8711 const Function& constructor, |
8708 ArgumentListNode* arguments) { | 8712 ArgumentListNode* arguments) { |
8709 const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. | 8713 // Factories have one extra argument: the type arguments. |
| 8714 // Constructors have 2 extra arguments: rcvr and construction phase. |
| 8715 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; |
8710 const int num_arguments = arguments->length() + kNumExtraArgs; | 8716 const int num_arguments = arguments->length() + kNumExtraArgs; |
8711 const Array& arg_values = Array::Handle(Array::New(num_arguments)); | 8717 const Array& arg_values = Array::Handle(Array::New(num_arguments)); |
8712 Instance& instance = Instance::Handle(); | 8718 Instance& instance = Instance::Handle(); |
8713 ASSERT(!constructor.IsFactory()); | 8719 if (!constructor.IsFactory()) { |
8714 instance = Instance::New(type_class, Heap::kOld); | 8720 instance = Instance::New(type_class, Heap::kOld); |
8715 if (!type_arguments.IsNull()) { | 8721 if (!type_arguments.IsNull()) { |
8716 if (!type_arguments.IsInstantiated()) { | 8722 if (!type_arguments.IsInstantiated()) { |
8717 ErrorMsg("type must be constant in const constructor"); | 8723 ErrorMsg("type must be constant in const constructor"); |
| 8724 } |
| 8725 instance.SetTypeArguments( |
| 8726 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); |
8718 } | 8727 } |
8719 instance.SetTypeArguments( | 8728 arg_values.SetAt(0, instance); |
8720 AbstractTypeArguments::Handle(type_arguments.Canonicalize())); | 8729 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 8730 } else { |
| 8731 // Prepend type_arguments to list of arguments to factory. |
| 8732 ASSERT(type_arguments.IsZoneHandle()); |
| 8733 arg_values.SetAt(0, type_arguments); |
8721 } | 8734 } |
8722 arg_values.SetAt(0, instance); | |
8723 arg_values.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | |
8724 for (int i = 0; i < arguments->length(); i++) { | 8735 for (int i = 0; i < arguments->length(); i++) { |
8725 AstNode* arg = arguments->NodeAt(i); | 8736 AstNode* arg = arguments->NodeAt(i); |
8726 // Arguments have been evaluated to a literal value already. | 8737 // Arguments have been evaluated to a literal value already. |
8727 ASSERT(arg->IsLiteralNode()); | 8738 ASSERT(arg->IsLiteralNode()); |
8728 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 8739 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
8729 } | 8740 } |
8730 const Array& args_descriptor = | 8741 const Array& args_descriptor = |
8731 Array::Handle(ArgumentsDescriptor::New(num_arguments, | 8742 Array::Handle(ArgumentsDescriptor::New(num_arguments, |
8732 arguments->names())); | 8743 arguments->names())); |
8733 const Object& result = | 8744 const Object& result = |
8734 Object::Handle(DartEntry::InvokeFunction(constructor, | 8745 Object::Handle(DartEntry::InvokeFunction(constructor, |
8735 arg_values, | 8746 arg_values, |
8736 args_descriptor)); | 8747 args_descriptor)); |
8737 if (result.IsError()) { | 8748 if (result.IsError()) { |
8738 // An exception may not occur in every parse attempt, i.e., the | 8749 // An exception may not occur in every parse attempt, i.e., the |
8739 // generated AST is not deterministic. Therefore mark the function as | 8750 // generated AST is not deterministic. Therefore mark the function as |
8740 // not optimizable. | 8751 // not optimizable. |
8741 current_function().set_is_optimizable(false); | 8752 current_function().set_is_optimizable(false); |
8742 if (result.IsUnhandledException()) { | 8753 if (result.IsUnhandledException()) { |
8743 return result.raw(); | 8754 return result.raw(); |
8744 } else { | 8755 } else { |
8745 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 8756 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); |
8746 UNREACHABLE(); | 8757 UNREACHABLE(); |
8747 return Object::null(); | 8758 return Object::null(); |
8748 } | 8759 } |
8749 } else { | 8760 } else { |
| 8761 if (constructor.IsFactory()) { |
| 8762 // The factory method returns the allocated object. |
| 8763 instance ^= result.raw(); |
| 8764 } |
8750 return TryCanonicalize(instance, TokenPos()); | 8765 return TryCanonicalize(instance, TokenPos()); |
8751 } | 8766 } |
8752 } | 8767 } |
8753 | 8768 |
8754 | 8769 |
8755 // Do a lookup for the identifier in the block scope and the class scope | 8770 // Do a lookup for the identifier in the block scope and the class scope |
8756 // return true if the identifier is found, false otherwise. | 8771 // return true if the identifier is found, false otherwise. |
8757 // If node is non NULL return an AST node corresponding to the identifier. | 8772 // If node is non NULL return an AST node corresponding to the identifier. |
8758 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 8773 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
8759 const String &ident, | 8774 const String &ident, |
(...skipping 1123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9883 type_arguments, | 9898 type_arguments, |
9884 constructor, | 9899 constructor, |
9885 arguments)); | 9900 arguments)); |
9886 if (constructor_result.IsUnhandledException()) { | 9901 if (constructor_result.IsUnhandledException()) { |
9887 // It's a compile-time error if invocation of a const constructor | 9902 // It's a compile-time error if invocation of a const constructor |
9888 // call fails. | 9903 // call fails. |
9889 AppendErrorMsg(Error::Cast(constructor_result), | 9904 AppendErrorMsg(Error::Cast(constructor_result), |
9890 new_pos, | 9905 new_pos, |
9891 "error while evaluating const constructor"); | 9906 "error while evaluating const constructor"); |
9892 } else { | 9907 } else { |
9893 const Instance& const_instance = Instance::Cast(constructor_result); | 9908 // Const constructors can return null in the case where a const native |
| 9909 // factory returns a null value. Thus we cannot use a Instance::Cast here. |
| 9910 Instance& const_instance = Instance::Handle(); |
| 9911 const_instance ^= constructor_result.raw(); |
9894 new_object = new LiteralNode(new_pos, | 9912 new_object = new LiteralNode(new_pos, |
9895 Instance::ZoneHandle(const_instance.raw())); | 9913 Instance::ZoneHandle(const_instance.raw())); |
9896 if (!type_bound.IsNull()) { | 9914 if (!type_bound.IsNull()) { |
9897 ASSERT(!type_bound.IsMalformed()); | 9915 ASSERT(!type_bound.IsMalformed()); |
9898 Error& malformed_error = Error::Handle(); | 9916 Error& malformed_error = Error::Handle(); |
9899 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9917 ASSERT(!is_top_level_); // We cannot check unresolved types. |
9900 if (!const_instance.IsInstanceOf(type_bound, | 9918 if (!const_instance.IsInstanceOf(type_bound, |
9901 TypeArguments::Handle(), | 9919 TypeArguments::Handle(), |
9902 &malformed_error)) { | 9920 &malformed_error)) { |
9903 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 9921 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10576 void Parser::SkipQualIdent() { | 10594 void Parser::SkipQualIdent() { |
10577 ASSERT(IsIdentifier()); | 10595 ASSERT(IsIdentifier()); |
10578 ConsumeToken(); | 10596 ConsumeToken(); |
10579 if (CurrentToken() == Token::kPERIOD) { | 10597 if (CurrentToken() == Token::kPERIOD) { |
10580 ConsumeToken(); // Consume the kPERIOD token. | 10598 ConsumeToken(); // Consume the kPERIOD token. |
10581 ExpectIdentifier("identifier expected after '.'"); | 10599 ExpectIdentifier("identifier expected after '.'"); |
10582 } | 10600 } |
10583 } | 10601 } |
10584 | 10602 |
10585 } // namespace dart | 10603 } // namespace dart |
OLD | NEW |