Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: runtime/vm/parser.cc

Issue 24395007: Improve NoSuchMethodError error messages (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2885 matching lines...) Expand 10 before | Expand all | Expand 10 after
2896 // TODO(regis): For an instance function, pass the receiver to 2896 // TODO(regis): For an instance function, pass the receiver to
2897 // NoSuchMethodError. 2897 // NoSuchMethodError.
2898 current_block_->statements->Add( 2898 current_block_->statements->Add(
2899 ThrowNoSuchMethodError(TokenPos(), 2899 ThrowNoSuchMethodError(TokenPos(),
2900 current_class(), 2900 current_class(),
2901 function_name, 2901 function_name,
2902 NULL, // No arguments. 2902 NULL, // No arguments.
2903 func.is_static() ? 2903 func.is_static() ?
2904 InvocationMirror::kStatic : 2904 InvocationMirror::kStatic :
2905 InvocationMirror::kDynamic, 2905 InvocationMirror::kDynamic,
2906 InvocationMirror::kMethod)); 2906 InvocationMirror::kMethod,
2907 NULL)); // No existing function.
2907 end_token_pos = TokenPos(); 2908 end_token_pos = TokenPos();
2908 } else { 2909 } else {
2909 UnexpectedToken(); 2910 UnexpectedToken();
2910 } 2911 }
2911 2912
2912 ASSERT(func.end_token_pos() == func.token_pos() || 2913 ASSERT(func.end_token_pos() == func.token_pos() ||
2913 func.end_token_pos() == end_token_pos); 2914 func.end_token_pos() == end_token_pos);
2914 func.set_end_token_pos(end_token_pos); 2915 func.set_end_token_pos(end_token_pos);
2915 SequenceNode* body = CloseBlock(); 2916 SequenceNode* body = CloseBlock();
2916 current_block_->statements->Add(body); 2917 current_block_->statements->Add(body);
(...skipping 4387 matching lines...) Expand 10 before | Expand all | Expand 10 after
7304 PrivateCoreLibName(Symbols::ThrowNew()), 7305 PrivateCoreLibName(Symbols::ThrowNew()),
7305 arguments); 7306 arguments);
7306 } 7307 }
7307 7308
7308 7309
7309 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, 7310 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos,
7310 const Class& cls, 7311 const Class& cls,
7311 const String& function_name, 7312 const String& function_name,
7312 ArgumentListNode* function_arguments, 7313 ArgumentListNode* function_arguments,
7313 InvocationMirror::Call im_call, 7314 InvocationMirror::Call im_call,
7314 InvocationMirror::Type im_type) { 7315 InvocationMirror::Type im_type,
7316 Function* func) {
7315 ArgumentListNode* arguments = new ArgumentListNode(call_pos); 7317 ArgumentListNode* arguments = new ArgumentListNode(call_pos);
7316 // Object receiver. 7318 // Object receiver.
7317 // TODO(regis): For now, we pass a class literal of the unresolved 7319 // TODO(regis): For now, we pass a class literal of the unresolved
7318 // method's owner, but this is not specified and will probably change. 7320 // method's owner, but this is not specified and will probably change.
7319 Type& type = Type::ZoneHandle( 7321 Type& type = Type::ZoneHandle(
7320 Type::New(cls, TypeArguments::Handle(), call_pos, Heap::kOld)); 7322 Type::New(cls, TypeArguments::Handle(), call_pos, Heap::kOld));
7321 type ^= ClassFinalizer::FinalizeType( 7323 type ^= ClassFinalizer::FinalizeType(
7322 current_class(), type, ClassFinalizer::kCanonicalize); 7324 current_class(), type, ClassFinalizer::kCanonicalize);
7323 arguments->Add(new LiteralNode(call_pos, type)); 7325 arguments->Add(new LiteralNode(call_pos, type));
7324 // String memberName. 7326 // String memberName.
(...skipping 15 matching lines...) Expand all
7340 Type::ZoneHandle(Type::ArrayType()), 7342 Type::ZoneHandle(Type::ArrayType()),
7341 function_arguments->nodes()); 7343 function_arguments->nodes());
7342 arguments->Add(array); 7344 arguments->Add(array);
7343 } 7345 }
7344 // List argumentNames. 7346 // List argumentNames.
7345 if (function_arguments == NULL) { 7347 if (function_arguments == NULL) {
7346 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); 7348 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle()));
7347 } else { 7349 } else {
7348 arguments->Add(new LiteralNode(call_pos, function_arguments->names())); 7350 arguments->Add(new LiteralNode(call_pos, function_arguments->names()));
7349 } 7351 }
7352
7350 // List existingArgumentNames. 7353 // List existingArgumentNames.
7351 // Check if there exists a function with the same name. 7354 // Check if there exists a function with the same name unless caller
7352 Function& function = 7355 // has done the lookup already. If there is a function with the same
7353 Function::Handle(cls.LookupStaticFunction(function_name)); 7356 // name but incompatible parameters, inform the NoSuchMethodError what the
7354 if (function.IsNull()) { 7357 // expected parameters are.
7355 arguments->Add(new LiteralNode(call_pos, Array::ZoneHandle())); 7358 Function& function = Function::Handle();
7359 if (func != NULL) {
7360 function = func->raw();
7356 } else { 7361 } else {
7357 const int total_num_parameters = function.NumParameters(); 7362 function = cls.LookupStaticFunction(function_name);
7358 Array& array =
7359 Array::ZoneHandle(Array::New(total_num_parameters, Heap::kOld));
7360 // Skip receiver.
7361 for (int i = 0; i < total_num_parameters; i++) {
7362 array.SetAt(i, String::Handle(function.ParameterNameAt(i)));
7363 }
7364 arguments->Add(new LiteralNode(call_pos, array));
7365 } 7363 }
7364 Array& array = Array::ZoneHandle();
7365 if (!function.IsNull()) {
7366 // The constructor for NoSuchMethodError takes a list of existing
7367 // parameter names to produce a descriptive error message explaining
7368 // the parameter mismatch. The problem is that the array of names
7369 // does not describe which parameters are optional positional or
7370 // named, which can lead to confusing error messages.
7371 // Since the NoSuchMethodError class only uses the list to produce
7372 // a string describing the expected parameters, we construct a more
7373 // descriptive string here and pass it as the only element of the
7374 // "existingArgumentNames" array of the NoSuchMethodError constructor.
7375 // TODO(13471): Separate the implementations of NoSuchMethodError
7376 // between dart2js and VM. Update the constructor to accept a string
7377 // describing the formal parameters of an incompatible call target.
7378 array = Array::New(1, Heap::kOld);
7379 array.SetAt(0, String::Handle(function.UserVisibleFormalParameters()));
7380 }
7381 arguments->Add(new LiteralNode(call_pos, array));
7382
7366 return MakeStaticCall(Symbols::NoSuchMethodError(), 7383 return MakeStaticCall(Symbols::NoSuchMethodError(),
7367 PrivateCoreLibName(Symbols::ThrowNew()), 7384 PrivateCoreLibName(Symbols::ThrowNew()),
7368 arguments); 7385 arguments);
7369 } 7386 }
7370 7387
7371 7388
7372 AstNode* Parser::ParseBinaryExpr(int min_preced) { 7389 AstNode* Parser::ParseBinaryExpr(int min_preced) {
7373 TRACE_PARSER("ParseBinaryExpr"); 7390 TRACE_PARSER("ParseBinaryExpr");
7374 ASSERT(min_preced >= Token::Precedence(Token::kOR)); 7391 ASSERT(min_preced >= Token::Precedence(Token::kOR));
7375 AstNode* left_operand = ParseUnaryExpr(); 7392 AstNode* left_operand = ParseUnaryExpr();
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
7643 name = left_ident->raw(); 7660 name = left_ident->raw();
7644 } 7661 }
7645 if (name.IsNull()) { 7662 if (name.IsNull()) {
7646 ErrorMsg(left_pos, "expression is not assignable"); 7663 ErrorMsg(left_pos, "expression is not assignable");
7647 } 7664 }
7648 result = ThrowNoSuchMethodError(original->token_pos(), 7665 result = ThrowNoSuchMethodError(original->token_pos(),
7649 current_class(), 7666 current_class(),
7650 name, 7667 name,
7651 NULL, // No arguments. 7668 NULL, // No arguments.
7652 InvocationMirror::kStatic, 7669 InvocationMirror::kStatic,
7653 InvocationMirror::kSetter); 7670 InvocationMirror::kSetter,
7671 NULL); // No existing function.
7654 } else if (result->IsStoreIndexedNode() || 7672 } else if (result->IsStoreIndexedNode() ||
7655 result->IsInstanceSetterNode() || 7673 result->IsInstanceSetterNode() ||
7656 result->IsStaticSetterNode() || 7674 result->IsStaticSetterNode() ||
7657 result->IsStoreStaticFieldNode() || 7675 result->IsStoreStaticFieldNode() ||
7658 result->IsStoreLocalNode()) { 7676 result->IsStoreLocalNode()) {
7659 // Ensure that the expression temp is allocated for nodes that may need it. 7677 // Ensure that the expression temp is allocated for nodes that may need it.
7660 EnsureExpressionTemp(); 7678 EnsureExpressionTemp();
7661 } 7679 }
7662 return result; 7680 return result;
7663 } 7681 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
7937 EnsureSavedCurrentContext(); 7955 EnsureSavedCurrentContext();
7938 closure = GenerateStaticFieldLookup(field, call_pos); 7956 closure = GenerateStaticFieldLookup(field, call_pos);
7939 return new ClosureCallNode(call_pos, closure, arguments); 7957 return new ClosureCallNode(call_pos, closure, arguments);
7940 } 7958 }
7941 // Could not resolve static method: throw a NoSuchMethodError. 7959 // Could not resolve static method: throw a NoSuchMethodError.
7942 return ThrowNoSuchMethodError(ident_pos, 7960 return ThrowNoSuchMethodError(ident_pos,
7943 cls, 7961 cls,
7944 func_name, 7962 func_name,
7945 arguments, 7963 arguments,
7946 InvocationMirror::kStatic, 7964 InvocationMirror::kStatic,
7947 InvocationMirror::kMethod); 7965 InvocationMirror::kMethod,
7966 NULL); // No existing function.
7948 } else if (cls.IsTopLevel() && 7967 } else if (cls.IsTopLevel() &&
7949 (cls.library() == Library::CoreLibrary()) && 7968 (cls.library() == Library::CoreLibrary()) &&
7950 (func.name() == Symbols::Identical().raw())) { 7969 (func.name() == Symbols::Identical().raw())) {
7951 // This is the predefined toplevel function identical(a,b). Create 7970 // This is the predefined toplevel function identical(a,b). Create
7952 // a comparison node instead. 7971 // a comparison node instead.
7953 ASSERT(num_arguments == 2); 7972 ASSERT(num_arguments == 2);
7954 return new ComparisonNode(ident_pos, 7973 return new ComparisonNode(ident_pos,
7955 Token::kEQ_STRICT, 7974 Token::kEQ_STRICT,
7956 arguments->NodeAt(0), 7975 arguments->NodeAt(0),
7957 arguments->NodeAt(1)); 7976 arguments->NodeAt(1));
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
8038 kNumArguments, 8057 kNumArguments,
8039 Object::empty_array(), 8058 Object::empty_array(),
8040 Resolver::kIsQualified); 8059 Resolver::kIsQualified);
8041 if (func.IsNull()) { 8060 if (func.IsNull()) {
8042 // No field or explicit setter function, throw a NoSuchMethodError. 8061 // No field or explicit setter function, throw a NoSuchMethodError.
8043 return ThrowNoSuchMethodError(ident_pos, 8062 return ThrowNoSuchMethodError(ident_pos,
8044 cls, 8063 cls,
8045 field_name, 8064 field_name,
8046 NULL, // No arguments. 8065 NULL, // No arguments.
8047 InvocationMirror::kStatic, 8066 InvocationMirror::kStatic,
8048 InvocationMirror::kField); 8067 InvocationMirror::kField,
8068 NULL); // No existing function.
8049 } 8069 }
8050 8070
8051 // Explicit setter function for the field found, field does not exist. 8071 // Explicit setter function for the field found, field does not exist.
8052 // Create a getter node first in case it is needed. If getter node 8072 // Create a getter node first in case it is needed. If getter node
8053 // is used as part of, e.g., "+=", and the explicit getter does not 8073 // is used as part of, e.g., "+=", and the explicit getter does not
8054 // exist, and error will be reported by the code generator. 8074 // exist, and error will be reported by the code generator.
8055 access = new StaticGetterNode(call_pos, 8075 access = new StaticGetterNode(call_pos,
8056 NULL, 8076 NULL,
8057 false, 8077 false,
8058 Class::ZoneHandle(cls.raw()), 8078 Class::ZoneHandle(cls.raw()),
(...skipping 24 matching lines...) Expand all
8083 // We might be referring to an implicit closure, check to see if 8103 // We might be referring to an implicit closure, check to see if
8084 // there is a function of the same name. 8104 // there is a function of the same name.
8085 func = cls.LookupStaticFunction(field_name); 8105 func = cls.LookupStaticFunction(field_name);
8086 if (func.IsNull()) { 8106 if (func.IsNull()) {
8087 // No field or explicit getter function, throw a NoSuchMethodError. 8107 // No field or explicit getter function, throw a NoSuchMethodError.
8088 return ThrowNoSuchMethodError(ident_pos, 8108 return ThrowNoSuchMethodError(ident_pos,
8089 cls, 8109 cls,
8090 field_name, 8110 field_name,
8091 NULL, // No arguments. 8111 NULL, // No arguments.
8092 InvocationMirror::kStatic, 8112 InvocationMirror::kStatic,
8093 InvocationMirror::kGetter); 8113 InvocationMirror::kGetter,
8114 NULL); // No existing function.
8094 } 8115 }
8095 access = CreateImplicitClosureNode(func, call_pos, NULL); 8116 access = CreateImplicitClosureNode(func, call_pos, NULL);
8096 } else { 8117 } else {
8097 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); 8118 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter);
8098 access = new StaticGetterNode(call_pos, 8119 access = new StaticGetterNode(call_pos,
8099 NULL, 8120 NULL,
8100 false, 8121 false,
8101 Class::ZoneHandle(cls.raw()), 8122 Class::ZoneHandle(cls.raw()),
8102 field_name); 8123 field_name);
8103 } 8124 }
(...skipping 19 matching lines...) Expand all
8123 // In an instance method, we convert this into a getter call 8144 // In an instance method, we convert this into a getter call
8124 // for a field (which may be defined in a subclass.) 8145 // for a field (which may be defined in a subclass.)
8125 String& name = String::CheckedZoneHandle(primary->primary().raw()); 8146 String& name = String::CheckedZoneHandle(primary->primary().raw());
8126 if (current_function().is_static() || 8147 if (current_function().is_static() ||
8127 current_function().IsInFactoryScope()) { 8148 current_function().IsInFactoryScope()) {
8128 return ThrowNoSuchMethodError(primary->token_pos(), 8149 return ThrowNoSuchMethodError(primary->token_pos(),
8129 current_class(), 8150 current_class(),
8130 name, 8151 name,
8131 NULL, // No arguments. 8152 NULL, // No arguments.
8132 InvocationMirror::kStatic, 8153 InvocationMirror::kStatic,
8133 InvocationMirror::kField); 8154 InvocationMirror::kField,
8155 NULL); // No existing function.
8134 } else { 8156 } else {
8135 AstNode* receiver = LoadReceiver(primary->token_pos()); 8157 AstNode* receiver = LoadReceiver(primary->token_pos());
8136 return CallGetter(node->token_pos(), receiver, name); 8158 return CallGetter(node->token_pos(), receiver, name);
8137 } 8159 }
8138 } 8160 }
8139 return primary; 8161 return primary;
8140 } 8162 }
8141 8163
8142 8164
8143 AstNode* Parser::LoadClosure(PrimaryNode* primary) { 8165 AstNode* Parser::LoadClosure(PrimaryNode* primary) {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
8295 if (primary->IsSuper()) { 8317 if (primary->IsSuper()) {
8296 ErrorMsg(primary->token_pos(), "illegal use of super"); 8318 ErrorMsg(primary->token_pos(), "illegal use of super");
8297 } 8319 }
8298 String& name = String::CheckedZoneHandle(primary->primary().raw()); 8320 String& name = String::CheckedZoneHandle(primary->primary().raw());
8299 if (current_function().is_static()) { 8321 if (current_function().is_static()) {
8300 selector = ThrowNoSuchMethodError(primary->token_pos(), 8322 selector = ThrowNoSuchMethodError(primary->token_pos(),
8301 current_class(), 8323 current_class(),
8302 name, 8324 name,
8303 NULL, // No arguments. 8325 NULL, // No arguments.
8304 InvocationMirror::kStatic, 8326 InvocationMirror::kStatic,
8305 InvocationMirror::kMethod); 8327 InvocationMirror::kMethod,
8328 NULL); // No existing function.
8306 } else { 8329 } else {
8307 // Treat as call to unresolved (instance) method. 8330 // Treat as call to unresolved (instance) method.
8308 AstNode* receiver = LoadReceiver(primary->token_pos()); 8331 AstNode* receiver = LoadReceiver(primary->token_pos());
8309 selector = ParseInstanceCall(receiver, name); 8332 selector = ParseInstanceCall(receiver, name);
8310 } 8333 }
8311 } else if (primary->primary().IsTypeParameter()) { 8334 } else if (primary->primary().IsTypeParameter()) {
8312 // TODO(regis): Issue 13134. Make sure the error message is the 8335 // TODO(regis): Issue 13134. Make sure the error message is the
8313 // one we want here and add a test covering this code. 8336 // one we want here and add a test covering this code.
8314 const String& name = String::ZoneHandle( 8337 const String& name = String::ZoneHandle(
8315 TypeParameter::Cast(primary->primary()).name()); 8338 TypeParameter::Cast(primary->primary()).name());
8316 selector = ThrowNoSuchMethodError(primary->token_pos(), 8339 selector = ThrowNoSuchMethodError(primary->token_pos(),
8317 current_class(), 8340 current_class(),
8318 name, 8341 name,
8319 NULL, // No arguments. 8342 NULL, // No arguments.
8320 InvocationMirror::kStatic, 8343 InvocationMirror::kStatic,
8321 InvocationMirror::kMethod); 8344 InvocationMirror::kMethod,
8345 NULL); // No existing function.
8322 } else if (primary->primary().IsClass()) { 8346 } else if (primary->primary().IsClass()) {
8323 const Class& type_class = Class::Cast(primary->primary()); 8347 const Class& type_class = Class::Cast(primary->primary());
8324 Type& type = Type::ZoneHandle( 8348 Type& type = Type::ZoneHandle(
8325 Type::New(type_class, TypeArguments::Handle(), 8349 Type::New(type_class, TypeArguments::Handle(),
8326 primary->token_pos(), Heap::kOld)); 8350 primary->token_pos(), Heap::kOld));
8327 type ^= ClassFinalizer::FinalizeType( 8351 type ^= ClassFinalizer::FinalizeType(
8328 current_class(), type, ClassFinalizer::kCanonicalize); 8352 current_class(), type, ClassFinalizer::kCanonicalize);
8329 ASSERT(!type.IsMalformed()); 8353 ASSERT(!type.IsMalformed());
8330 selector = new TypeNode(primary->token_pos(), type); 8354 selector = new TypeNode(primary->token_pos(), type);
8331 } else { 8355 } else {
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
9045 // method, evaluation of an unresolved identifier causes a 9069 // method, evaluation of an unresolved identifier causes a
9046 // NoSuchMethodError to be thrown. In an instance method, we convert 9070 // NoSuchMethodError to be thrown. In an instance method, we convert
9047 // the unresolved name to an instance field access, since a 9071 // the unresolved name to an instance field access, since a
9048 // subclass might define a field with this name. 9072 // subclass might define a field with this name.
9049 if (current_function().is_static()) { 9073 if (current_function().is_static()) {
9050 resolved = ThrowNoSuchMethodError(ident_pos, 9074 resolved = ThrowNoSuchMethodError(ident_pos,
9051 current_class(), 9075 current_class(),
9052 ident, 9076 ident,
9053 NULL, // No arguments. 9077 NULL, // No arguments.
9054 InvocationMirror::kStatic, 9078 InvocationMirror::kStatic,
9055 InvocationMirror::kField); 9079 InvocationMirror::kField,
9080 NULL); // No existing function.
9056 } else { 9081 } else {
9057 // Treat as call to unresolved instance field. 9082 // Treat as call to unresolved instance field.
9058 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); 9083 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
9059 } 9084 }
9060 } else if (primary->primary().IsFunction()) { 9085 } else if (primary->primary().IsFunction()) {
9061 if (allow_closure_names) { 9086 if (allow_closure_names) {
9062 resolved = LoadClosure(primary); 9087 resolved = LoadClosure(primary);
9063 } else { 9088 } else {
9064 ErrorMsg(ident_pos, "illegal reference to method '%s'", 9089 ErrorMsg(ident_pos, "illegal reference to method '%s'",
9065 ident.ToCString()); 9090 ident.ToCString());
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
9747 String::Handle(type_class.Name()).ToCString(), 9772 String::Handle(type_class.Name()).ToCString(),
9748 external_constructor_name.ToCString()); 9773 external_constructor_name.ToCString());
9749 const Error& error = Error::Handle(type.malformed_error()); 9774 const Error& error = Error::Handle(type.malformed_error());
9750 ErrorMsg(error); 9775 ErrorMsg(error);
9751 } 9776 }
9752 return ThrowNoSuchMethodError(call_pos, 9777 return ThrowNoSuchMethodError(call_pos,
9753 type_class, 9778 type_class,
9754 external_constructor_name, 9779 external_constructor_name,
9755 arguments, 9780 arguments,
9756 InvocationMirror::kConstructor, 9781 InvocationMirror::kConstructor,
9757 InvocationMirror::kMethod); 9782 InvocationMirror::kMethod,
9783 &constructor);
9758 } else if (constructor.IsRedirectingFactory()) { 9784 } else if (constructor.IsRedirectingFactory()) {
9759 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); 9785 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor);
9760 Type& redirect_type = Type::Handle(constructor.RedirectionType()); 9786 Type& redirect_type = Type::Handle(constructor.RedirectionType());
9761 if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) { 9787 if (!redirect_type.IsMalformed() && !redirect_type.IsInstantiated()) {
9762 // The type arguments of the redirection type are instantiated from the 9788 // The type arguments of the redirection type are instantiated from the
9763 // type arguments of the parsed type of the 'new' or 'const' expression. 9789 // type arguments of the parsed type of the 'new' or 'const' expression.
9764 Error& malformed_error = Error::Handle(); 9790 Error& malformed_error = Error::Handle();
9765 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, 9791 redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
9766 &malformed_error); 9792 &malformed_error);
9767 if (!malformed_error.IsNull()) { 9793 if (!malformed_error.IsNull()) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
9815 "for class '%s': %s", 9841 "for class '%s': %s",
9816 external_constructor_name.ToCString(), 9842 external_constructor_name.ToCString(),
9817 String::Handle(type_class.Name()).ToCString(), 9843 String::Handle(type_class.Name()).ToCString(),
9818 error_message.ToCString()); 9844 error_message.ToCString());
9819 } 9845 }
9820 return ThrowNoSuchMethodError(call_pos, 9846 return ThrowNoSuchMethodError(call_pos,
9821 type_class, 9847 type_class,
9822 external_constructor_name, 9848 external_constructor_name,
9823 arguments, 9849 arguments,
9824 InvocationMirror::kConstructor, 9850 InvocationMirror::kConstructor,
9825 InvocationMirror::kMethod); 9851 InvocationMirror::kMethod,
9852 &constructor);
9826 } 9853 }
9827 9854
9828 // Return a throw in case of a malformed type or report a compile-time error 9855 // Return a throw in case of a malformed type or report a compile-time error
9829 // if the constructor is const. 9856 // if the constructor is const.
9830 if (type.IsMalformed()) { 9857 if (type.IsMalformed()) {
9831 if (is_const) { 9858 if (is_const) {
9832 const Error& error = Error::Handle(type.malformed_error()); 9859 const Error& error = Error::Handle(type.malformed_error());
9833 ErrorMsg(error); 9860 ErrorMsg(error);
9834 } 9861 }
9835 return ThrowTypeError(type_pos, type); 9862 return ThrowTypeError(type_pos, type);
9836 } 9863 }
9837 type_arguments ^= type_arguments.Canonicalize(); 9864 type_arguments ^= type_arguments.Canonicalize();
9838 // Make the constructor call. 9865 // Make the constructor call.
9839 AstNode* new_object = NULL; 9866 AstNode* new_object = NULL;
9840 if (is_const) { 9867 if (is_const) {
9841 if (!constructor.is_const()) { 9868 if (!constructor.is_const()) {
9842 ErrorMsg("'const' requires const constructor: '%s'", 9869 const String& external_constructor_name =
9843 String::Handle(constructor.name()).ToCString()); 9870 (named_constructor ? constructor_name : type_class_name);
9871 ErrorMsg("non-const constructor '%s' cannot be used in "
9872 "const object creation",
9873 external_constructor_name.ToCString());
9844 } 9874 }
9845 const Object& constructor_result = Object::Handle( 9875 const Object& constructor_result = Object::Handle(
9846 EvaluateConstConstructorCall(type_class, 9876 EvaluateConstConstructorCall(type_class,
9847 type_arguments, 9877 type_arguments,
9848 constructor, 9878 constructor,
9849 arguments)); 9879 arguments));
9850 if (constructor_result.IsUnhandledException()) { 9880 if (constructor_result.IsUnhandledException()) {
9851 new_object = GenerateRethrow(new_pos, constructor_result); 9881 new_object = GenerateRethrow(new_pos, constructor_result);
9852 } else { 9882 } else {
9853 const Instance& const_instance = Instance::Cast(constructor_result); 9883 const Instance& const_instance = Instance::Cast(constructor_result);
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
10057 InvocationMirror::Type call_type = 10087 InvocationMirror::Type call_type =
10058 CurrentToken() == Token::kLPAREN ? 10088 CurrentToken() == Token::kLPAREN ?
10059 InvocationMirror::kMethod : InvocationMirror::kGetter; 10089 InvocationMirror::kMethod : InvocationMirror::kGetter;
10060 const String& unresolved_name = 10090 const String& unresolved_name =
10061 String::Cast(primary->AsPrimaryNode()->primary()); 10091 String::Cast(primary->AsPrimaryNode()->primary());
10062 primary = ThrowNoSuchMethodError(primary->token_pos(), 10092 primary = ThrowNoSuchMethodError(primary->token_pos(),
10063 current_class(), 10093 current_class(),
10064 unresolved_name, 10094 unresolved_name,
10065 NULL, // No arguments. 10095 NULL, // No arguments.
10066 InvocationMirror::kTopLevel, 10096 InvocationMirror::kTopLevel,
10067 call_type); 10097 call_type,
10098 NULL); // No existing function.
10068 } 10099 }
10069 } 10100 }
10070 ASSERT(primary != NULL); 10101 ASSERT(primary != NULL);
10071 } else if (CurrentToken() == Token::kTHIS) { 10102 } else if (CurrentToken() == Token::kTHIS) {
10072 LocalVariable* local = LookupLocalScope(Symbols::This()); 10103 LocalVariable* local = LookupLocalScope(Symbols::This());
10073 if (local == NULL) { 10104 if (local == NULL) {
10074 ErrorMsg("receiver 'this' is not in scope"); 10105 ErrorMsg("receiver 'this' is not in scope");
10075 } 10106 }
10076 primary = new LoadLocalNode(TokenPos(), local); 10107 primary = new LoadLocalNode(TokenPos(), local);
10077 ConsumeToken(); 10108 ConsumeToken();
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
10517 void Parser::SkipQualIdent() { 10548 void Parser::SkipQualIdent() {
10518 ASSERT(IsIdentifier()); 10549 ASSERT(IsIdentifier());
10519 ConsumeToken(); 10550 ConsumeToken();
10520 if (CurrentToken() == Token::kPERIOD) { 10551 if (CurrentToken() == Token::kPERIOD) {
10521 ConsumeToken(); // Consume the kPERIOD token. 10552 ConsumeToken(); // Consume the kPERIOD token.
10522 ExpectIdentifier("identifier expected after '.'"); 10553 ExpectIdentifier("identifier expected after '.'");
10523 } 10554 }
10524 } 10555 }
10525 10556
10526 } // namespace dart 10557 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698