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

Unified Diff: runtime/vm/parser.cc

Issue 40863002: Handle metadata with type literals or qualified identifiers. (Closed) Base URL: https://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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index fbd10686c53669b1b1c0611dcb28a82f702477a5..2209f780b18e646985bfb968f172c764e59ef261 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -893,6 +893,7 @@ RawArray* Parser::EvaluateMetadata() {
expr = ParseNewOperator(Token::kCONST);
} else {
expr = ParsePrimary();
+ expr = ParseQualified(expr);
}
if (expr->EvalConstExpr() == NULL) {
ErrorMsg(expr_pos, "expression must be a compile-time constant");
@@ -8429,6 +8430,106 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) {
}
+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.
+ AstNode* left = primary;
+ while (true) {
+ AstNode* selector = NULL;
+ if (CurrentToken() == Token::kPERIOD) {
+ ConsumeToken();
+ if (left->IsPrimaryNode()) {
+ if (left->AsPrimaryNode()->primary().IsFunction()) {
+ left = LoadClosure(left->AsPrimaryNode());
+ } else if (left->AsPrimaryNode()->primary().IsTypeParameter()) {
+ if (current_block_->scope->function_level() > 0) {
+ // Make sure that the instantiator is captured.
+ CaptureInstantiator();
+ }
+ TypeParameter& type_parameter = TypeParameter::ZoneHandle();
+ type_parameter ^= ClassFinalizer::FinalizeType(
+ current_class(),
+ TypeParameter::Cast(left->AsPrimaryNode()->primary()),
+ ClassFinalizer::kFinalize);
+ ASSERT(!type_parameter.IsMalformed());
+ left = new TypeNode(primary->token_pos(), type_parameter);
+ } 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");
+ if (CurrentToken() == Token::kLPAREN) {
hausner 2013/10/24 23:19:48 This can't happen for metadata.
+ // Identifier followed by a opening paren: method call.
+ if (left->IsPrimaryNode() &&
+ left->AsPrimaryNode()->primary().IsClass()) {
+ // Static method call prefixed with class name.
+ const Class& cls = Class::Cast(left->AsPrimaryNode()->primary());
+ selector = ParseStaticCall(cls, *ident, ident_pos);
+ } else {
+ selector = ParseInstanceCall(left, *ident);
+ }
+ } else {
+ // Field access.
+ 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.
+ selector = CallGetter(ident_pos, left, *ident);
+ } else {
+ // Static field access.
+ selector =
+ ParseStaticFieldAccess(cls, *ident, ident_pos, true);
+ }
+ }
+ } else {
+ // No (more) selectors to parse.
+ if (left->IsPrimaryNode()) {
+ PrimaryNode* primary = left->AsPrimaryNode();
+ if (primary->primary().IsFunction()) {
+ // 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);
+ } else if (primary->primary().IsTypeParameter()) {
+ if (current_block_->scope->function_level() > 0) {
+ // Make sure that the instantiator is captured.
+ CaptureInstantiator();
+ }
+ TypeParameter& type_parameter = TypeParameter::ZoneHandle();
+ type_parameter ^= ClassFinalizer::FinalizeType(
+ current_class(),
+ TypeParameter::Cast(primary->primary()),
+ ClassFinalizer::kFinalize);
+ ASSERT(!type_parameter.IsMalformed());
+ left = new TypeNode(primary->token_pos(), type_parameter);
+ }
+ }
+ // Done parsing selectors.
+ return left;
+ }
+ ASSERT(selector != NULL);
+ left = selector;
+ }
+}
+
+
AstNode* Parser::ParsePostfixExpr() {
TRACE_PARSER("ParsePostfixExpr");
String* expr_ident =

Powered by Google App Engine
This is Rietveld 408576698