Chromium Code Reviews| 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 7188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7199 ASSERT(is_malbounded); | 7199 ASSERT(is_malbounded); |
| 7200 } | 7200 } |
| 7201 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( | 7201 arguments->Add(new LiteralNode(type_pos, String::ZoneHandle( |
| 7202 Symbols::New(error.ToErrorCString())))); | 7202 Symbols::New(error.ToErrorCString())))); |
| 7203 return MakeStaticCall(Symbols::TypeError(), | 7203 return MakeStaticCall(Symbols::TypeError(), |
| 7204 PrivateCoreLibName(Symbols::ThrowNew()), | 7204 PrivateCoreLibName(Symbols::ThrowNew()), |
| 7205 arguments); | 7205 arguments); |
| 7206 } | 7206 } |
| 7207 | 7207 |
| 7208 | 7208 |
| 7209 // TODO(regis): Providing the argument values is not always feasible, since | |
| 7210 // evaluating them could throw an error. | |
| 7211 // Should NoSuchMethodError reflect the argument count and names instead of | |
| 7212 // argument values? Or should the spec specify a different evaluation order? | |
| 7213 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 7209 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, |
| 7214 const Class& cls, | 7210 const Class& cls, |
| 7215 const String& function_name, | 7211 const String& function_name, |
| 7212 ArgumentListNode* actuals, | |
|
regis
2013/08/28 21:10:54
function_arguments
zra
2013/08/28 22:47:00
Done.
| |
| 7216 InvocationMirror::Call im_call, | 7213 InvocationMirror::Call im_call, |
| 7217 InvocationMirror::Type im_type) { | 7214 InvocationMirror::Type im_type) { |
| 7218 ArgumentListNode* arguments = new ArgumentListNode(call_pos); | 7215 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
| 7219 // Object receiver. | 7216 // Object receiver. |
| 7220 // TODO(regis): For now, we pass a class literal of the unresolved | 7217 // TODO(regis): For now, we pass a class literal of the unresolved |
| 7221 // method's owner, but this is not specified and will probably change. | 7218 // method's owner, but this is not specified and will probably change. |
| 7222 Type& type = Type::ZoneHandle( | 7219 Type& type = Type::ZoneHandle( |
| 7223 Type::New(cls, TypeArguments::Handle(), call_pos, Heap::kOld)); | 7220 Type::New(cls, TypeArguments::Handle(), call_pos, Heap::kOld)); |
| 7224 type ^= ClassFinalizer::FinalizeType( | 7221 type ^= ClassFinalizer::FinalizeType( |
| 7225 current_class(), type, ClassFinalizer::kCanonicalize); | 7222 current_class(), type, ClassFinalizer::kCanonicalize); |
| 7226 arguments->Add(new LiteralNode(call_pos, type)); | 7223 arguments->Add(new LiteralNode(call_pos, type)); |
| 7227 // String memberName. | 7224 // String memberName. |
| 7228 arguments->Add(new LiteralNode( | 7225 arguments->Add(new LiteralNode( |
| 7229 call_pos, String::ZoneHandle(Symbols::New(function_name)))); | 7226 call_pos, String::ZoneHandle(Symbols::New(function_name)))); |
| 7230 // Smi invocation_type. | 7227 // Smi invocation_type. |
| 7231 if (cls.IsTopLevel()) { | 7228 if (cls.IsTopLevel()) { |
| 7232 ASSERT(im_call == InvocationMirror::kStatic || | 7229 ASSERT(im_call == InvocationMirror::kStatic || |
| 7233 im_call == InvocationMirror::kTopLevel); | 7230 im_call == InvocationMirror::kTopLevel); |
| 7234 im_call = InvocationMirror::kTopLevel; | 7231 im_call = InvocationMirror::kTopLevel; |
| 7235 } | 7232 } |
| 7236 arguments->Add(new LiteralNode(call_pos, Smi::ZoneHandle( | 7233 arguments->Add(new LiteralNode(call_pos, Smi::ZoneHandle( |
| 7237 Smi::New(InvocationMirror::EncodeType(im_call, im_type))))); | 7234 Smi::New(InvocationMirror::EncodeType(im_call, im_type))))); |
| 7238 // List arguments. | 7235 // List arguments. |
| 7239 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | 7236 if (actuals == NULL) { |
| 7237 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | |
| 7238 } else { | |
| 7239 ArrayNode* array = new ArrayNode( | |
| 7240 call_pos, Type::ZoneHandle(Type::ArrayType()), actuals->nodes()); | |
| 7241 arguments->Add(array); | |
| 7242 } | |
| 7240 // List argumentNames. | 7243 // List argumentNames. |
| 7241 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | 7244 if (actuals == NULL) { |
| 7245 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | |
| 7246 } else { | |
| 7247 arguments->Add(new LiteralNode(call_pos, actuals->names())); | |
| 7248 } | |
| 7242 // List existingArgumentNames. | 7249 // List existingArgumentNames. |
| 7243 // Check if there exists a function with the same name. | 7250 // Check if there exists a function with the same name. |
| 7244 Function& function = | 7251 Function& function = |
| 7245 Function::Handle(cls.LookupStaticFunction(function_name)); | 7252 Function::Handle(cls.LookupStaticFunction(function_name)); |
| 7246 if (function.IsNull()) { | 7253 if (function.IsNull()) { |
| 7247 // TODO(srdjan): Store argument values into the argument list. | |
| 7248 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); | 7254 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); |
| 7249 } else { | 7255 } else { |
| 7250 const int total_num_parameters = function.NumParameters(); | 7256 const int total_num_parameters = function.NumParameters(); |
| 7251 Array& array = | 7257 Array& array = |
| 7252 Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld)); | 7258 Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld)); |
| 7253 // Skip receiver. | 7259 // Skip receiver. |
| 7254 for (int i = 0; i < total_num_parameters; i++) { | 7260 for (int i = 0; i < total_num_parameters; i++) { |
| 7255 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); | 7261 array.SetAt(i, String::Handle(function.ParameterNameAt(i))); |
| 7256 } | 7262 } |
| 7257 arguments->Add(new LiteralNode(call_pos, array)); | 7263 arguments->Add(new LiteralNode(call_pos, array)); |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7741 TRACE_PARSER("ParseActualParameters"); | 7747 TRACE_PARSER("ParseActualParameters"); |
| 7742 ASSERT(CurrentToken() == Token::kLPAREN); | 7748 ASSERT(CurrentToken() == Token::kLPAREN); |
| 7743 const bool saved_mode = SetAllowFunctionLiterals(true); | 7749 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7744 ArgumentListNode* arguments; | 7750 ArgumentListNode* arguments; |
| 7745 if (implicit_arguments == NULL) { | 7751 if (implicit_arguments == NULL) { |
| 7746 arguments = new ArgumentListNode(TokenPos()); | 7752 arguments = new ArgumentListNode(TokenPos()); |
| 7747 } else { | 7753 } else { |
| 7748 arguments = implicit_arguments; | 7754 arguments = implicit_arguments; |
| 7749 } | 7755 } |
| 7750 const GrowableObjectArray& names = | 7756 const GrowableObjectArray& names = |
| 7751 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 7757 GrowableObjectArray::Handle(GrowableObjectArray::New(Heap::kOld)); |
| 7752 bool named_argument_seen = false; | 7758 bool named_argument_seen = false; |
| 7753 if (LookaheadToken(1) != Token::kRPAREN) { | 7759 if (LookaheadToken(1) != Token::kRPAREN) { |
| 7754 String& arg_name = String::Handle(); | 7760 String& arg_name = String::Handle(); |
| 7755 do { | 7761 do { |
| 7756 ASSERT((CurrentToken() == Token::kLPAREN) || | 7762 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 7757 (CurrentToken() == Token::kCOMMA)); | 7763 (CurrentToken() == Token::kCOMMA)); |
| 7758 ConsumeToken(); | 7764 ConsumeToken(); |
| 7759 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 7765 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 7760 named_argument_seen = true; | 7766 named_argument_seen = true; |
| 7761 // The canonicalization of the arguments descriptor array built in | 7767 // The canonicalization of the arguments descriptor array built in |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7830 } | 7836 } |
| 7831 } else { | 7837 } else { |
| 7832 EnsureSavedCurrentContext(); | 7838 EnsureSavedCurrentContext(); |
| 7833 closure = GenerateStaticFieldLookup(field, call_pos); | 7839 closure = GenerateStaticFieldLookup(field, call_pos); |
| 7834 return new ClosureCallNode(call_pos, closure, arguments); | 7840 return new ClosureCallNode(call_pos, closure, arguments); |
| 7835 } | 7841 } |
| 7836 // Could not resolve static method: throw a NoSuchMethodError. | 7842 // Could not resolve static method: throw a NoSuchMethodError. |
| 7837 return ThrowNoSuchMethodError(ident_pos, | 7843 return ThrowNoSuchMethodError(ident_pos, |
| 7838 cls, | 7844 cls, |
| 7839 func_name, | 7845 func_name, |
| 7846 arguments, | |
| 7840 InvocationMirror::kStatic, | 7847 InvocationMirror::kStatic, |
| 7841 InvocationMirror::kMethod); | 7848 InvocationMirror::kMethod); |
| 7842 } else if (cls.IsTopLevel() && | 7849 } else if (cls.IsTopLevel() && |
| 7843 (cls.library() == Library::CoreLibrary()) && | 7850 (cls.library() == Library::CoreLibrary()) && |
| 7844 (func.name() == Symbols::Identical().raw())) { | 7851 (func.name() == Symbols::Identical().raw())) { |
| 7845 // This is the predefined toplevel function identical(a,b). Create | 7852 // This is the predefined toplevel function identical(a,b). Create |
| 7846 // a comparison node instead. | 7853 // a comparison node instead. |
| 7847 ASSERT(num_arguments == 2); | 7854 ASSERT(num_arguments == 2); |
| 7848 return new ComparisonNode(ident_pos, | 7855 return new ComparisonNode(ident_pos, |
| 7849 Token::kEQ_STRICT, | 7856 Token::kEQ_STRICT, |
| (...skipping 1902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9752 call_pos, | 9759 call_pos, |
| 9753 "class '%s' has no constructor or factory named '%s'", | 9760 "class '%s' has no constructor or factory named '%s'", |
| 9754 String::Handle(type_class.Name()).ToCString(), | 9761 String::Handle(type_class.Name()).ToCString(), |
| 9755 external_constructor_name.ToCString()); | 9762 external_constructor_name.ToCString()); |
| 9756 const Error& error = Error::Handle(type.malformed_error()); | 9763 const Error& error = Error::Handle(type.malformed_error()); |
| 9757 ErrorMsg(error); | 9764 ErrorMsg(error); |
| 9758 } | 9765 } |
| 9759 return ThrowNoSuchMethodError(call_pos, | 9766 return ThrowNoSuchMethodError(call_pos, |
| 9760 type_class, | 9767 type_class, |
| 9761 external_constructor_name, | 9768 external_constructor_name, |
| 9769 arguments, | |
| 9762 InvocationMirror::kConstructor, | 9770 InvocationMirror::kConstructor, |
| 9763 InvocationMirror::kMethod); | 9771 InvocationMirror::kMethod); |
| 9764 } else if (constructor.IsRedirectingFactory()) { | 9772 } else if (constructor.IsRedirectingFactory()) { |
| 9765 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); | 9773 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); |
| 9766 Type& redirect_type = Type::Handle(constructor.RedirectionType()); | 9774 Type& redirect_type = Type::Handle(constructor.RedirectionType()); |
| 9767 if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) { | 9775 if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) { |
| 9768 // The type arguments of the redirection type are instantiated from the | 9776 // The type arguments of the redirection type are instantiated from the |
| 9769 // type arguments of the parsed type of the 'new' or 'const' expression. | 9777 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 9770 Error& malformed_error = Error::Handle(); | 9778 Error& malformed_error = Error::Handle(); |
| 9771 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, | 9779 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9819 ErrorMsg(call_pos, | 9827 ErrorMsg(call_pos, |
| 9820 "invalid arguments passed to constructor '%s' " | 9828 "invalid arguments passed to constructor '%s' " |
| 9821 "for class '%s': %s", | 9829 "for class '%s': %s", |
| 9822 external_constructor_name.ToCString(), | 9830 external_constructor_name.ToCString(), |
| 9823 String::Handle(type_class.Name()).ToCString(), | 9831 String::Handle(type_class.Name()).ToCString(), |
| 9824 error_message.ToCString()); | 9832 error_message.ToCString()); |
| 9825 } | 9833 } |
| 9826 return ThrowNoSuchMethodError(call_pos, | 9834 return ThrowNoSuchMethodError(call_pos, |
| 9827 type_class, | 9835 type_class, |
| 9828 external_constructor_name, | 9836 external_constructor_name, |
| 9837 arguments, | |
| 9829 InvocationMirror::kConstructor, | 9838 InvocationMirror::kConstructor, |
| 9830 InvocationMirror::kMethod); | 9839 InvocationMirror::kMethod); |
| 9831 } | 9840 } |
| 9832 | 9841 |
| 9833 // Return a throw in case of a malformed type or report a compile-time error | 9842 // Return a throw in case of a malformed type or report a compile-time error |
| 9834 // if the constructor is const. | 9843 // if the constructor is const. |
| 9835 if (type.IsMalformed()) { | 9844 if (type.IsMalformed()) { |
| 9836 if (is_const) { | 9845 if (is_const) { |
| 9837 const Error& error = Error::Handle(type.malformed_error()); | 9846 const Error& error = Error::Handle(type.malformed_error()); |
| 9838 ErrorMsg(error); | 9847 ErrorMsg(error); |
| (...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10472 void Parser::SkipQualIdent() { | 10481 void Parser::SkipQualIdent() { |
| 10473 ASSERT(IsIdentifier()); | 10482 ASSERT(IsIdentifier()); |
| 10474 ConsumeToken(); | 10483 ConsumeToken(); |
| 10475 if (CurrentToken() == Token::kPERIOD) { | 10484 if (CurrentToken() == Token::kPERIOD) { |
| 10476 ConsumeToken(); // Consume the kPERIOD token. | 10485 ConsumeToken(); // Consume the kPERIOD token. |
| 10477 ExpectIdentifier("identifier expected after '.'"); | 10486 ExpectIdentifier("identifier expected after '.'"); |
| 10478 } | 10487 } |
| 10479 } | 10488 } |
| 10480 | 10489 |
| 10481 } // namespace dart | 10490 } // namespace dart |
| OLD | NEW |