| 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]
|
|
|