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

Unified Diff: runtime/vm/parser.cc

Issue 1410383020: Eliminate all but one top-level class per library. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address Review Comments Created 5 years, 1 month 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
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
}
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698