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