| Index: pkg/compiler/lib/src/compiler.dart
|
| diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
|
| index 6ebb7a56ba782611176b0a4fd6e79451fc10195c..d2f3001e8569b243fd5e0fc872d88b8365fd63a3 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;
|
| @@ -913,7 +914,7 @@ abstract class Compiler extends DiagnosticListener {
|
| 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(
|
| @@ -1323,7 +1324,7 @@ abstract class Compiler extends DiagnosticListener {
|
| });
|
| }
|
| 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);
|
| }
|
| @@ -1350,7 +1351,7 @@ abstract class Compiler extends DiagnosticListener {
|
| }
|
| }
|
|
|
| - WorldImpact analyzeElement(Element element) {
|
| + ResolutionWorldImpact analyzeElement(Element element) {
|
| assert(invariant(element,
|
| element.impliesType ||
|
| element.isField ||
|
| @@ -1362,23 +1363,11 @@ abstract class Compiler extends DiagnosticListener {
|
| 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'));
|
| @@ -1386,17 +1375,18 @@ abstract class Compiler extends DiagnosticListener {
|
| // TODO(ahe): Add structured diagnostics to the compiler API and
|
| // use it to separate this from the --verbose option.
|
| if (phase == PHASE_RESOLVING) {
|
| - log('Resolved ${enqueuer.resolution.resolvedElements.length} '
|
| + 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;
|
| }
|
|
|
| @@ -1626,7 +1616,7 @@ abstract class Compiler extends DiagnosticListener {
|
| void checkLive(member) {
|
| if (member.isErroneous) return;
|
| if (member.isFunction) {
|
| - if (!enqueuer.resolution.hasBeenResolved(member)) {
|
| + if (!enqueuer.resolution.hasBeenProcessed(member)) {
|
| reportHintMessage(
|
| member, MessageKind.UNUSED_METHOD, {'name': member.name});
|
| }
|
| @@ -1786,28 +1776,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]);
|
| }
|
| @@ -1815,9 +1824,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) {
|
| @@ -1827,43 +1837,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]);
|
| }
|
| @@ -1872,6 +1900,8 @@ class _CompilerCoreTypes implements CoreTypes {
|
| // TODO(johnniwinther): Move [ResolverTask] here.
|
| class _CompilerResolution implements Resolution {
|
| final Compiler compiler;
|
| + final Map<Element, ResolutionWorldImpact> _worldImpactCache =
|
| + <Element, ResolutionWorldImpact>{};
|
|
|
| _CompilerResolution(this.compiler);
|
|
|
| @@ -1913,6 +1943,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]
|
|
|