Chromium Code Reviews| Index: runtime/vm/parser.cc |
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
| index afa71beee5919fad213108cebfc09f741e116c06..f1ef9d0923358d4626921b012ab5ab732123f92d 100644 |
| --- a/runtime/vm/parser.cc |
| +++ b/runtime/vm/parser.cc |
| @@ -877,6 +877,7 @@ RawArray* Parser::EvaluateMetadata() { |
| expr = ParseNewOperator(Token::kCONST); |
| } else { |
| expr = ParsePrimary(); |
| + expr = ParseMemberSelection(expr); |
| } |
| if (expr->EvalConstExpr() == NULL) { |
| ErrorMsg(expr_pos, "expression must be a compile-time constant"); |
| @@ -8419,6 +8420,64 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
| } |
| +AstNode* Parser::ParseMemberSelection(AstNode* primary) { |
| + AstNode* left = primary; |
| + |
| + if (CurrentToken() == Token::kPERIOD) { |
| + ConsumeToken(); |
| + if (left->IsPrimaryNode()) { |
| + if (left->AsPrimaryNode()->primary().IsFunction()) { |
|
hausner
2013/10/25 20:24:25
I still don't understand why you handle this case.
|
| + left = LoadClosure(left->AsPrimaryNode()); |
| + } else { |
| + // Super field access handled in ParseSuperFieldAccess(), |
| + // super calls handled in ParseSuperCall(). |
| + ASSERT(!left->AsPrimaryNode()->IsSuper()); |
| + left = LoadFieldIfUnresolved(left); |
| + } |
| + } |
| + const intptr_t ident_pos = TokenPos(); |
| + String* ident = ExpectIdentifier("identifier expected"); |
| + |
| + Class& cls = Class::Handle(); |
| + if (left->IsPrimaryNode()) { |
| + PrimaryNode* primary_node = left->AsPrimaryNode(); |
| + if (primary_node->primary().IsClass()) { |
| + // If the primary node referred to a class we are loading a |
| + // qualified static field. |
| + cls ^= primary_node->primary().raw(); |
| + } |
| + } |
| + if (cls.IsNull()) { |
| + // Instance field access. |
| + return CallGetter(ident_pos, left, *ident); |
| + } else { |
| + // Static field access. |
| + return ParseStaticFieldAccess(cls, *ident, ident_pos, true); |
| + } |
| + } |
| + |
| + // No selector to parse. |
| + if (left->IsPrimaryNode()) { |
| + PrimaryNode* primary = left->AsPrimaryNode(); |
| + if (primary->primary().IsFunction()) { |
|
hausner
2013/10/25 20:24:25
ditto
|
| + // Treat as implicit closure. |
| + left = LoadClosure(primary); |
| + } else if (primary->primary().IsClass()) { |
| + const Class& type_class = Class::Cast(primary->primary()); |
| + AbstractType& type = Type::ZoneHandle( |
| + Type::New(type_class, TypeArguments::Handle(), |
| + primary->token_pos(), Heap::kOld)); |
| + type = ClassFinalizer::FinalizeType( |
| + current_class(), type, ClassFinalizer::kCanonicalize); |
| + // Type may be malbounded, but not malformed. |
| + ASSERT(!type.IsMalformed()); |
| + left = new TypeNode(primary->token_pos(), type); |
| + } |
| + } |
| + return left; |
| +} |
| + |
| + |
| AstNode* Parser::ParsePostfixExpr() { |
| TRACE_PARSER("ParsePostfixExpr"); |
| String* expr_ident = |