Index: runtime/vm/parser.cc |
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
index de042e4972d6ffb9487b4b8a3bede5ec4a773871..8667c209b17f2dc935d1dbc8eeb05e9ddd4a020c 100644 |
--- a/runtime/vm/parser.cc |
+++ b/runtime/vm/parser.cc |
@@ -274,7 +274,6 @@ Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) |
token_kind_(Token::kILLEGAL), |
current_block_(NULL), |
is_top_level_(false), |
- parsing_metadata_(false), |
current_member_(NULL), |
allow_function_literals_(true), |
parsed_function_(NULL), |
@@ -301,7 +300,6 @@ Parser::Parser(const Script& script, |
token_kind_(Token::kILLEGAL), |
current_block_(NULL), |
is_top_level_(false), |
- parsing_metadata_(false), |
current_member_(NULL), |
allow_function_literals_(true), |
parsed_function_(parsed_function), |
@@ -886,10 +884,24 @@ RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) { |
LongJumpScope jump; |
if (setjmp(*jump.Set()) == 0) { |
const Script& script = Script::Handle(isolate, cls.script()); |
- const Library& lib = Library::Handle(isolate, cls.library()); |
- Parser parser(script, lib, token_pos); |
+ // Parsing metadata can involve following paths in the parser that are |
+ // normally used for expressions and assume current_function is non-null, |
+ // so we create a fake function to use as the current_function rather than |
+ // scattering special cases throughout the parser. |
+ const Function& fake_function = Function::ZoneHandle(Function::New( |
+ Symbols::At(), |
+ RawFunction::kRegularFunction, |
+ true, // is_static |
+ false, // is_const |
+ false, // is_abstract |
+ false, // is_external |
+ false, // is_native |
+ cls, |
+ token_pos)); |
+ ParsedFunction* parsed_function = |
+ new ParsedFunction(isolate, fake_function); |
+ Parser parser(script, parsed_function, token_pos); |
parser.set_current_class(cls); |
- parser.set_parsing_metadata(true); |
RawObject* metadata = parser.EvaluateMetadata(); |
return metadata; |
@@ -8490,13 +8502,7 @@ AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
// NoSuchMethodError to be thrown. |
// In an instance method, we convert this into a getter call |
// for a field (which may be defined in a subclass.) |
- // In metadata, an unresolved identifier cannot be a compile-time constant. |
String& name = String::CheckedZoneHandle(primary->primary().raw()); |
- if (parsing_metadata_) { |
- ErrorMsg(primary->token_pos(), |
- "unresolved identifier '%s' is not a compile-time constant", |
- name.ToCString()); |
- } |
if (current_function().is_static() || |
current_function().IsInFactoryScope()) { |
StaticGetterNode* getter = |
@@ -8530,11 +8536,6 @@ AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
return closure; |
} else { |
// Instance function access. |
- if (parsing_metadata_) { |
- ErrorMsg(primary->token_pos(), |
- "cannot access instance method '%s' from metadata", |
- funcname.ToCString()); |
- } |
if (current_function().is_static() || |
current_function().IsInFactoryScope()) { |
ErrorMsg(primary->token_pos(), |
@@ -8737,14 +8738,6 @@ AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
} else { |
// Left is not a primary node; this must be a closure call. |
AstNode* closure = left; |
- if (parsing_metadata_) { |
- // Compiling closure calls involves saving the current context based |
- // on the current function, and metadata has no current function. |
- // Fail early rather than limping along only to discover later that |
- // we parsed something that isn't a compile-time constant. |
- ErrorMsg(closure->token_pos(), |
- "expression is not a valid compile-time constant"); |
- } |
selector = ParseClosureCall(closure); |
} |
} else { |
@@ -8954,11 +8947,6 @@ void Parser::CheckInstanceFieldAccess(intptr_t field_pos, |
const String& field_name) { |
// Fields are not accessible from a static function, except from a |
// constructor, which is considered as non-static by the compiler. |
- if (parsing_metadata_) { |
- ErrorMsg(field_pos, |
- "cannot access instance field '%s' from metadata", |
- field_name.ToCString()); |
- } |
if (current_function().is_static()) { |
ErrorMsg(field_pos, |
"cannot access instance field '%s' from a static function", |
@@ -9146,11 +9134,8 @@ RawObject* Parser::EvaluateConstConstructorCall( |
if (result.IsError()) { |
// An exception may not occur in every parse attempt, i.e., the |
// generated AST is not deterministic. Therefore mark the function as |
- // not optimizable. Unless we are evaluating metadata, in which case there |
- // is no current function. |
- if (!parsing_metadata_) { |
- current_function().SetIsOptimizable(false); |
- } |
+ // not optimizable. |
+ current_function().SetIsOptimizable(false); |
if (result.IsUnhandledException()) { |
return result.raw(); |
} else { |
@@ -9247,11 +9232,6 @@ bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
// be found. |
AstNode* receiver = NULL; |
const bool kTestOnly = true; |
- if (parsing_metadata_) { |
- ErrorMsg(ident_pos, |
- "'%s' is not a compile-time constant", |
- ident.ToCString()); |
- } |
if (!current_function().is_static() && |
(LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { |
receiver = LoadReceiver(ident_pos); |
@@ -10640,9 +10620,6 @@ AstNode* Parser::ParsePrimary() { |
} else if (token == Token::kHASH) { |
primary = ParseSymbolLiteral(); |
} else if (token == Token::kSUPER) { |
- if (parsing_metadata_) { |
- ErrorMsg("cannot access superclass from metadata"); |
- } |
if (current_function().is_static()) { |
ErrorMsg("cannot access superclass from static method"); |
} |