| Index: pkg/compiler/lib/src/common/resolution.dart
|
| diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
|
| index 38b8d5c295be363c1bd1ae3757f297f922b4f6f5..474b10e743803d7a257c514d8f6a8e50eb0249f3 100644
|
| --- a/pkg/compiler/lib/src/common/resolution.dart
|
| +++ b/pkg/compiler/lib/src/common/resolution.dart
|
| @@ -10,7 +10,8 @@ import '../compiler.dart' show
|
| import '../core_types.dart' show
|
| CoreTypes;
|
| import '../dart_types.dart' show
|
| - DartType;
|
| + DartType,
|
| + InterfaceType;
|
| import '../diagnostics/diagnostic_listener.dart' show
|
| DiagnosticReporter;
|
| import '../elements/elements.dart' show
|
| @@ -20,7 +21,9 @@ import '../elements/elements.dart' show
|
| ErroneousElement,
|
| FunctionElement,
|
| FunctionSignature,
|
| + LocalFunctionElement,
|
| MetadataAnnotation,
|
| + MethodElement,
|
| TypedefElement,
|
| TypeVariableElement;
|
| import '../enqueue.dart' show
|
| @@ -30,6 +33,10 @@ import '../tree/tree.dart' show
|
| AsyncForIn,
|
| Send,
|
| TypeAnnotation;
|
| +import '../universe/universe.dart' show
|
| + UniverseSelector;
|
| +import '../util/util.dart' show
|
| + Setlet;
|
| import 'registry.dart' show
|
| Registry;
|
| import 'work.dart' show
|
| @@ -46,6 +53,7 @@ class ResolutionWorkItem extends WorkItem {
|
|
|
| WorldImpact run(Compiler compiler, ResolutionEnqueuer world) {
|
| WorldImpact impact = compiler.analyze(this, world);
|
| + impact = compiler.backend.resolutionCallbacks.transformImpact(impact);
|
| _isAnalyzed = true;
|
| return impact;
|
| }
|
| @@ -53,8 +61,13 @@ class ResolutionWorkItem extends WorkItem {
|
| bool get isAnalyzed => _isAnalyzed;
|
| }
|
|
|
| +// TODO(johnniwinther): Rename this to something like `BackendResolutionApi`
|
| +// and clean up the interface.
|
| /// Backend callbacks function specific to the resolution phase.
|
| class ResolutionCallbacks {
|
| + ///
|
| + WorldImpact transformImpact(ResolutionWorldImpact worldImpact) => worldImpact;
|
| +
|
| /// Register that an assert has been seen.
|
| void onAssert(bool hasMessage, Registry registry) {}
|
|
|
| @@ -133,6 +146,258 @@ class ResolutionCallbacks {
|
| void onIncDecOperation(Registry registry) {}
|
| }
|
|
|
| +class ResolutionWorldImpact extends WorldImpact {
|
| + const ResolutionWorldImpact();
|
| +
|
| + // TODO(johnniwinther): Remove this.
|
| + void registerDependency(Element element) {}
|
| +
|
| + Iterable<Feature> get features => const <Feature>[];
|
| + Iterable<DartType> get requiredTypes => const <DartType>[];
|
| + Iterable<MapLiteralUse> get mapLiterals => const <MapLiteralUse>[];
|
| + Iterable<ListLiteralUse> get listLiterals => const <ListLiteralUse>[];
|
| + Iterable<DartType> get typeLiterals => const <DartType>[];
|
| + Iterable<String> get constSymbolNames => const <String>[];
|
| +}
|
| +
|
| +/// A language feature seen during resolution.
|
| +// TODO(johnniwinther): Should mirror usage be part of this?
|
| +enum Feature {
|
| + /// Invocation of a generative construction on an abstract class.
|
| + ABSTRACT_CLASS_INSTANTIATION,
|
| + /// An assert statement with no message.
|
| + ASSERT,
|
| + /// An assert statement with a message.
|
| + ASSERT_WITH_MESSAGE,
|
| + /// A method with an `async` body modifier.
|
| + ASYNC,
|
| + /// An asynchronous for in statement like `await for (var e in i) {}`.
|
| + ASYNC_FOR_IN,
|
| + /// A method with an `async*` body modifier.
|
| + ASYNC_STAR,
|
| + /// A catch statement.
|
| + CATCH_STATEMENT,
|
| + /// A compile time error.
|
| + COMPILE_TIME_ERROR,
|
| + /// A fall through in a switch case.
|
| + FALL_THROUGH_ERROR,
|
| + /// A ++/-- operation.
|
| + INC_DEC_OPERATION,
|
| + /// A field whose initialization is not a constant.
|
| + LAZY_FIELD,
|
| + /// A call to `new Symbol`.
|
| + NEW_SYMBOL,
|
| + /// A catch clause with a variable for the stack trace.
|
| + STACK_TRACE_IN_CATCH,
|
| + /// String interpolation.
|
| + STRING_INTERPOLATION,
|
| + /// An implicit call to `super.noSuchMethod`, like calling an unresolved
|
| + /// super method.
|
| + SUPER_NO_SUCH_METHOD,
|
| + /// A redirection to the `Symbol` constructor.
|
| + SYMBOL_CONSTRUCTOR,
|
| + /// An synchronous for in statement, like `for (var e in i) {}`.
|
| + SYNC_FOR_IN,
|
| + /// A method with a `sync*` body modifier.
|
| + SYNC_STAR,
|
| + /// A throw expression.
|
| + THROW_EXPRESSION,
|
| + /// An implicit throw of a `NoSuchMethodError`, like calling an unresolved
|
| + /// static method.
|
| + THROW_NO_SUCH_METHOD,
|
| + /// An implicit throw of a runtime error, like
|
| + THROW_RUNTIME_ERROR,
|
| + /// The need for a type variable bound check, like instantiation of a generic
|
| + /// type whose type variable have non-trivial bounds.
|
| + TYPE_VARIABLE_BOUNDS_CHECK,
|
| +}
|
| +
|
| +/// A use of a map literal seen during resolution.
|
| +class MapLiteralUse {
|
| + final InterfaceType type;
|
| + final bool isConstant;
|
| + final bool isEmpty;
|
| +
|
| + MapLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
|
| +
|
| + int get hashCode {
|
| + return
|
| + type.hashCode * 13 +
|
| + isConstant.hashCode * 17 +
|
| + isEmpty.hashCode * 19;
|
| + }
|
| +
|
| + bool operator ==(other) {
|
| + if (identical(this, other)) return true;
|
| + if (other is! MapLiteralUse) return false;
|
| + return
|
| + type == other.type &&
|
| + isConstant == other.isConstant &&
|
| + isEmpty == other.isEmpty;
|
| + }
|
| +}
|
| +
|
| +/// A use of a list literal seen during resolution.
|
| +class ListLiteralUse {
|
| + final InterfaceType type;
|
| + final bool isConstant;
|
| + final bool isEmpty;
|
| +
|
| + ListLiteralUse(this.type, {this.isConstant: false, this.isEmpty: false});
|
| +
|
| + int get hashCode {
|
| + return
|
| + type.hashCode * 13 +
|
| + isConstant.hashCode * 17 +
|
| + isEmpty.hashCode * 19;
|
| + }
|
| +
|
| + bool operator ==(other) {
|
| + if (identical(this, other)) return true;
|
| + if (other is! ListLiteralUse) return false;
|
| + return
|
| + type == other.type &&
|
| + isConstant == other.isConstant &&
|
| + isEmpty == other.isEmpty;
|
| + }
|
| +}
|
| +
|
| +/// Mutable implementation of [WorldImpact] used to transform
|
| +/// [ResolutionWorldImpact] to [WorldImpact].
|
| +// TODO(johnniwinther): Remove [Registry] when dependency is tracked directly
|
| +// on [WorldImpact].
|
| +class TransformedWorldImpact implements WorldImpact, Registry {
|
| + final ResolutionWorldImpact worldImpact;
|
| +
|
| + Setlet<Element> _staticUses;
|
| + Setlet<InterfaceType> _instantiatedTypes;
|
| + Setlet<UniverseSelector> _dynamicGetters;
|
| + Setlet<UniverseSelector> _dynamicInvocations;
|
| + Setlet<UniverseSelector> _dynamicSetters;
|
| +
|
| + TransformedWorldImpact(this.worldImpact);
|
| +
|
| + @override
|
| + Iterable<DartType> get asCasts => worldImpact.asCasts;
|
| +
|
| + @override
|
| + Iterable<DartType> get checkedModeChecks => worldImpact.checkedModeChecks;
|
| +
|
| + @override
|
| + Iterable<MethodElement> get closurizedFunctions {
|
| + return worldImpact.closurizedFunctions;
|
| + }
|
| +
|
| + @override
|
| + Iterable<UniverseSelector> get dynamicGetters {
|
| + return _dynamicGetters != null
|
| + ? _dynamicGetters : worldImpact.dynamicGetters;
|
| + }
|
| +
|
| + @override
|
| + Iterable<UniverseSelector> get dynamicInvocations {
|
| + return _dynamicInvocations != null
|
| + ? _dynamicInvocations : worldImpact.dynamicInvocations;
|
| + }
|
| +
|
| + @override
|
| + Iterable<UniverseSelector> get dynamicSetters {
|
| + return _dynamicSetters != null
|
| + ? _dynamicSetters : worldImpact.dynamicSetters;
|
| + }
|
| +
|
| + @override
|
| + Iterable<DartType> get isChecks => worldImpact.isChecks;
|
| +
|
| + @override
|
| + Iterable<Element> get staticUses {
|
| + if (_staticUses == null) {
|
| + return worldImpact.staticUses;
|
| + }
|
| + return _staticUses;
|
| + }
|
| +
|
| + @override
|
| + bool get isForResolution => true;
|
| +
|
| + _unsupported(String message) => throw new UnsupportedError(message);
|
| +
|
| + @override
|
| + Iterable<Element> get otherDependencies => _unsupported('otherDependencies');
|
| +
|
| + // TODO(johnniwinther): Remove this.
|
| + @override
|
| + void registerAssert(bool hasMessage) => _unsupported('registerAssert');
|
| +
|
| + @override
|
| + void registerDependency(Element element) {
|
| + worldImpact.registerDependency(element);
|
| + }
|
| +
|
| + @override
|
| + void registerDynamicGetter(UniverseSelector selector) {
|
| + if (_dynamicGetters == null) {
|
| + _dynamicGetters = new Setlet<UniverseSelector>();
|
| + _dynamicGetters.addAll(worldImpact.dynamicGetters);
|
| + }
|
| + _dynamicGetters.add(selector);
|
| + }
|
| +
|
| + @override
|
| + void registerDynamicInvocation(UniverseSelector selector) {
|
| + if (_dynamicInvocations == null) {
|
| + _dynamicInvocations = new Setlet<UniverseSelector>();
|
| + _dynamicInvocations.addAll(worldImpact.dynamicInvocations);
|
| + }
|
| + _dynamicInvocations.add(selector);
|
| + }
|
| +
|
| + @override
|
| + void registerDynamicSetter(UniverseSelector selector) {
|
| + if (_dynamicSetters == null) {
|
| + _dynamicSetters = new Setlet<UniverseSelector>();
|
| + _dynamicSetters.addAll(worldImpact.dynamicSetters);
|
| + }
|
| + _dynamicSetters.add(selector);
|
| + }
|
| +
|
| + @override
|
| + void registerGetOfStaticFunction(FunctionElement element) {
|
| + _unsupported('registerGetOfStaticFunction($element)');
|
| + }
|
| +
|
| + @override
|
| + void registerInstantiation(InterfaceType type) {
|
| + // TODO(johnniwinther): Remove this when dependency tracking is done on
|
| + // the world impact itself.
|
| + registerDependency(type.element);
|
| + if (_instantiatedTypes == null) {
|
| + _instantiatedTypes = new Setlet<InterfaceType>();
|
| + }
|
| + _instantiatedTypes.add(type);
|
| + }
|
| +
|
| + @override
|
| + Iterable<InterfaceType> get instantiatedTypes {
|
| + return _instantiatedTypes != null
|
| + ? _instantiatedTypes : const <InterfaceType>[];
|
| + }
|
| +
|
| + @override
|
| + void registerStaticInvocation(Element element) {
|
| + // TODO(johnniwinther): Remove this when dependency tracking is done on
|
| + // the world impact itself.
|
| + registerDependency(element);
|
| + if (_staticUses == null) {
|
| + _staticUses = new Setlet<Element>();
|
| + }
|
| + _staticUses.add(element);
|
| + }
|
| +
|
| + @override
|
| + Iterable<LocalFunctionElement> get closures => worldImpact.closures;
|
| +}
|
| +
|
| // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
|
| abstract class Resolution {
|
| Parsing get parsing;
|
| @@ -145,6 +410,9 @@ abstract class Resolution {
|
| void resolveMetadataAnnotation(MetadataAnnotation metadataAnnotation);
|
| FunctionSignature resolveSignature(FunctionElement function);
|
| DartType resolveTypeAnnotation(Element element, TypeAnnotation node);
|
| +
|
| + bool hasBeenResolved(Element element);
|
| + ResolutionWorldImpact analyzeElement(Element element);
|
| }
|
|
|
| // TODO(johnniwinther): Rename to `Parser` or `ParsingContext`.
|
|
|