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

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

Issue 134083005: Handle wrong method invocation of a type parameter (fix issue 13134). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 11 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
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 "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/bootstrap.h" 9 #include "vm/bootstrap.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 8398 matching lines...) Expand 10 before | Expand all | Expand 10 after
8409 const intptr_t bracket_pos = TokenPos(); 8409 const intptr_t bracket_pos = TokenPos();
8410 ConsumeToken(); 8410 ConsumeToken();
8411 left = LoadFieldIfUnresolved(left); 8411 left = LoadFieldIfUnresolved(left);
8412 const bool saved_mode = SetAllowFunctionLiterals(true); 8412 const bool saved_mode = SetAllowFunctionLiterals(true);
8413 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); 8413 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades);
8414 SetAllowFunctionLiterals(saved_mode); 8414 SetAllowFunctionLiterals(saved_mode);
8415 ExpectToken(Token::kRBRACK); 8415 ExpectToken(Token::kRBRACK);
8416 AstNode* array = left; 8416 AstNode* array = left;
8417 if (left->IsPrimaryNode()) { 8417 if (left->IsPrimaryNode()) {
8418 PrimaryNode* primary = left->AsPrimaryNode(); 8418 PrimaryNode* primary = left->AsPrimaryNode();
8419 const intptr_t primary_pos = primary->token_pos();
8419 if (primary->primary().IsFunction()) { 8420 if (primary->primary().IsFunction()) {
8420 array = LoadClosure(primary); 8421 array = LoadClosure(primary);
8421 } else if (primary->primary().IsClass()) { 8422 } else if (primary->primary().IsClass()) {
8422 const Class& type_class = Class::Cast(primary->primary()); 8423 const Class& type_class = Class::Cast(primary->primary());
8423 AbstractType& type = Type::ZoneHandle( 8424 AbstractType& type = Type::ZoneHandle(
8424 Type::New(type_class, TypeArguments::Handle(), 8425 Type::New(type_class, TypeArguments::Handle(),
8425 primary->token_pos(), Heap::kOld)); 8426 primary_pos, Heap::kOld));
8426 type ^= ClassFinalizer::FinalizeType( 8427 type ^= ClassFinalizer::FinalizeType(
8427 current_class(), type, ClassFinalizer::kCanonicalize); 8428 current_class(), type, ClassFinalizer::kCanonicalize);
8428 // Type may be malbounded, but not malformed. 8429 // Type may be malbounded, but not malformed.
8429 ASSERT(!type.IsMalformed()); 8430 ASSERT(!type.IsMalformed());
8430 array = new TypeNode(primary->token_pos(), type); 8431 array = new TypeNode(primary_pos, type);
8431 } else if (primary->primary().IsTypeParameter()) { 8432 } else if (primary->primary().IsTypeParameter()) {
8433 if (current_function().is_static()) {
8434 const String& name = String::ZoneHandle(
8435 TypeParameter::Cast(primary->primary()).name());
8436 ErrorMsg(primary_pos,
hausner 2014/01/18 00:29:55 I think you can factor this out. It is an error wi
regis 2014/01/18 00:48:53 I added the check for T.id, but I did not factor o
8437 "cannot access type parameter '%s' from static function",
8438 name.ToCString());
8439 }
8432 if (current_block_->scope->function_level() > 0) { 8440 if (current_block_->scope->function_level() > 0) {
8433 // Make sure that the instantiator is captured. 8441 // Make sure that the instantiator is captured.
8434 CaptureInstantiator(); 8442 CaptureInstantiator();
8435 } 8443 }
8436 TypeParameter& type_parameter = TypeParameter::ZoneHandle(); 8444 TypeParameter& type_parameter = TypeParameter::ZoneHandle();
8437 type_parameter ^= ClassFinalizer::FinalizeType( 8445 type_parameter ^= ClassFinalizer::FinalizeType(
8438 current_class(), 8446 current_class(),
8439 TypeParameter::Cast(primary->primary()), 8447 TypeParameter::Cast(primary->primary()),
8440 ClassFinalizer::kCanonicalize); 8448 ClassFinalizer::kCanonicalize);
8441 ASSERT(!type_parameter.IsMalformed()); 8449 ASSERT(!type_parameter.IsMalformed());
8442 array = new TypeNode(primary->token_pos(), type_parameter); 8450 array = new TypeNode(primary_pos, type_parameter);
8443 } else { 8451 } else {
8444 UNREACHABLE(); // Internal parser error. 8452 UNREACHABLE(); // Internal parser error.
8445 } 8453 }
8446 } 8454 }
8447 selector = new LoadIndexedNode(bracket_pos, 8455 selector = new LoadIndexedNode(bracket_pos,
8448 array, 8456 array,
8449 index, 8457 index,
8450 Class::ZoneHandle()); 8458 Class::ZoneHandle());
8451 } else if (CurrentToken() == Token::kLPAREN) { 8459 } else if (CurrentToken() == Token::kLPAREN) {
8452 if (left->IsPrimaryNode()) { 8460 if (left->IsPrimaryNode()) {
(...skipping 12 matching lines...) Expand all
8465 ErrorMsg(primary_pos, 8473 ErrorMsg(primary_pos,
8466 "cannot access instance method '%s' " 8474 "cannot access instance method '%s' "
8467 "from static function", 8475 "from static function",
8468 func_name.ToCString()); 8476 func_name.ToCString());
8469 } 8477 }
8470 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); 8478 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name);
8471 } 8479 }
8472 } else if (primary->primary().IsString()) { 8480 } else if (primary->primary().IsString()) {
8473 // Primary is an unresolved name. 8481 // Primary is an unresolved name.
8474 if (primary->IsSuper()) { 8482 if (primary->IsSuper()) {
8475 ErrorMsg(primary->token_pos(), "illegal use of super"); 8483 ErrorMsg(primary_pos, "illegal use of super");
8476 } 8484 }
8477 String& name = String::CheckedZoneHandle(primary->primary().raw()); 8485 String& name = String::CheckedZoneHandle(primary->primary().raw());
8478 if (current_function().is_static()) { 8486 if (current_function().is_static()) {
8479 selector = ThrowNoSuchMethodError(primary->token_pos(), 8487 selector = ThrowNoSuchMethodError(primary_pos,
8480 current_class(), 8488 current_class(),
8481 name, 8489 name,
8482 NULL, // No arguments. 8490 NULL, // No arguments.
8483 InvocationMirror::kStatic, 8491 InvocationMirror::kStatic,
8484 InvocationMirror::kMethod, 8492 InvocationMirror::kMethod,
8485 NULL); // No existing function. 8493 NULL); // No existing function.
8486 } else { 8494 } else {
8487 // Treat as call to unresolved (instance) method. 8495 // Treat as call to unresolved (instance) method.
8488 AstNode* receiver = LoadReceiver(primary->token_pos()); 8496 selector = ParseInstanceCall(LoadReceiver(primary_pos), name);
8489 selector = ParseInstanceCall(receiver, name);
8490 } 8497 }
8491 } else if (primary->primary().IsTypeParameter()) { 8498 } else if (primary->primary().IsTypeParameter()) {
8492 // TODO(regis): Issue 13134. Make sure the error message is the
8493 // one we want here and add a test covering this code.
8494 const String& name = String::ZoneHandle( 8499 const String& name = String::ZoneHandle(
8495 TypeParameter::Cast(primary->primary()).name()); 8500 TypeParameter::Cast(primary->primary()).name());
8496 selector = ThrowNoSuchMethodError(primary->token_pos(), 8501 if (current_function().is_static()) {
8497 current_class(), 8502 // Treat as this.T(), because T is in scope.
8498 name, 8503 ErrorMsg(primary_pos,
8499 NULL, // No arguments. 8504 "cannot access type parameter '%s' from static function",
8500 InvocationMirror::kStatic, 8505 name.ToCString());
8501 InvocationMirror::kMethod, 8506 } else {
8502 NULL); // No existing function. 8507 // Treat as call to unresolved (instance) method.
8508 selector = ParseInstanceCall(LoadReceiver(primary_pos), name);
8509 }
8503 } else if (primary->primary().IsClass()) { 8510 } else if (primary->primary().IsClass()) {
8504 const Class& type_class = Class::Cast(primary->primary()); 8511 const Class& type_class = Class::Cast(primary->primary());
8505 AbstractType& type = Type::ZoneHandle(Type::New( 8512 AbstractType& type = Type::ZoneHandle(Type::New(
8506 type_class, TypeArguments::Handle(), primary->token_pos())); 8513 type_class, TypeArguments::Handle(), primary_pos));
8507 type ^= ClassFinalizer::FinalizeType( 8514 type ^= ClassFinalizer::FinalizeType(
8508 current_class(), type, ClassFinalizer::kCanonicalize); 8515 current_class(), type, ClassFinalizer::kCanonicalize);
8509 // Type may be malbounded, but not malformed. 8516 // Type may be malbounded, but not malformed.
8510 ASSERT(!type.IsMalformed()); 8517 ASSERT(!type.IsMalformed());
8511 selector = new TypeNode(primary->token_pos(), type); 8518 selector = new TypeNode(primary_pos, type);
8512 } else { 8519 } else {
8513 UNREACHABLE(); // Internal parser error. 8520 UNREACHABLE(); // Internal parser error.
8514 } 8521 }
8515 } else { 8522 } else {
8516 // Left is not a primary node; this must be a closure call. 8523 // Left is not a primary node; this must be a closure call.
8517 AstNode* closure = left; 8524 AstNode* closure = left;
8518 selector = ParseClosureCall(closure); 8525 selector = ParseClosureCall(closure);
8519 } 8526 }
8520 } else { 8527 } else {
8521 // No (more) selectors to parse. 8528 // No (more) selectors to parse.
8522 left = LoadFieldIfUnresolved(left); 8529 left = LoadFieldIfUnresolved(left);
8523 if (left->IsPrimaryNode()) { 8530 if (left->IsPrimaryNode()) {
8524 PrimaryNode* primary = left->AsPrimaryNode(); 8531 PrimaryNode* primary = left->AsPrimaryNode();
8532 const intptr_t primary_pos = primary->token_pos();
8525 if (primary->primary().IsFunction()) { 8533 if (primary->primary().IsFunction()) {
8526 // Treat as implicit closure. 8534 // Treat as implicit closure.
8527 left = LoadClosure(primary); 8535 left = LoadClosure(primary);
8528 } else if (primary->primary().IsClass()) { 8536 } else if (primary->primary().IsClass()) {
8529 const Class& type_class = Class::Cast(primary->primary()); 8537 const Class& type_class = Class::Cast(primary->primary());
8530 AbstractType& type = Type::ZoneHandle(Type::New( 8538 AbstractType& type = Type::ZoneHandle(Type::New(
8531 type_class, TypeArguments::Handle(), primary->token_pos())); 8539 type_class, TypeArguments::Handle(), primary_pos));
8532 type = ClassFinalizer::FinalizeType( 8540 type = ClassFinalizer::FinalizeType(
8533 current_class(), type, ClassFinalizer::kCanonicalize); 8541 current_class(), type, ClassFinalizer::kCanonicalize);
8534 // Type may be malbounded, but not malformed. 8542 // Type may be malbounded, but not malformed.
8535 ASSERT(!type.IsMalformed()); 8543 ASSERT(!type.IsMalformed());
8536 left = new TypeNode(primary->token_pos(), type); 8544 left = new TypeNode(primary_pos, type);
8537 } else if (primary->primary().IsTypeParameter()) { 8545 } else if (primary->primary().IsTypeParameter()) {
8546 if (current_function().is_static()) {
8547 const String& name = String::ZoneHandle(
8548 TypeParameter::Cast(primary->primary()).name());
8549 ErrorMsg(primary_pos,
8550 "cannot access type parameter '%s' from static function",
8551 name.ToCString());
8552 }
8538 if (current_block_->scope->function_level() > 0) { 8553 if (current_block_->scope->function_level() > 0) {
8539 // Make sure that the instantiator is captured. 8554 // Make sure that the instantiator is captured.
8540 CaptureInstantiator(); 8555 CaptureInstantiator();
8541 } 8556 }
8542 TypeParameter& type_parameter = TypeParameter::ZoneHandle(); 8557 TypeParameter& type_parameter = TypeParameter::ZoneHandle();
8543 type_parameter ^= ClassFinalizer::FinalizeType( 8558 type_parameter ^= ClassFinalizer::FinalizeType(
8544 current_class(), 8559 current_class(),
8545 TypeParameter::Cast(primary->primary()), 8560 TypeParameter::Cast(primary->primary()),
8546 ClassFinalizer::kCanonicalize); 8561 ClassFinalizer::kCanonicalize);
8547 ASSERT(!type_parameter.IsMalformed()); 8562 ASSERT(!type_parameter.IsMalformed());
8548 left = new TypeNode(primary->token_pos(), type_parameter); 8563 left = new TypeNode(primary_pos, type_parameter);
8549 } else if (primary->IsSuper()) { 8564 } else if (primary->IsSuper()) {
8550 // Return "super" to handle unary super operator calls, 8565 // Return "super" to handle unary super operator calls,
8551 // or to report illegal use of "super" otherwise. 8566 // or to report illegal use of "super" otherwise.
8552 left = primary; 8567 left = primary;
8553 } else { 8568 } else {
8554 UNREACHABLE(); // Internal parser error. 8569 UNREACHABLE(); // Internal parser error.
8555 } 8570 }
8556 } 8571 }
8557 // Done parsing selectors. 8572 // Done parsing selectors.
8558 return left; 8573 return left;
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
9222 return new TypeNode(ident_pos, type_parameter); 9237 return new TypeNode(ident_pos, type_parameter);
9223 } 9238 }
9224 } 9239 }
9225 // Not found in the local scope, and the name is not a type parameter. 9240 // Not found in the local scope, and the name is not a type parameter.
9226 // Try finding the variable in the library scope (current library 9241 // Try finding the variable in the library scope (current library
9227 // and all libraries imported by it without a library prefix). 9242 // and all libraries imported by it without a library prefix).
9228 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); 9243 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident);
9229 } 9244 }
9230 if (resolved->IsPrimaryNode()) { 9245 if (resolved->IsPrimaryNode()) {
9231 PrimaryNode* primary = resolved->AsPrimaryNode(); 9246 PrimaryNode* primary = resolved->AsPrimaryNode();
9247 const intptr_t primary_pos = primary->token_pos();
9232 if (primary->primary().IsString()) { 9248 if (primary->primary().IsString()) {
9233 // We got an unresolved name. If we are compiling a static 9249 // We got an unresolved name. If we are compiling a static
9234 // method, evaluation of an unresolved identifier causes a 9250 // method, evaluation of an unresolved identifier causes a
9235 // NoSuchMethodError to be thrown. In an instance method, we convert 9251 // NoSuchMethodError to be thrown. In an instance method, we convert
9236 // the unresolved name to an instance field access, since a 9252 // the unresolved name to an instance field access, since a
9237 // subclass might define a field with this name. 9253 // subclass might define a field with this name.
9238 if (current_function().is_static()) { 9254 if (current_function().is_static()) {
9239 resolved = ThrowNoSuchMethodError(ident_pos, 9255 resolved = ThrowNoSuchMethodError(ident_pos,
9240 current_class(), 9256 current_class(),
9241 ident, 9257 ident,
9242 NULL, // No arguments. 9258 NULL, // No arguments.
9243 InvocationMirror::kStatic, 9259 InvocationMirror::kStatic,
9244 InvocationMirror::kField, 9260 InvocationMirror::kField,
9245 NULL); // No existing function. 9261 NULL); // No existing function.
9246 } else { 9262 } else {
9247 // Treat as call to unresolved instance field. 9263 // Treat as call to unresolved instance field.
9248 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); 9264 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
9249 } 9265 }
9250 } else if (primary->primary().IsFunction()) { 9266 } else if (primary->primary().IsFunction()) {
9251 if (allow_closure_names) { 9267 if (allow_closure_names) {
9252 resolved = LoadClosure(primary); 9268 resolved = LoadClosure(primary);
9253 } else { 9269 } else {
9254 ErrorMsg(ident_pos, "illegal reference to method '%s'", 9270 ErrorMsg(ident_pos, "illegal reference to method '%s'",
9255 ident.ToCString()); 9271 ident.ToCString());
9256 } 9272 }
9257 } else if (primary->primary().IsClass()) { 9273 } else if (primary->primary().IsClass()) {
9258 const Class& type_class = Class::Cast(primary->primary()); 9274 const Class& type_class = Class::Cast(primary->primary());
9259 AbstractType& type = Type::ZoneHandle( 9275 AbstractType& type = Type::ZoneHandle(
9260 Type::New(type_class, TypeArguments::Handle(), primary->token_pos())); 9276 Type::New(type_class, TypeArguments::Handle(), primary_pos));
9261 type ^= ClassFinalizer::FinalizeType( 9277 type ^= ClassFinalizer::FinalizeType(
9262 current_class(), type, ClassFinalizer::kCanonicalize); 9278 current_class(), type, ClassFinalizer::kCanonicalize);
9263 // Type may be malbounded, but not malformed. 9279 // Type may be malbounded, but not malformed.
9264 ASSERT(!type.IsMalformed()); 9280 ASSERT(!type.IsMalformed());
9265 resolved = new TypeNode(primary->token_pos(), type); 9281 resolved = new TypeNode(primary_pos, type);
9266 } 9282 }
9267 } 9283 }
9268 return resolved; 9284 return resolved;
9269 } 9285 }
9270 9286
9271 9287
9272 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and 9288 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and
9273 // finalize it according to the given type finalization mode. 9289 // finalize it according to the given type finalization mode.
9274 RawAbstractType* Parser::ParseType( 9290 RawAbstractType* Parser::ParseType(
9275 ClassFinalizer::FinalizationKind finalization) { 9291 ClassFinalizer::FinalizationKind finalization) {
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after
10750 void Parser::SkipQualIdent() { 10766 void Parser::SkipQualIdent() {
10751 ASSERT(IsIdentifier()); 10767 ASSERT(IsIdentifier());
10752 ConsumeToken(); 10768 ConsumeToken();
10753 if (CurrentToken() == Token::kPERIOD) { 10769 if (CurrentToken() == Token::kPERIOD) {
10754 ConsumeToken(); // Consume the kPERIOD token. 10770 ConsumeToken(); // Consume the kPERIOD token.
10755 ExpectIdentifier("identifier expected after '.'"); 10771 ExpectIdentifier("identifier expected after '.'");
10756 } 10772 }
10757 } 10773 }
10758 10774
10759 } // namespace dart 10775 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | tests/language/language_dart2js.status » ('j') | tests/language/type_variable_conflict2_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698