Index: pkg/compiler/lib/src/compiler.dart |
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart |
index 5df0af3c5812b6ca112e299d66a14df9155beb58..4ca95334cf524309fb4dcef018713e72e7ec12c1 100644 |
--- a/pkg/compiler/lib/src/compiler.dart |
+++ b/pkg/compiler/lib/src/compiler.dart |
@@ -26,7 +26,8 @@ import 'common/registry.dart' show |
import 'common/resolution.dart' show |
Parsing, |
Resolution, |
- ResolutionWorkItem; |
+ ResolutionWorkItem, |
+ ResolutionWorldImpact; |
import 'common/tasks.dart' show |
CompilerTask, |
GenericTask; |
@@ -769,7 +770,7 @@ abstract class Compiler { |
bool isProxyConstant(ConstantValue value) { |
FieldElement field = coreLibrary.find('proxy'); |
if (field == null) return false; |
- if (!enqueuer.resolution.hasBeenResolved(field)) return false; |
+ if (!resolution.hasBeenResolved(field)) return false; |
if (proxyConstant == null) { |
proxyConstant = |
constants.getConstantValue( |
@@ -1160,7 +1161,7 @@ abstract class Compiler { |
}); |
} |
if (!REPORT_EXCESS_RESOLUTION) return; |
- var resolved = new Set.from(enqueuer.resolution.resolvedElements); |
+ var resolved = new Set.from(enqueuer.resolution.processedElements); |
for (Element e in enqueuer.codegen.generatedCode.keys) { |
resolved.remove(e); |
} |
@@ -1187,7 +1188,7 @@ abstract class Compiler { |
} |
} |
- WorldImpact analyzeElement(Element element) { |
+ ResolutionWorldImpact analyzeElement(Element element) { |
assert(invariant(element, |
element.impliesType || |
element.isField || |
@@ -1199,23 +1200,11 @@ abstract class Compiler { |
assert(invariant(element, element is AnalyzableElement, |
message: 'Element $element is not analyzable.')); |
assert(invariant(element, element.isDeclaration)); |
- ResolutionEnqueuer world = enqueuer.resolution; |
- if (world.hasBeenResolved(element)) { |
- return const WorldImpact(); |
- } |
- assert(parser != null); |
- Node tree = parser.parse(element); |
- assert(invariant(element, !element.isSynthesized || tree == null)); |
- WorldImpact worldImpact = resolver.resolve(element); |
- if (tree != null && !analyzeSignaturesOnly && !suppressWarnings) { |
- // Only analyze nodes with a corresponding [TreeElements]. |
- checker.check(element); |
- } |
- world.registerResolvedElement(element); |
- return worldImpact; |
+ return resolution.analyzeElement(element); |
} |
- WorldImpact analyze(ResolutionWorkItem work, ResolutionEnqueuer world) { |
+ ResolutionWorldImpact analyze(ResolutionWorkItem work, |
+ ResolutionEnqueuer world) { |
assert(invariant(work.element, identical(world, enqueuer.resolution))); |
assert(invariant(work.element, !work.isAnalyzed, |
message: 'Element ${work.element} has already been analyzed')); |
@@ -1223,18 +1212,19 @@ abstract class Compiler { |
// 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.resolvedElements.length} ' |
+ reporter.log( |
+ 'Resolved ${enqueuer.resolution.processedElements.length} ' |
'elements.'); |
progress.reset(); |
} |
} |
AstElement element = work.element; |
- if (world.hasBeenResolved(element)) { |
- return const WorldImpact(); |
+ if (world.hasBeenProcessed(element)) { |
+ return const ResolutionWorldImpact(); |
} |
- WorldImpact worldImpact = analyzeElement(element); |
+ ResolutionWorldImpact worldImpact = analyzeElement(element); |
backend.onElementResolved(element, element.resolvedAst.elements); |
+ world.registerProcessedElement(element); |
return worldImpact; |
} |
@@ -1330,7 +1320,7 @@ abstract class Compiler { |
void checkLive(member) { |
if (member.isErroneous) return; |
if (member.isFunction) { |
- if (!enqueuer.resolution.hasBeenResolved(member)) { |
+ if (!enqueuer.resolution.hasBeenProcessed(member)) { |
reporter.reportHintMessage( |
member, MessageKind.UNUSED_METHOD, {'name': member.name}); |
} |
@@ -1490,28 +1480,47 @@ class _CompilerCoreTypes implements CoreTypes { |
_CompilerCoreTypes(this.resolution); |
@override |
- InterfaceType get objectType => objectClass.computeType(resolution); |
+ InterfaceType get objectType { |
+ objectClass.ensureResolved(resolution); |
+ return objectClass.rawType; |
+ } |
@override |
- InterfaceType get boolType => boolClass.computeType(resolution); |
+ InterfaceType get boolType { |
+ boolClass.ensureResolved(resolution); |
+ return boolClass.rawType; |
+ } |
@override |
- InterfaceType get doubleType => doubleClass.computeType(resolution); |
+ InterfaceType get doubleType { |
+ doubleClass.ensureResolved(resolution); |
+ return doubleClass.rawType; |
+ } |
@override |
- InterfaceType get functionType => functionClass.computeType(resolution); |
+ InterfaceType get functionType { |
+ functionClass.ensureResolved(resolution); |
+ return functionClass.rawType; |
+ } |
@override |
- InterfaceType get intType => intClass.computeType(resolution); |
+ InterfaceType get intType { |
+ intClass.ensureResolved(resolution); |
+ return intClass.rawType; |
+ } |
@override |
- InterfaceType get resourceType => resourceClass.computeType(resolution); |
+ InterfaceType get resourceType { |
+ resourceClass.ensureResolved(resolution); |
+ return resourceClass.rawType; |
+ } |
@override |
InterfaceType listType([DartType elementType]) { |
- InterfaceType type = listClass.computeType(resolution); |
+ listClass.ensureResolved(resolution); |
+ InterfaceType type = listClass.rawType; |
if (elementType == null) { |
- return listClass.rawType; |
+ return type; |
} |
return type.createInstantiation([elementType]); |
} |
@@ -1519,9 +1528,10 @@ class _CompilerCoreTypes implements CoreTypes { |
@override |
InterfaceType mapType([DartType keyType, |
DartType valueType]) { |
- InterfaceType type = mapClass.computeType(resolution); |
+ mapClass.ensureResolved(resolution); |
+ InterfaceType type = mapClass.rawType; |
if (keyType == null && valueType == null) { |
- return mapClass.rawType; |
+ return type; |
} else if (keyType == null) { |
keyType = const DynamicType(); |
} else if (valueType == null) { |
@@ -1531,43 +1541,61 @@ class _CompilerCoreTypes implements CoreTypes { |
} |
@override |
- InterfaceType get nullType => nullClass.computeType(resolution); |
+ InterfaceType get nullType { |
+ nullClass.ensureResolved(resolution); |
+ return nullClass.rawType; |
+ } |
@override |
- InterfaceType get numType => numClass.computeType(resolution); |
+ InterfaceType get numType { |
+ numClass.ensureResolved(resolution); |
+ return numClass.rawType; |
+ } |
@override |
- InterfaceType get stringType => stringClass.computeType(resolution); |
+ InterfaceType get stringType { |
+ stringClass.ensureResolved(resolution); |
+ return stringClass.rawType; |
+ } |
@override |
- InterfaceType get symbolType => symbolClass.computeType(resolution); |
+ InterfaceType get symbolType { |
+ symbolClass.ensureResolved(resolution); |
+ return symbolClass.rawType; |
+ } |
@override |
- InterfaceType get typeType => typeClass.computeType(resolution); |
+ InterfaceType get typeType { |
+ typeClass.ensureResolved(resolution); |
+ return typeClass.rawType; |
+ } |
@override |
InterfaceType iterableType([DartType elementType]) { |
- InterfaceType type = iterableClass.computeType(resolution); |
+ iterableClass.ensureResolved(resolution); |
+ InterfaceType type = iterableClass.rawType; |
if (elementType == null) { |
- return iterableClass.rawType; |
+ return type; |
} |
return type.createInstantiation([elementType]); |
} |
@override |
InterfaceType futureType([DartType elementType]) { |
- InterfaceType type = futureClass.computeType(resolution); |
+ futureClass.ensureResolved(resolution); |
+ InterfaceType type = futureClass.rawType; |
if (elementType == null) { |
- return futureClass.rawType; |
+ return type; |
} |
return type.createInstantiation([elementType]); |
} |
@override |
InterfaceType streamType([DartType elementType]) { |
- InterfaceType type = streamClass.computeType(resolution); |
+ streamClass.ensureResolved(resolution); |
+ InterfaceType type = streamClass.rawType; |
if (elementType == null) { |
- return streamClass.rawType; |
+ return type; |
} |
return type.createInstantiation([elementType]); |
} |
@@ -1920,6 +1948,8 @@ class _CompilerDiagnosticReporter extends DiagnosticReporter { |
// TODO(johnniwinther): Move [ResolverTask] here. |
class _CompilerResolution implements Resolution { |
final Compiler compiler; |
+ final Map<Element, ResolutionWorldImpact> _worldImpactCache = |
+ <Element, ResolutionWorldImpact>{}; |
_CompilerResolution(this.compiler); |
@@ -1961,6 +1991,27 @@ class _CompilerResolution implements Resolution { |
DartType resolveTypeAnnotation(Element element, TypeAnnotation node) { |
return compiler.resolver.resolveTypeAnnotation(element, node); |
} |
+ |
+ ResolutionWorldImpact analyzeElement(Element element) { |
+ return _worldImpactCache.putIfAbsent(element, () { |
+ assert(compiler.parser != null); |
+ Node tree = compiler.parser.parse(element); |
+ assert(invariant(element, !element.isSynthesized || tree == null)); |
+ ResolutionWorldImpact worldImpact = compiler.resolver.resolve(element); |
+ if (tree != null && |
+ !compiler.analyzeSignaturesOnly && |
+ !compiler.suppressWarnings) { |
+ // Only analyze nodes with a corresponding [TreeElements]. |
+ compiler.checker.check(element); |
+ } |
+ return worldImpact; |
+ }); |
+ } |
+ |
+ @override |
+ bool hasBeenResolved(Element element) { |
+ return _worldImpactCache.containsKey(element); |
+ } |
} |
// TODO(johnniwinther): Move [ParserTask], [PatchParserTask], [DietParserTask] |