| 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 |