Index: pkg/compiler/lib/src/compiler.dart |
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart |
index fe27108d2f46add922ab5df6700d6a3f93e76400..25337d07fb506268750a983755daff04417b3f74 100644 |
--- a/pkg/compiler/lib/src/compiler.dart |
+++ b/pkg/compiler/lib/src/compiler.dart |
@@ -93,7 +93,7 @@ abstract class Compiler implements LibraryLoaderListener { |
Types types; |
_CompilerCoreTypes _coreTypes; |
CompilerDiagnosticReporter _reporter; |
- _CompilerResolution _resolution; |
+ CompilerResolution _resolution; |
ParsingContext _parsingContext; |
final CacheStrategy cacheStrategy; |
@@ -215,7 +215,7 @@ abstract class Compiler implements LibraryLoaderListener { |
} else { |
_reporter = new CompilerDiagnosticReporter(this, options); |
} |
- _resolution = new _CompilerResolution(this); |
+ _resolution = createResolution(); |
// TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and |
// make its field final. |
_coreTypes = new _CompilerCoreTypes(_resolution, reporter); |
@@ -233,13 +233,7 @@ abstract class Compiler implements LibraryLoaderListener { |
if (makeBackend != null) { |
backend = makeBackend(this); |
} else { |
- js_backend.JavaScriptBackend jsBackend = new js_backend.JavaScriptBackend( |
- this, |
- generateSourceMap: options.generateSourceMap, |
- useStartupEmitter: options.useStartupEmitter, |
- useNewSourceInfo: options.useNewSourceInfo, |
- useKernel: options.useKernel); |
- backend = jsBackend; |
+ backend = createBackend(); |
} |
enqueuer = backend.makeEnqueuer(); |
@@ -302,6 +296,17 @@ abstract class Compiler implements LibraryLoaderListener { |
return _world; |
} |
+ /// Creates the backend. |
+ /// |
+ /// Override this to mock the backend for testing. |
+ Backend createBackend() { |
+ return new js_backend.JavaScriptBackend(this, |
+ generateSourceMap: options.generateSourceMap, |
+ useStartupEmitter: options.useStartupEmitter, |
+ useNewSourceInfo: options.useNewSourceInfo, |
+ useKernel: options.useKernel); |
+ } |
+ |
/// Creates the scanner task. |
/// |
/// Override this to mock the scanner for testing. |
@@ -309,6 +314,11 @@ abstract class Compiler implements LibraryLoaderListener { |
new ScannerTask(dietParser, reporter, measurer, |
preserveComments: options.preserveComments, commentMap: commentMap); |
+ /// Creates the resolution object. |
+ /// |
+ /// Override this to mock resolution for testing. |
+ Resolution createResolution() => new CompilerResolution(this); |
+ |
/// Creates the resolver task. |
/// |
/// Override this to mock the resolver for testing. |
@@ -625,7 +635,7 @@ abstract class Compiler implements LibraryLoaderListener { |
.then((LibraryElement library) { |
if (library == null) return null; |
enqueuer.resolution.applyImpact(computeImpactForLibrary(library)); |
- emptyQueue(enqueuer.resolution); |
+ emptyQueue(enqueuer.resolution, onProgress: showResolutionProgress); |
enqueuer.resolution.logSummary(reporter.log); |
return library; |
}); |
@@ -686,7 +696,8 @@ abstract class Compiler implements LibraryLoaderListener { |
mainFunction.computeType(resolution); |
} |
- processQueue(enqueuer.resolution, mainFunction); |
+ processQueue(enqueuer.resolution, mainFunction, |
+ onProgress: showResolutionProgress); |
enqueuer.resolution.logSummary(reporter.log); |
_reporter.reportSuppressedMessagesSummary(); |
@@ -743,7 +754,8 @@ abstract class Compiler implements LibraryLoaderListener { |
enqueuer.codegen.applyImpact(computeImpactForLibrary(library)); |
}); |
} |
- processQueue(enqueuer.codegen, mainFunction); |
+ processQueue(enqueuer.codegen, mainFunction, |
+ onProgress: showCodegenProgress); |
enqueuer.codegen.logSummary(reporter.log); |
int programSize = backend.assembleProgram(); |
@@ -841,22 +853,25 @@ abstract class Compiler implements LibraryLoaderListener { |
/** |
* Empty the [enqueuer] queue. |
*/ |
- void emptyQueue(Enqueuer enqueuer) { |
+ void emptyQueue(Enqueuer enqueuer, {void onProgress()}) { |
selfTask.measureSubtask("Compiler.emptyQueue", () { |
enqueuer.forEach((WorkItem work) { |
+ if (onProgress != null) { |
+ onProgress(); |
+ } |
reporter.withCurrentElement( |
work.element, |
() => selfTask.measureSubtask("world.applyImpact", () { |
enqueuer.applyImpact( |
- selfTask.measureSubtask( |
- "work.run", () => work.run(this, enqueuer)), |
+ selfTask.measureSubtask("work.run", () => work.run()), |
impactSource: work.element); |
})); |
}); |
}); |
} |
- void processQueue(Enqueuer enqueuer, MethodElement mainMethod) { |
+ void processQueue(Enqueuer enqueuer, MethodElement mainMethod, |
+ {void onProgress()}) { |
selfTask.measureSubtask("Compiler.processQueue", () { |
enqueuer.open(impactStrategy); |
enqueuer.applyImpact(enqueuer.nativeEnqueuer |
@@ -868,7 +883,7 @@ abstract class Compiler implements LibraryLoaderListener { |
if (options.verbose) { |
progress.reset(); |
} |
- emptyQueue(enqueuer); |
+ emptyQueue(enqueuer, onProgress: onProgress); |
enqueuer.queueIsClosed = true; |
enqueuer.close(); |
// Notify the impact strategy impacts are no longer needed for this |
@@ -919,49 +934,27 @@ abstract class Compiler implements LibraryLoaderListener { |
} |
} |
- WorldImpact analyzeElement(Element element) => |
- selfTask.measureSubtask("Compiler.analyzeElement", () { |
- assert(invariant( |
- element, |
- element.impliesType || |
- element.isField || |
- element.isFunction || |
- element.isConstructor || |
- element.isGetter || |
- element.isSetter, |
- message: 'Unexpected element kind: ${element.kind}')); |
- assert(invariant(element, element is AnalyzableElement, |
- message: 'Element $element is not analyzable.')); |
- assert(invariant(element, element.isDeclaration)); |
- return resolution.computeWorldImpact(element); |
- }); |
- |
- WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) => |
+/* |
Harry Terkelsen
2016/11/28 19:24:29
delete commented code
Johnni Winther
2016/11/29 08:43:38
Done.
|
+ WorldImpact analyze(ResolutionWorkItem work) => |
selfTask.measureSubtask("Compiler.analyze", () { |
- assert(invariant(work.element, identical(world, enqueuer.resolution))); |
assert(invariant(work.element, !work.isAnalyzed, |
message: 'Element ${work.element} has already been analyzed')); |
- if (shouldPrintProgress) { |
- // TODO(ahe): Add structured diagnostics to the compiler API and |
- // use it to separate this from the --verbose option. |
- if (phase == PHASE_RESOLVING) { |
- reporter |
- .log('Resolved ${enqueuer.resolution.processedElements.length} ' |
- 'elements.'); |
- progress.reset(); |
- } |
- } |
AstElement element = work.element; |
- if (world.hasBeenProcessed(element)) { |
- return const WorldImpact(); |
- } |
- WorldImpact worldImpact = analyzeElement(element); |
- world.registerProcessedElement(element); |
- return worldImpact; |
+ return resolution.computeWorldImpact(element); |
}); |
+*/ |
+ void showResolutionProgress() { |
+ if (shouldPrintProgress) { |
+ // TODO(ahe): Add structured diagnostics to the compiler API and |
+ // use it to separate this from the --verbose option. |
+ assert(phase == PHASE_RESOLVING); |
+ reporter.log('Resolved ${enqueuer.resolution.processedElements.length} ' |
+ 'elements.'); |
+ progress.reset(); |
+ } |
+ } |
- WorldImpact codegen(CodegenWorkItem work, Enqueuer world) { |
- assert(invariant(work.element, identical(world, enqueuer.codegen))); |
+ void showCodegenProgress() { |
if (shouldPrintProgress) { |
// TODO(ahe): Add structured diagnostics to the compiler API and |
// use it to separate this from the --verbose option. |
@@ -969,7 +962,6 @@ abstract class Compiler implements LibraryLoaderListener { |
'Compiled ${enqueuer.codegen.processedEntities.length} methods.'); |
progress.reset(); |
} |
- return backend.codegen(work); |
} |
void reportDiagnostic(DiagnosticMessage message, |
@@ -1945,94 +1937,94 @@ class CompilerDiagnosticReporter extends DiagnosticReporter { |
} |
// TODO(johnniwinther): Move [ResolverTask] here. |
-class _CompilerResolution implements Resolution { |
- final Compiler compiler; |
+class CompilerResolution implements Resolution { |
+ final Compiler _compiler; |
final Map<Element, ResolutionImpact> _resolutionImpactCache = |
<Element, ResolutionImpact>{}; |
final Map<Element, WorldImpact> _worldImpactCache = <Element, WorldImpact>{}; |
bool retainCachesForTesting = false; |
- _CompilerResolution(this.compiler); |
+ CompilerResolution(this._compiler); |
@override |
- DiagnosticReporter get reporter => compiler.reporter; |
+ DiagnosticReporter get reporter => _compiler.reporter; |
@override |
- ParsingContext get parsingContext => compiler.parsingContext; |
+ ParsingContext get parsingContext => _compiler.parsingContext; |
@override |
- CoreClasses get coreClasses => compiler.coreClasses; |
+ CoreClasses get coreClasses => _compiler.coreClasses; |
@override |
- CoreTypes get coreTypes => compiler.coreTypes; |
+ CoreTypes get coreTypes => _compiler.coreTypes; |
@override |
- CommonElements get commonElements => compiler.commonElements; |
+ CommonElements get commonElements => _compiler.commonElements; |
@override |
- Types get types => compiler.types; |
+ Types get types => _compiler.types; |
@override |
- Target get target => compiler.backend; |
+ Target get target => _compiler.backend; |
@override |
- ResolverTask get resolver => compiler.resolver; |
+ ResolverTask get resolver => _compiler.resolver; |
@override |
- ResolutionEnqueuer get enqueuer => compiler.enqueuer.resolution; |
+ ResolutionEnqueuer get enqueuer => _compiler.enqueuer.resolution; |
@override |
- CompilerOptions get options => compiler.options; |
+ CompilerOptions get options => _compiler.options; |
@override |
- IdGenerator get idGenerator => compiler.idGenerator; |
+ IdGenerator get idGenerator => _compiler.idGenerator; |
@override |
- ConstantEnvironment get constants => compiler.constants; |
+ ConstantEnvironment get constants => _compiler.constants; |
@override |
MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask => |
- compiler.mirrorUsageAnalyzerTask; |
+ _compiler.mirrorUsageAnalyzerTask; |
@override |
- LibraryElement get coreLibrary => compiler._coreTypes.coreLibrary; |
+ LibraryElement get coreLibrary => _compiler._coreTypes.coreLibrary; |
@override |
bool get wasProxyConstantComputedTestingOnly => _proxyConstant != null; |
@override |
void registerClass(ClassElement cls) { |
- compiler.openWorld.registerClass(cls); |
+ _compiler.openWorld.registerClass(cls); |
} |
@override |
void resolveClass(ClassElement cls) { |
- compiler.resolver.resolveClass(cls); |
+ _compiler.resolver.resolveClass(cls); |
} |
@override |
void resolveTypedef(TypedefElement typdef) { |
- compiler.resolver.resolve(typdef); |
+ _compiler.resolver.resolve(typdef); |
} |
@override |
void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation) { |
- compiler.resolver.resolveMetadataAnnotation(metadataAnnotation); |
+ _compiler.resolver.resolveMetadataAnnotation(metadataAnnotation); |
} |
@override |
FunctionSignature resolveSignature(FunctionElement function) { |
- return compiler.resolver.resolveSignature(function); |
+ return _compiler.resolver.resolveSignature(function); |
} |
@override |
DartType resolveTypeAnnotation(Element element, TypeAnnotation node) { |
- return compiler.resolver.resolveTypeAnnotation(element, node); |
+ return _compiler.resolver.resolveTypeAnnotation(element, node); |
} |
@override |
void ensureResolved(Element element) { |
- if (compiler.serialization.isDeserialized(element)) { |
+ if (_compiler.serialization.isDeserialized(element)) { |
return; |
} |
computeWorldImpact(element); |
@@ -2040,21 +2032,21 @@ class _CompilerResolution implements Resolution { |
@override |
void ensureClassMembers(ClassElement element) { |
- if (!compiler.serialization.isDeserialized(element)) { |
- compiler.resolver.checkClass(element); |
+ if (!_compiler.serialization.isDeserialized(element)) { |
+ _compiler.resolver.checkClass(element); |
} |
} |
@override |
void registerCompileTimeError(Element element, DiagnosticMessage message) => |
- compiler.registerCompileTimeError(element, message); |
+ _compiler.registerCompileTimeError(element, message); |
@override |
bool hasResolvedAst(ExecutableElement element) { |
assert(invariant(element, element.isDeclaration, |
message: "Element $element must be the declaration.")); |
- if (compiler.serialization.isDeserialized(element)) { |
- return compiler.serialization.hasResolvedAst(element); |
+ if (_compiler.serialization.isDeserialized(element)) { |
+ return _compiler.serialization.hasResolvedAst(element); |
} |
return hasBeenResolved(element.memberContext.declaration) && |
element.hasResolvedAst; |
@@ -2066,8 +2058,8 @@ class _CompilerResolution implements Resolution { |
message: "Element $element must be the declaration.")); |
assert(invariant(element, hasResolvedAst(element), |
message: "ResolvedAst not available for $element.")); |
- if (compiler.serialization.isDeserialized(element)) { |
- return compiler.serialization.getResolvedAst(element); |
+ if (_compiler.serialization.isDeserialized(element)) { |
+ return _compiler.serialization.getResolvedAst(element); |
} |
return element.resolvedAst; |
} |
@@ -2082,8 +2074,8 @@ class _CompilerResolution implements Resolution { |
bool hasResolutionImpact(Element element) { |
assert(invariant(element, element.isDeclaration, |
message: "Element $element must be the declaration.")); |
- if (compiler.serialization.isDeserialized(element)) { |
- return compiler.serialization.hasResolutionImpact(element); |
+ if (_compiler.serialization.isDeserialized(element)) { |
+ return _compiler.serialization.hasResolutionImpact(element); |
} |
return _resolutionImpactCache.containsKey(element); |
} |
@@ -2093,8 +2085,8 @@ class _CompilerResolution implements Resolution { |
assert(invariant(element, element.isDeclaration, |
message: "Element $element must be the declaration.")); |
ResolutionImpact resolutionImpact; |
- if (compiler.serialization.isDeserialized(element)) { |
- resolutionImpact = compiler.serialization.getResolutionImpact(element); |
+ if (_compiler.serialization.isDeserialized(element)) { |
+ resolutionImpact = _compiler.serialization.getResolutionImpact(element); |
} else { |
resolutionImpact = _resolutionImpactCache[element]; |
} |
@@ -2115,39 +2107,54 @@ class _CompilerResolution implements Resolution { |
@override |
WorldImpact computeWorldImpact(Element element) { |
- assert(invariant(element, element.isDeclaration, |
- message: "Element $element must be the declaration.")); |
- return _worldImpactCache.putIfAbsent(element, () { |
- assert(compiler.parser != null); |
- Node tree = compiler.parser.parse(element); |
- assert(invariant(element, !element.isSynthesized || tree == null)); |
- ResolutionImpact resolutionImpact = compiler.resolver.resolve(element); |
- |
- if (compiler.serialization.supportSerialization || |
- retainCachesForTesting) { |
- // [ResolutionImpact] is currently only used by serialization. The |
- // enqueuer uses the [WorldImpact] which is always cached. |
- // TODO(johnniwinther): Align these use cases better; maybe only |
- // cache [ResolutionImpact] and let the enqueuer transform it into |
- // a [WorldImpact]. |
- _resolutionImpactCache[element] = resolutionImpact; |
- } |
- if (tree != null && !compiler.options.analyzeSignaturesOnly) { |
- // TODO(het): don't do this if suppressWarnings is on, currently we have |
- // to do it because the typechecker also sets types |
- // Only analyze nodes with a corresponding [TreeElements]. |
- compiler.checker.check(element); |
- } |
- return transformResolutionImpact(element, resolutionImpact); |
+ return _compiler.selfTask.measureSubtask("Resolution.computeWorldImpact", |
+ () { |
+ assert(invariant( |
+ element, |
+ element.impliesType || |
+ element.isField || |
+ element.isFunction || |
+ element.isConstructor || |
+ element.isGetter || |
+ element.isSetter, |
+ message: 'Unexpected element kind: ${element.kind}')); |
+ assert(invariant(element, element is AnalyzableElement, |
+ message: 'Element $element is not analyzable.')); |
+ assert(invariant(element, element.isDeclaration)); |
Harry Terkelsen
2016/11/28 19:24:29
you have the same invariant twice
Johnni Winther
2016/11/29 08:43:38
One removed!
|
+ assert(invariant(element, element.isDeclaration, |
+ message: "Element $element must be the declaration.")); |
+ return _worldImpactCache.putIfAbsent(element, () { |
+ assert(_compiler.parser != null); |
+ Node tree = _compiler.parser.parse(element); |
+ assert(invariant(element, !element.isSynthesized || tree == null)); |
+ ResolutionImpact resolutionImpact = _compiler.resolver.resolve(element); |
+ |
+ if (_compiler.serialization.supportSerialization || |
+ retainCachesForTesting) { |
+ // [ResolutionImpact] is currently only used by serialization. The |
+ // enqueuer uses the [WorldImpact] which is always cached. |
+ // TODO(johnniwinther): Align these use cases better; maybe only |
+ // cache [ResolutionImpact] and let the enqueuer transform it into |
+ // a [WorldImpact]. |
+ _resolutionImpactCache[element] = resolutionImpact; |
+ } |
+ if (tree != null && !_compiler.options.analyzeSignaturesOnly) { |
+ // TODO(het): don't do this if suppressWarnings is on, currently we |
+ // have to do it because the typechecker also sets types |
+ // Only analyze nodes with a corresponding [TreeElements]. |
+ _compiler.checker.check(element); |
+ } |
+ return transformResolutionImpact(element, resolutionImpact); |
+ }); |
}); |
} |
@override |
WorldImpact transformResolutionImpact( |
Element element, ResolutionImpact resolutionImpact) { |
- WorldImpact worldImpact = compiler.backend.impactTransformer |
+ WorldImpact worldImpact = _compiler.backend.impactTransformer |
.transformResolutionImpact( |
- compiler.enqueuer.resolution, resolutionImpact); |
+ _compiler.enqueuer.resolution, resolutionImpact); |
_worldImpactCache[element] = worldImpact; |
return worldImpact; |
} |
@@ -2157,7 +2164,7 @@ class _CompilerResolution implements Resolution { |
assert(invariant(element, element.isDeclaration, |
message: "Element $element must be the declaration.")); |
if (retainCachesForTesting) return; |
- if (compiler.serialization.isDeserialized(element)) return; |
+ if (_compiler.serialization.isDeserialized(element)) return; |
assert(invariant(element, _worldImpactCache[element] != null, |
message: "WorldImpact not computed for $element.")); |
_worldImpactCache[element] = const WorldImpact(); |
@@ -2180,10 +2187,10 @@ class _CompilerResolution implements Resolution { |
@override |
ResolutionWorkItem createWorkItem(Element element) { |
- if (compiler.serialization.isDeserialized(element)) { |
- return compiler.serialization.createResolutionWorkItem(element); |
+ if (_compiler.serialization.isDeserialized(element)) { |
+ return _compiler.serialization.createResolutionWorkItem(element); |
} else { |
- return new ResolutionWorkItem(element); |
+ return new ResolutionWorkItem(this, element); |
} |
} |