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 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 886 AstNode* expr = NULL; | 886 AstNode* expr = NULL; |
| 887 if ((LookaheadToken(1) == Token::kLPAREN) || | 887 if ((LookaheadToken(1) == Token::kLPAREN) || |
| 888 ((LookaheadToken(1) == Token::kPERIOD) && | 888 ((LookaheadToken(1) == Token::kPERIOD) && |
| 889 (LookaheadToken(3) == Token::kLPAREN)) || | 889 (LookaheadToken(3) == Token::kLPAREN)) || |
| 890 ((LookaheadToken(1) == Token::kPERIOD) && | 890 ((LookaheadToken(1) == Token::kPERIOD) && |
| 891 (LookaheadToken(3) == Token::kPERIOD) && | 891 (LookaheadToken(3) == Token::kPERIOD) && |
| 892 (LookaheadToken(5) == Token::kLPAREN))) { | 892 (LookaheadToken(5) == Token::kLPAREN))) { |
| 893 expr = ParseNewOperator(Token::kCONST); | 893 expr = ParseNewOperator(Token::kCONST); |
| 894 } else { | 894 } else { |
| 895 expr = ParsePrimary(); | 895 expr = ParsePrimary(); |
| 896 expr = ParseQualified(expr); | |
| 896 } | 897 } |
| 897 if (expr->EvalConstExpr() == NULL) { | 898 if (expr->EvalConstExpr() == NULL) { |
| 898 ErrorMsg(expr_pos, "expression must be a compile-time constant"); | 899 ErrorMsg(expr_pos, "expression must be a compile-time constant"); |
| 899 } | 900 } |
| 900 const Instance& val = EvaluateConstExpr(expr); | 901 const Instance& val = EvaluateConstExpr(expr); |
| 901 meta_values.Add(val); | 902 meta_values.Add(val); |
| 902 } | 903 } |
| 903 return Array::MakeArray(meta_values); | 904 return Array::MakeArray(meta_values); |
| 904 } | 905 } |
| 905 | 906 |
| (...skipping 7516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8422 } | 8423 } |
| 8423 // Done parsing selectors. | 8424 // Done parsing selectors. |
| 8424 return left; | 8425 return left; |
| 8425 } | 8426 } |
| 8426 ASSERT(selector != NULL); | 8427 ASSERT(selector != NULL); |
| 8427 left = selector; | 8428 left = selector; |
| 8428 } | 8429 } |
| 8429 } | 8430 } |
| 8430 | 8431 |
| 8431 | 8432 |
| 8433 AstNode* Parser::ParseQualified(AstNode* primary) { | |
|
rmacnak
2013/10/24 21:33:56
Yuck. This is basically ParseSelectors with about
hausner
2013/10/24 23:19:48
I think this is way more complicated than need be.
| |
| 8434 AstNode* left = primary; | |
| 8435 while (true) { | |
| 8436 AstNode* selector = NULL; | |
| 8437 if (CurrentToken() == Token::kPERIOD) { | |
| 8438 ConsumeToken(); | |
| 8439 if (left->IsPrimaryNode()) { | |
| 8440 if (left->AsPrimaryNode()->primary().IsFunction()) { | |
| 8441 left = LoadClosure(left->AsPrimaryNode()); | |
| 8442 } else if (left->AsPrimaryNode()->primary().IsTypeParameter()) { | |
| 8443 if (current_block_->scope->function_level() > 0) { | |
| 8444 // Make sure that the instantiator is captured. | |
| 8445 CaptureInstantiator(); | |
| 8446 } | |
| 8447 TypeParameter& type_parameter = TypeParameter::ZoneHandle(); | |
| 8448 type_parameter ^= ClassFinalizer::FinalizeType( | |
| 8449 current_class(), | |
| 8450 TypeParameter::Cast(left->AsPrimaryNode()->primary()), | |
| 8451 ClassFinalizer::kFinalize); | |
| 8452 ASSERT(!type_parameter.IsMalformed()); | |
| 8453 left = new TypeNode(primary->token_pos(), type_parameter); | |
| 8454 } else { | |
| 8455 // Super field access handled in ParseSuperFieldAccess(), | |
| 8456 // super calls handled in ParseSuperCall(). | |
| 8457 ASSERT(!left->AsPrimaryNode()->IsSuper()); | |
| 8458 left = LoadFieldIfUnresolved(left); | |
| 8459 } | |
| 8460 } | |
| 8461 const intptr_t ident_pos = TokenPos(); | |
| 8462 String* ident = ExpectIdentifier("identifier expected"); | |
| 8463 if (CurrentToken() == Token::kLPAREN) { | |
|
hausner
2013/10/24 23:19:48
This can't happen for metadata.
| |
| 8464 // Identifier followed by a opening paren: method call. | |
| 8465 if (left->IsPrimaryNode() && | |
| 8466 left->AsPrimaryNode()->primary().IsClass()) { | |
| 8467 // Static method call prefixed with class name. | |
| 8468 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | |
| 8469 selector = ParseStaticCall(cls, *ident, ident_pos); | |
| 8470 } else { | |
| 8471 selector = ParseInstanceCall(left, *ident); | |
| 8472 } | |
| 8473 } else { | |
| 8474 // Field access. | |
| 8475 Class& cls = Class::Handle(); | |
| 8476 if (left->IsPrimaryNode()) { | |
| 8477 PrimaryNode* primary_node = left->AsPrimaryNode(); | |
| 8478 if (primary_node->primary().IsClass()) { | |
| 8479 // If the primary node referred to a class we are loading a | |
| 8480 // qualified static field. | |
| 8481 cls ^= primary_node->primary().raw(); | |
| 8482 } | |
| 8483 } | |
| 8484 if (cls.IsNull()) { | |
| 8485 // Instance field access. | |
| 8486 selector = CallGetter(ident_pos, left, *ident); | |
| 8487 } else { | |
| 8488 // Static field access. | |
| 8489 selector = | |
| 8490 ParseStaticFieldAccess(cls, *ident, ident_pos, true); | |
| 8491 } | |
| 8492 } | |
| 8493 } else { | |
| 8494 // No (more) selectors to parse. | |
| 8495 if (left->IsPrimaryNode()) { | |
| 8496 PrimaryNode* primary = left->AsPrimaryNode(); | |
| 8497 if (primary->primary().IsFunction()) { | |
| 8498 // Treat as implicit closure. | |
| 8499 left = LoadClosure(primary); | |
| 8500 } else if (primary->primary().IsClass()) { | |
| 8501 const Class& type_class = Class::Cast(primary->primary()); | |
| 8502 AbstractType& type = Type::ZoneHandle( | |
| 8503 Type::New(type_class, TypeArguments::Handle(), | |
| 8504 primary->token_pos(), Heap::kOld)); | |
| 8505 type = ClassFinalizer::FinalizeType( | |
| 8506 current_class(), type, ClassFinalizer::kCanonicalize); | |
| 8507 // Type may be malbounded, but not malformed. | |
| 8508 ASSERT(!type.IsMalformed()); | |
| 8509 left = new TypeNode(primary->token_pos(), type); | |
| 8510 } else if (primary->primary().IsTypeParameter()) { | |
| 8511 if (current_block_->scope->function_level() > 0) { | |
| 8512 // Make sure that the instantiator is captured. | |
| 8513 CaptureInstantiator(); | |
| 8514 } | |
| 8515 TypeParameter& type_parameter = TypeParameter::ZoneHandle(); | |
| 8516 type_parameter ^= ClassFinalizer::FinalizeType( | |
| 8517 current_class(), | |
| 8518 TypeParameter::Cast(primary->primary()), | |
| 8519 ClassFinalizer::kFinalize); | |
| 8520 ASSERT(!type_parameter.IsMalformed()); | |
| 8521 left = new TypeNode(primary->token_pos(), type_parameter); | |
| 8522 } | |
| 8523 } | |
| 8524 // Done parsing selectors. | |
| 8525 return left; | |
| 8526 } | |
| 8527 ASSERT(selector != NULL); | |
| 8528 left = selector; | |
| 8529 } | |
| 8530 } | |
| 8531 | |
| 8532 | |
| 8432 AstNode* Parser::ParsePostfixExpr() { | 8533 AstNode* Parser::ParsePostfixExpr() { |
| 8433 TRACE_PARSER("ParsePostfixExpr"); | 8534 TRACE_PARSER("ParsePostfixExpr"); |
| 8434 String* expr_ident = | 8535 String* expr_ident = |
| 8435 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8536 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8436 const intptr_t expr_pos = TokenPos(); | 8537 const intptr_t expr_pos = TokenPos(); |
| 8437 AstNode* expr = ParsePrimary(); | 8538 AstNode* expr = ParsePrimary(); |
| 8438 expr = ParseSelectors(expr, false); | 8539 expr = ParseSelectors(expr, false); |
| 8439 if (IsIncrementOperator(CurrentToken())) { | 8540 if (IsIncrementOperator(CurrentToken())) { |
| 8440 TRACE_PARSER("IncrementOperator"); | 8541 TRACE_PARSER("IncrementOperator"); |
| 8441 Token::Kind incr_op = CurrentToken(); | 8542 Token::Kind incr_op = CurrentToken(); |
| (...skipping 2169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10611 void Parser::SkipQualIdent() { | 10712 void Parser::SkipQualIdent() { |
| 10612 ASSERT(IsIdentifier()); | 10713 ASSERT(IsIdentifier()); |
| 10613 ConsumeToken(); | 10714 ConsumeToken(); |
| 10614 if (CurrentToken() == Token::kPERIOD) { | 10715 if (CurrentToken() == Token::kPERIOD) { |
| 10615 ConsumeToken(); // Consume the kPERIOD token. | 10716 ConsumeToken(); // Consume the kPERIOD token. |
| 10616 ExpectIdentifier("identifier expected after '.'"); | 10717 ExpectIdentifier("identifier expected after '.'"); |
| 10617 } | 10718 } |
| 10618 } | 10719 } |
| 10619 | 10720 |
| 10620 } // namespace dart | 10721 } // namespace dart |
| OLD | NEW |