| Index: runtime/vm/parser.cc
|
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
|
| index ecdfc5874e6301287baf8e8c6ccbb7a9987aebd1..df88dbfe7dd7c3a665f32e5c0112221c6a9fa432 100644
|
| --- a/runtime/vm/parser.cc
|
| +++ b/runtime/vm/parser.cc
|
| @@ -1008,13 +1008,15 @@ void Parser::ParseFunction(ParsedFunction* parsed_function) {
|
| }
|
|
|
|
|
| -RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) {
|
| +RawObject* Parser::ParseMetadata(const Field& meta_data) {
|
| LongJumpScope jump;
|
| if (setjmp(*jump.Set()) == 0) {
|
| Thread* thread = Thread::Current();
|
| StackZone stack_zone(thread);
|
| Zone* zone = stack_zone.GetZone();
|
| - const Script& script = Script::Handle(zone, cls.script());
|
| + const Class& owner_class = Class::Handle(zone, meta_data.owner());
|
| + const Script& script = Script::Handle(zone, meta_data.script());
|
| + const intptr_t token_pos = meta_data.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
|
| @@ -1027,13 +1029,13 @@ RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) {
|
| false, // is_abstract
|
| false, // is_external
|
| false, // is_native
|
| - cls,
|
| + Object::Handle(zone, meta_data.RawOwner()),
|
| token_pos));
|
| fake_function.set_is_debuggable(false);
|
| ParsedFunction* parsed_function =
|
| new ParsedFunction(thread, fake_function);
|
| Parser parser(script, parsed_function, token_pos);
|
| - parser.set_current_class(cls);
|
| + parser.set_current_class(owner_class);
|
|
|
| RawObject* metadata = parser.EvaluateMetadata();
|
| return metadata;
|
| @@ -1149,18 +1151,14 @@ ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) {
|
| // TODO(koda): Should there be a StackZone here?
|
| Zone* zone = thread->zone();
|
|
|
| - const Class& script_cls = Class::Handle(zone, field.origin());
|
| - const Script& script = Script::Handle(zone, script_cls.script());
|
| -
|
| const String& field_name = String::Handle(zone, field.name());
|
| String& init_name = String::Handle(zone,
|
| Symbols::FromConcat(Symbols::InitPrefix(), field_name));
|
|
|
| + const Script& script = Script::Handle(zone, field.script());
|
| Object& initializer_owner = Object::Handle(field.owner());
|
| - if (field.owner() != field.origin()) {
|
| - initializer_owner =
|
| - PatchClass::New(Class::Handle(field.owner()), script_cls);
|
| - }
|
| + initializer_owner =
|
| + PatchClass::New(Class::Handle(field.owner()), script);
|
|
|
| const Function& initializer = Function::ZoneHandle(zone,
|
| Function::New(init_name,
|
| @@ -1851,6 +1849,13 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value,
|
| const bool no_explicit_default_values = false;
|
| ParseFormalParameterList(no_explicit_default_values, false, &func_params);
|
|
|
| + // In top-level and mixin functions, the source may be in a different
|
| + // script than the script of the current class.
|
| + Object& sig_func_owner = Object::Handle(Z, current_class().raw());
|
| + if (current_class().script() != script_.raw()) {
|
| + sig_func_owner = PatchClass::New(current_class(), script_);
|
| + }
|
| +
|
| // The field 'is_static' has no meaning for signature functions.
|
| const Function& signature_function = Function::Handle(Z,
|
| Function::New(*parameter.name,
|
| @@ -1860,18 +1865,18 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value,
|
| /* is_abstract = */ false,
|
| /* is_external = */ false,
|
| /* is_native = */ false,
|
| - current_class(),
|
| + sig_func_owner,
|
| parameter.name_pos));
|
| signature_function.set_result_type(result_type);
|
| signature_function.set_is_debuggable(false);
|
| AddFormalParamsToFunction(&func_params, signature_function);
|
| - const String& signature = String::Handle(Z,
|
| - signature_function.Signature());
|
| + const String& signature =
|
| + String::Handle(Z, signature_function.Signature());
|
| // Lookup the signature class, i.e. the class whose name is the signature.
|
| // We only lookup in the current library, but not in its imports, and only
|
| // create a new canonical signature class if it does not exist yet.
|
| - Class& signature_class = Class::ZoneHandle(Z,
|
| - library_.LookupLocalClass(signature));
|
| + Class& signature_class =
|
| + Class::ZoneHandle(Z, library_.LookupLocalClass(signature));
|
| if (signature_class.IsNull()) {
|
| signature_class = Class::NewSignatureClass(signature,
|
| signature_function,
|
| @@ -4418,7 +4423,7 @@ void Parser::ParseClassMemberDefinition(ClassDesc* members,
|
|
|
|
|
| void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
|
| - const Class& toplevel_class,
|
| + const Object& tl_owner,
|
| intptr_t metadata_pos) {
|
| TRACE_PARSER("ParseEnumDeclaration");
|
| const intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos
|
| @@ -4460,7 +4465,7 @@ void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
|
| cls.set_is_synthesized_class();
|
| cls.set_is_enum_class();
|
| if (metadata_pos >= 0) {
|
| - library_.AddClassMetadata(cls, toplevel_class, metadata_pos);
|
| + library_.AddClassMetadata(cls, tl_owner, metadata_pos);
|
| }
|
| cls.set_super_type(Type::Handle(Z, Type::ObjectType()));
|
| pending_classes.Add(cls, Heap::kOld);
|
| @@ -4468,7 +4473,7 @@ void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
|
|
|
|
|
| void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes,
|
| - const Class& toplevel_class,
|
| + const Object& tl_owner,
|
| intptr_t metadata_pos) {
|
| TRACE_PARSER("ParseClassDeclaration");
|
| bool is_patch = false;
|
| @@ -4583,7 +4588,7 @@ void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes,
|
| cls.set_is_abstract();
|
| }
|
| if (metadata_pos >= 0) {
|
| - library_.AddClassMetadata(cls, toplevel_class, metadata_pos);
|
| + library_.AddClassMetadata(cls, tl_owner, metadata_pos);
|
| }
|
|
|
| const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN);
|
| @@ -4963,7 +4968,7 @@ void Parser::CheckConstructors(ClassDesc* class_desc) {
|
|
|
| void Parser::ParseMixinAppAlias(
|
| const GrowableObjectArray& pending_classes,
|
| - const Class& toplevel_class,
|
| + const Object& tl_owner,
|
| intptr_t metadata_pos) {
|
| TRACE_PARSER("ParseMixinAppAlias");
|
| const intptr_t classname_pos = TokenPos();
|
| @@ -5017,7 +5022,7 @@ void Parser::ParseMixinAppAlias(
|
| ExpectSemicolon();
|
| pending_classes.Add(mixin_application, Heap::kOld);
|
| if (metadata_pos >= 0) {
|
| - library_.AddClassMetadata(mixin_application, toplevel_class, metadata_pos);
|
| + library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos);
|
| }
|
| }
|
|
|
| @@ -5063,7 +5068,7 @@ bool Parser::IsMixinAppAlias() {
|
|
|
|
|
| void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
|
| - const Class& toplevel_class,
|
| + const Object& tl_owner,
|
| intptr_t metadata_pos) {
|
| TRACE_PARSER("ParseTypedef");
|
| intptr_t declaration_pos = (metadata_pos > 0) ? metadata_pos : TokenPos();
|
| @@ -5073,7 +5078,7 @@ void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
|
| if (FLAG_warn_mixin_typedef) {
|
| ReportWarning(TokenPos(), "deprecated mixin application typedef");
|
| }
|
| - ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos);
|
| + ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos);
|
| return;
|
| }
|
|
|
| @@ -5184,7 +5189,7 @@ void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
|
| pending_classes.Add(function_type_alias, Heap::kOld);
|
| if (metadata_pos >= 0) {
|
| library_.AddClassMetadata(function_type_alias,
|
| - toplevel_class,
|
| + tl_owner,
|
| metadata_pos);
|
| }
|
| }
|
| @@ -5421,6 +5426,7 @@ RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
|
|
|
|
|
| void Parser::ParseTopLevelVariable(TopLevel* top_level,
|
| + const Object& owner,
|
| intptr_t metadata_pos) {
|
| TRACE_PARSER("ParseTopLevelVariable");
|
| const bool is_const = (CurrentToken() == Token::kCONST);
|
| @@ -5456,8 +5462,10 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level,
|
|
|
| const bool is_reflectable =
|
| !(library_.is_dart_scheme() && library_.IsPrivate(var_name));
|
| - field = Field::New(var_name, is_static, is_final, is_const, is_reflectable,
|
| - current_class(), type, name_pos);
|
| +
|
| + field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos);
|
| + field.SetFieldType(type);
|
| + field.set_is_reflectable(is_reflectable);
|
| field.SetStaticValue(Object::null_instance(), true);
|
| top_level->AddField(field);
|
| library_.AddObject(field, var_name);
|
| @@ -5485,13 +5493,11 @@ void Parser::ParseTopLevelVariable(TopLevel* top_level,
|
| /* is_abstract = */ false,
|
| /* is_external = */ false,
|
| /* is_native = */ false,
|
| - current_class(),
|
| + owner,
|
| name_pos);
|
| getter.set_result_type(type);
|
| getter.set_is_debuggable(false);
|
| - if (library_.is_dart_scheme() && library_.IsPrivate(var_name)) {
|
| - getter.set_is_reflectable(false);
|
| - }
|
| + getter.set_is_reflectable(is_reflectable);
|
| top_level->AddFunction(getter);
|
| }
|
| } else if (is_final) {
|
| @@ -5538,6 +5544,7 @@ RawFunction::AsyncModifier Parser::ParseFunctionModifier() {
|
|
|
|
|
| void Parser::ParseTopLevelFunction(TopLevel* top_level,
|
| + const Object& owner,
|
| intptr_t metadata_pos) {
|
| TRACE_PARSER("ParseTopLevelFunction");
|
| const intptr_t decl_begin_pos = TokenPos();
|
| @@ -5629,7 +5636,7 @@ void Parser::ParseTopLevelFunction(TopLevel* top_level,
|
| /* is_abstract = */ false,
|
| is_external,
|
| is_native,
|
| - current_class(),
|
| + owner,
|
| decl_begin_pos));
|
| func.set_result_type(result_type);
|
| func.set_end_token_pos(function_end_pos);
|
| @@ -5645,6 +5652,12 @@ void Parser::ParseTopLevelFunction(TopLevel* top_level,
|
| if (!is_patch) {
|
| library_.AddObject(func, func_name);
|
| } else {
|
| + // Need to remove the previously added function that is being patched.
|
| + const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class());
|
| + const Function& replaced_func =
|
| + Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name));
|
| + ASSERT(!replaced_func.IsNull());
|
| + toplevel_cls.RemoveFunction(replaced_func);
|
| library_.ReplaceObject(func, func_name);
|
| }
|
| if (metadata_pos >= 0) {
|
| @@ -5654,6 +5667,7 @@ void Parser::ParseTopLevelFunction(TopLevel* top_level,
|
|
|
|
|
| void Parser::ParseTopLevelAccessor(TopLevel* top_level,
|
| + const Object& owner,
|
| intptr_t metadata_pos) {
|
| TRACE_PARSER("ParseTopLevelAccessor");
|
| const intptr_t decl_begin_pos = TokenPos();
|
| @@ -5784,7 +5798,7 @@ void Parser::ParseTopLevelAccessor(TopLevel* top_level,
|
| /* is_abstract = */ false,
|
| is_external,
|
| is_native,
|
| - current_class(),
|
| + owner,
|
| decl_begin_pos));
|
| func.set_result_type(result_type);
|
| func.set_end_token_pos(accessor_end_pos);
|
| @@ -5801,6 +5815,14 @@ void Parser::ParseTopLevelAccessor(TopLevel* top_level,
|
| if (!is_patch) {
|
| library_.AddObject(func, accessor_name);
|
| } else {
|
| + // Need to remove the previously added accessor that is being patched.
|
| + const Class& toplevel_cls = Class::Handle(Z,
|
| + owner.IsClass() ? Class::Cast(owner).raw()
|
| + : PatchClass::Cast(owner).patched_class());
|
| + const Function& replaced_func =
|
| + Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name));
|
| + ASSERT(!replaced_func.IsNull());
|
| + toplevel_cls.RemoveFunction(replaced_func);
|
| library_.ReplaceObject(func, accessor_name);
|
| }
|
| if (metadata_pos >= 0) {
|
| @@ -5880,7 +5902,8 @@ void Parser::ParseIdentList(GrowableObjectArray* names) {
|
| }
|
|
|
|
|
| -void Parser::ParseLibraryImportExport(intptr_t metadata_pos) {
|
| +void Parser::ParseLibraryImportExport(const Object& tl_owner,
|
| + intptr_t metadata_pos) {
|
| bool is_import = (CurrentToken() == Token::kIMPORT);
|
| bool is_export = (CurrentToken() == Token::kEXPORT);
|
| ASSERT(is_import || is_export);
|
| @@ -5965,7 +5988,7 @@ void Parser::ParseLibraryImportExport(intptr_t metadata_pos) {
|
| Namespace& ns = Namespace::Handle(Z,
|
| Namespace::New(library, show_names, hide_names));
|
| if (metadata_pos >= 0) {
|
| - ns.AddMetadata(metadata_pos, current_class());
|
| + ns.AddMetadata(tl_owner, metadata_pos);
|
| }
|
|
|
| // Ensure that private dart:_ libraries are only imported into dart:
|
| @@ -6028,7 +6051,7 @@ void Parser::ParseLibraryPart() {
|
| }
|
|
|
|
|
| -void Parser::ParseLibraryDefinition() {
|
| +void Parser::ParseLibraryDefinition(const Object& tl_owner) {
|
| TRACE_PARSER("ParseLibraryDefinition");
|
|
|
| // Handle the script tag.
|
| @@ -6051,14 +6074,14 @@ void Parser::ParseLibraryDefinition() {
|
| }
|
| ParseLibraryName();
|
| if (metadata_pos >= 0) {
|
| - library_.AddLibraryMetadata(current_class(), metadata_pos);
|
| + library_.AddLibraryMetadata(tl_owner, metadata_pos);
|
| }
|
| rewind_pos = TokenPos();
|
| metadata_pos = SkipMetadata();
|
| }
|
| while ((CurrentToken() == Token::kIMPORT) ||
|
| (CurrentToken() == Token::kEXPORT)) {
|
| - ParseLibraryImportExport(metadata_pos);
|
| + ParseLibraryImportExport(tl_owner, metadata_pos);
|
| rewind_pos = TokenPos();
|
| metadata_pos = SkipMetadata();
|
| }
|
| @@ -6110,13 +6133,21 @@ void Parser::ParseTopLevel() {
|
| SetPosition(0);
|
| is_top_level_ = true;
|
| TopLevel top_level(Z);
|
| - Class& toplevel_class = Class::Handle(Z,
|
| - Class::New(Symbols::TopLevel(), script_, TokenPos()));
|
| - toplevel_class.set_library(library_);
|
| +
|
| + Object& tl_owner = Object::Handle(Z);
|
| + Class& toplevel_class = Class::Handle(Z, library_.toplevel_class());
|
| + if (toplevel_class.IsNull()) {
|
| + toplevel_class = Class::New(Symbols::TopLevel(), script_, TokenPos());
|
| + toplevel_class.set_library(library_);
|
| + library_.set_toplevel_class(toplevel_class);
|
| + tl_owner = toplevel_class.raw();
|
| + } else {
|
| + tl_owner = PatchClass::New(toplevel_class, script_);
|
| + }
|
|
|
| if (is_library_source() || is_patch_source()) {
|
| set_current_class(toplevel_class);
|
| - ParseLibraryDefinition();
|
| + ParseLibraryDefinition(tl_owner);
|
| } else if (is_part_source()) {
|
| ParsePartHeader();
|
| }
|
| @@ -6126,27 +6157,27 @@ void Parser::ParseTopLevel() {
|
| set_current_class(cls); // No current class.
|
| intptr_t metadata_pos = SkipMetadata();
|
| if (CurrentToken() == Token::kCLASS) {
|
| - ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
|
| + ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
|
| } else if (CurrentToken() == Token::kENUM) {
|
| - ParseEnumDeclaration(pending_classes, toplevel_class, metadata_pos);
|
| + ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos);
|
| } else if ((CurrentToken() == Token::kTYPEDEF) &&
|
| (LookaheadToken(1) != Token::kLPAREN)) {
|
| set_current_class(toplevel_class);
|
| - ParseTypedef(pending_classes, toplevel_class, metadata_pos);
|
| + ParseTypedef(pending_classes, tl_owner, metadata_pos);
|
| } else if ((CurrentToken() == Token::kABSTRACT) &&
|
| (LookaheadToken(1) == Token::kCLASS)) {
|
| - ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
|
| + ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
|
| } else if (is_patch_source() && IsSymbol(Symbols::Patch()) &&
|
| (LookaheadToken(1) == Token::kCLASS)) {
|
| - ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos);
|
| + ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
|
| } else {
|
| set_current_class(toplevel_class);
|
| if (IsVariableDeclaration()) {
|
| - ParseTopLevelVariable(&top_level, metadata_pos);
|
| + ParseTopLevelVariable(&top_level, tl_owner, metadata_pos);
|
| } else if (IsFunctionDeclaration()) {
|
| - ParseTopLevelFunction(&top_level, metadata_pos);
|
| + ParseTopLevelFunction(&top_level, tl_owner, metadata_pos);
|
| } else if (IsTopLevelAccessor()) {
|
| - ParseTopLevelAccessor(&top_level, metadata_pos);
|
| + ParseTopLevelAccessor(&top_level, tl_owner, metadata_pos);
|
| } else if (CurrentToken() == Token::kEOS) {
|
| break;
|
| } else {
|
| @@ -6155,19 +6186,13 @@ void Parser::ParseTopLevel() {
|
| }
|
| }
|
|
|
| - if ((library_.num_anonymous_classes() == 0) ||
|
| - (top_level.fields().length() > 0) ||
|
| - (top_level.functions().length() > 0)) {
|
| + if (top_level.fields().length() > 0) {
|
| toplevel_class.AddFields(top_level.fields());
|
| - const intptr_t len = top_level.functions().length();
|
| - const Array& array = Array::Handle(Z, Array::New(len, Heap::kOld));
|
| - for (intptr_t i = 0; i < len; i++) {
|
| - array.SetAt(i, *top_level.functions()[i]);
|
| - }
|
| - toplevel_class.SetFunctions(array);
|
| - library_.AddAnonymousClass(toplevel_class);
|
| - pending_classes.Add(toplevel_class, Heap::kOld);
|
| }
|
| + for (intptr_t i = 0; i < top_level.functions().length(); i++) {
|
| + toplevel_class.AddFunction(*top_level.functions()[i]);
|
| + }
|
| + pending_classes.Add(toplevel_class, Heap::kOld);
|
| }
|
|
|
|
|
| @@ -6226,9 +6251,7 @@ void Parser::OpenFunctionBlock(const Function& func) {
|
|
|
| void Parser::OpenAsyncClosure() {
|
| TRACE_PARSER("OpenAsyncClosure");
|
| -
|
| async_temp_scope_ = current_block_->scope;
|
| -
|
| OpenAsyncTryBlock();
|
| }
|
|
|
| @@ -14407,7 +14430,7 @@ void Parser::ParseFunction(ParsedFunction* parsed_function) {
|
| }
|
|
|
|
|
| -RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) {
|
| +RawObject* Parser::ParseMetadata(const Field& meta_data) {
|
| UNREACHABLE();
|
| return Object::null();
|
| }
|
|
|