| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 20386)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -261,7 +261,7 @@
|
|
|
| // For parsing a compilation unit.
|
| Parser::Parser(const Script& script, const Library& library)
|
| - : script_(script),
|
| + : script_(Script::Handle(script.raw())),
|
| tokens_iterator_(TokenStream::Handle(script.tokens()), 0),
|
| token_kind_(Token::kILLEGAL),
|
| current_block_(NULL),
|
| @@ -271,7 +271,7 @@
|
| parsed_function_(NULL),
|
| innermost_function_(Function::Handle()),
|
| current_class_(Class::Handle()),
|
| - library_(library),
|
| + library_(Library::Handle(library.raw())),
|
| try_blocks_list_(NULL) {
|
| ASSERT(tokens_iterator_.IsValid());
|
| ASSERT(!library.IsNull());
|
| @@ -282,7 +282,7 @@
|
| Parser::Parser(const Script& script,
|
| ParsedFunction* parsed_function,
|
| intptr_t token_position)
|
| - : script_(script),
|
| + : script_(Script::Handle(script.raw())),
|
| tokens_iterator_(TokenStream::Handle(script.tokens()), token_position),
|
| token_kind_(Token::kILLEGAL),
|
| current_block_(NULL),
|
| @@ -303,6 +303,13 @@
|
| }
|
|
|
|
|
| +void Parser::SetScript(const Script & script, intptr_t token_pos) {
|
| + script_ = script.raw();
|
| + tokens_iterator_.SetStream(TokenStream::Handle(script.tokens()), token_pos);
|
| + token_kind_ = Token::kILLEGAL;
|
| +}
|
| +
|
| +
|
| bool Parser::SetAllowFunctionLiterals(bool value) {
|
| bool current_value = allow_function_literals_;
|
| allow_function_literals_ = value;
|
| @@ -1831,6 +1838,40 @@
|
| }
|
|
|
|
|
| +AstNode* Parser::ParseExternalInitializedField(const Field& field) {
|
| + // Only use this function if the initialized field originates
|
| + // from a different class. We need to save and restore current
|
| + // class, library, and token stream (script).
|
| + ASSERT(current_class().raw() != field.origin());
|
| + const Class& saved_class = Class::Handle(current_class().raw());
|
| + const Library& saved_library = Library::Handle(library().raw());
|
| + const Script& saved_script = Script::Handle(script().raw());
|
| + const intptr_t saved_token_pos = TokenPos();
|
| +
|
| + set_current_class(Class::Handle(field.origin()));
|
| + set_library(Library::Handle(current_class().library()));
|
| + SetScript(Script::Handle(current_class().script()), field.token_pos());
|
| +
|
| + ASSERT(IsIdentifier());
|
| + ConsumeToken();
|
| + ExpectToken(Token::kASSIGN);
|
| + AstNode* init_expr = NULL;
|
| + if (field.is_const()) {
|
| + init_expr = ParseConstExpr();
|
| + } else {
|
| + init_expr = ParseExpr(kAllowConst, kConsumeCascades);
|
| + if (init_expr->EvalConstExpr() != NULL) {
|
| + init_expr =
|
| + new LiteralNode(field.token_pos(), EvaluateConstExpr(init_expr));
|
| + }
|
| + }
|
| + set_current_class(saved_class);
|
| + set_library(saved_library);
|
| + SetScript(saved_script, saved_token_pos);
|
| + return init_expr;
|
| +}
|
| +
|
| +
|
| void Parser::ParseInitializedInstanceFields(const Class& cls,
|
| LocalVariable* receiver,
|
| GrowableArray<Field*>* initialized_fields) {
|
| @@ -1849,26 +1890,22 @@
|
| // initialized.
|
| initialized_fields->Add(&field);
|
| }
|
| - intptr_t field_pos = field.token_pos();
|
| + AstNode* init_expr = NULL;
|
| if (current_class().raw() != field.origin()) {
|
| - const Class& origin_class = Class::Handle(field.origin());
|
| - if (origin_class.library() != library_.raw()) {
|
| - ErrorMsg("Cannot handle initialized mixin field '%s'"
|
| - "from imported library\n", field.ToCString());
|
| - }
|
| - }
|
| - SetPosition(field_pos);
|
| - ASSERT(IsIdentifier());
|
| - ConsumeToken();
|
| - ExpectToken(Token::kASSIGN);
|
| -
|
| - AstNode* init_expr = NULL;
|
| - if (field.is_const()) {
|
| - init_expr = ParseConstExpr();
|
| + init_expr = ParseExternalInitializedField(field);
|
| } else {
|
| - init_expr = ParseExpr(kAllowConst, kConsumeCascades);
|
| - if (init_expr->EvalConstExpr() != NULL) {
|
| - init_expr = new LiteralNode(field_pos, EvaluateConstExpr(init_expr));
|
| + SetPosition(field.token_pos());
|
| + ASSERT(IsIdentifier());
|
| + ConsumeToken();
|
| + ExpectToken(Token::kASSIGN);
|
| + if (field.is_const()) {
|
| + init_expr = ParseConstExpr();
|
| + } else {
|
| + init_expr = ParseExpr(kAllowConst, kConsumeCascades);
|
| + if (init_expr->EvalConstExpr() != NULL) {
|
| + init_expr = new LiteralNode(field.token_pos(),
|
| + EvaluateConstExpr(init_expr));
|
| + }
|
| }
|
| }
|
| ASSERT(init_expr != NULL);
|
|
|