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

Unified Diff: pkg/kernel/lib/analyzer/loader.dart

Issue 2669303002: Support for modular mixin resolution. (Closed)
Patch Set: Update binary format Created 3 years, 10 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: pkg/kernel/lib/analyzer/loader.dart
diff --git a/pkg/kernel/lib/analyzer/loader.dart b/pkg/kernel/lib/analyzer/loader.dart
index 664bf791f3be0c68178579c08d78c677364e2d6d..a54837870f0745f71bedd96af3e0b71f6efa96c2 100644
--- a/pkg/kernel/lib/analyzer/loader.dart
+++ b/pkg/kernel/lib/analyzer/loader.dart
@@ -106,6 +106,8 @@ class DartLoader implements ReferenceLevelLoader {
/// so as not to expose partially initialized classes.
final List<ast.Class> temporaryClassWorklist = [];
+ final Map<LibraryElement, List<ClassElement>> mixinLibraryWorklist = {};
+
final bool ignoreRedirectingFactories;
LibraryElement _libraryBeingLoaded = null;
@@ -113,8 +115,9 @@ class DartLoader implements ReferenceLevelLoader {
bool get strongMode => context.analysisOptions.strongMode;
DartLoader(this.repository, DartOptions options, Packages packages,
- {DartSdk dartSdk, AnalysisContext context,
- this.ignoreRedirectingFactories: true})
+ {DartSdk dartSdk,
+ AnalysisContext context,
+ this.ignoreRedirectingFactories: true})
: this.context =
context ?? createContext(options, packages, dartSdk: dartSdk),
this.applicationRoot = options.applicationRoot;
@@ -199,7 +202,7 @@ class DartLoader implements ReferenceLevelLoader {
}
}
libraryElements.add(element);
- _iterateWorklist();
+ _iterateTemporaryClassWorklist();
// Ensure everything is stored in the original declaration order.
library.classes
..clear()
@@ -388,15 +391,43 @@ class DartLoader implements ReferenceLevelLoader {
}
}
- void promoteToBodyLevel(ast.Class classNode, ClassElement element,
+ void promoteToMixinLevel(ast.Class classNode, ClassElement element,
NamedCompilationUnitMember astNode) {
- if (classNode.level == ast.ClassLevel.Body) return;
+ if (classNode.level.index >= ast.ClassLevel.Mixin.index) return;
promoteToHierarchyLevel(classNode);
- classNode.level = ast.ClassLevel.Body;
+ classNode.level = ast.ClassLevel.Mixin;
// Clear out the member references that were put in the class.
// The AST builder will load them all put back in the right order.
classNode..fields.clear()..procedures.clear()..constructors.clear();
new ClassBodyBuilder(this, classNode, element).build(astNode);
+
+ // Ensure mixed-in classes are available.
+ for (var mixin in element.mixins) {
+ _ensureMixinBecomesLoaded(mixin.element);
+ }
+ }
+
+ /// Ensures that [element] eventually becomes loaded at least at mixin level.
+ void _ensureMixinBecomesLoaded(ClassElement element) {
+ if (isLibraryBeingLoaded(element.library)) {
+ return;
+ }
+ var class_ = getClassReference(element);
+ if (class_.level.index >= ast.ClassLevel.Mixin.index) {
+ return;
+ }
+ var list = mixinLibraryWorklist[element.library] ??= <ClassElement>[];
+ list.add(element);
+ }
+
+ void promoteToBodyLevel(ast.Class classNode, ClassElement element,
+ NamedCompilationUnitMember astNode) {
+ if (classNode.level == ast.ClassLevel.Body) return;
+ promoteToMixinLevel(classNode, element, astNode);
+ classNode.level = ast.ClassLevel.Body;
+ // This frontend delivers the same contents for classes at body and mixin
+ // levels, even though as specified, the mixin level does not require all
+ // the static members to be present. So no additional work is needed.
}
ast.TypeParameter tryGetClassTypeParameter(TypeParameterElement element) {
@@ -617,6 +648,11 @@ class DartLoader implements ReferenceLevelLoader {
}
void ensureLibraryIsLoaded(ast.Library node) {
+ _ensureLibraryIsLoaded(node);
+ _iterateMixinLibraryWorklist();
+ }
+
+ void _ensureLibraryIsLoaded(ast.Library node) {
if (!node.isExternal) return;
node.isExternal = false;
var source = context.sourceFactory
@@ -649,6 +685,23 @@ class DartLoader implements ReferenceLevelLoader {
}
}
+ void loadSdkInterface(ast.Program program, Target target) {
+ var requiredSdkMembers = target.requiredSdkClasses;
+ for (var libraryUri in requiredSdkMembers.keys) {
+ var source = context.sourceFactory.forUri2(Uri.parse(libraryUri));
+ var libraryElement = context.computeLibraryElement(source);
+ for (var member in requiredSdkMembers[libraryUri]) {
+ var type = libraryElement.getType(member);
+ if (type == null) {
+ throw 'Could not find $member in $libraryUri';
+ }
+ promoteToTypeLevel(getClassReference(type));
+ }
+ }
+ _iterateTemporaryClassWorklist();
+ _iterateMixinLibraryWorklist();
+ }
+
void loadEverything({Target target, bool compileSdk}) {
compileSdk ??= true;
if (compileSdk) {
@@ -688,13 +741,28 @@ class DartLoader implements ReferenceLevelLoader {
return list;
}
- void _iterateWorklist() {
+ void _iterateTemporaryClassWorklist() {
while (temporaryClassWorklist.isNotEmpty) {
var element = temporaryClassWorklist.removeLast();
promoteToTypeLevel(element);
}
}
+ void _iterateMixinLibraryWorklist() {
+ // The worklist groups classes in the same library together so that we
+ // request resolved ASTs for each library only once.
+ while (mixinLibraryWorklist.isNotEmpty) {
+ LibraryElement library = mixinLibraryWorklist.keys.first;
+ _libraryBeingLoaded = library;
+ List<ClassElement> classes = mixinLibraryWorklist.remove(library);
+ for (var class_ in classes) {
+ var classNode = getClassReference(class_);
+ promoteToMixinLevel(classNode, class_, class_.computeNode());
+ }
+ }
+ _iterateTemporaryClassWorklist();
+ }
+
ast.Procedure _getMainMethod(Uri uri) {
Source source = context.sourceFactory.forUri2(uri);
LibraryElement library = context.computeLibraryElement(source);
@@ -714,8 +782,7 @@ class DartLoader implements ReferenceLevelLoader {
ast.ProcedureKind.Method,
new ast.FunctionNode(new ast.ExpressionStatement(new ast.Throw(
new ast.StringLiteral('Program has no main method')))),
- isStatic: true)
- ..fileUri = library.fileUri;
+ isStatic: true)..fileUri = library.fileUri;
library.addMember(main);
return main;
}

Powered by Google App Engine
This is Rietveld 408576698