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 "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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |