Index: pkg/compiler/lib/src/resolution/registry.dart |
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart |
index 592ad34752185c443f2b47bd25225bead02d8b19..51aa37c4250bc8f48dd5b956d449e5505b10d7b0 100644 |
--- a/pkg/compiler/lib/src/resolution/registry.dart |
+++ b/pkg/compiler/lib/src/resolution/registry.dart |
@@ -7,6 +7,11 @@ library dart2js.resolution.registry; |
import '../common/backend_api.dart' show |
Backend, |
ForeignResolver; |
+import '../common/resolution.dart' show |
+ Feature, |
+ ListLiteralUse, |
+ MapLiteralUse, |
+ ResolutionWorldImpact; |
import '../common/registry.dart' show |
Registry; |
import '../compiler.dart' show |
@@ -16,9 +21,9 @@ import '../dart_types.dart'; |
import '../diagnostics/invariant.dart' show |
invariant; |
import '../enqueue.dart' show |
- ResolutionEnqueuer, |
- WorldImpact; |
+ ResolutionEnqueuer; |
import '../elements/elements.dart'; |
+import '../helpers/helpers.dart'; |
import '../tree/tree.dart'; |
import '../util/util.dart' show |
Setlet; |
@@ -37,11 +42,7 @@ import 'members.dart' show |
import 'tree_elements.dart' show |
TreeElementMapping; |
-/// [ResolutionRegistry] collects all resolution information. It stores node |
-/// related information in a [TreeElements] mapping and registers calls with |
-/// [Backend], [World] and [Enqueuer]. |
-// TODO(johnniwinther): Split this into an interface and implementation class. |
- |
+// TODO(johnniwinther): Remove this. |
class EagerRegistry implements Registry { |
final Compiler compiler; |
final TreeElementMapping mapping; |
@@ -100,19 +101,35 @@ class EagerRegistry implements Registry { |
String toString() => 'EagerRegistry for ${mapping.analyzedElement}'; |
} |
-class ResolutionWorldImpact implements WorldImpact { |
+class _ResolutionWorldImpact implements ResolutionWorldImpact { |
final Registry registry; |
+ // TODO(johnniwinther): Do we benefit from lazy initialization of the |
+ // [Setlet]s? |
Setlet<UniverseSelector> _dynamicInvocations; |
Setlet<UniverseSelector> _dynamicGetters; |
Setlet<UniverseSelector> _dynamicSetters; |
Setlet<InterfaceType> _instantiatedTypes; |
Setlet<Element> _staticUses; |
- Setlet<DartType> _checkedTypes; |
+ Setlet<DartType> _isChecks; |
+ Setlet<DartType> _asCasts; |
+ Setlet<DartType> _checkedModeChecks; |
Setlet<MethodElement> _closurizedFunctions; |
- |
- ResolutionWorldImpact(Compiler compiler, TreeElementMapping mapping) |
+ Setlet<LocalFunctionElement> _closures; |
+ Setlet<Feature> _features; |
+ // TODO(johnniwinther): This seems to be a union of other sets. |
+ Setlet<DartType> _requiredTypes; |
+ Setlet<MapLiteralUse> _mapLiterals; |
+ Setlet<ListLiteralUse> _listLiterals; |
+ Setlet<DartType> _typeLiterals; |
+ Setlet<String> _constSymbolNames; |
+ |
+ _ResolutionWorldImpact(Compiler compiler, TreeElementMapping mapping) |
: this.registry = new EagerRegistry(compiler, mapping); |
+ void registerDependency(Element element) { |
+ registry.registerDependency(element); |
+ } |
+ |
void registerDynamicGetter(UniverseSelector selector) { |
if (_dynamicGetters == null) { |
_dynamicGetters = new Setlet<UniverseSelector>(); |
@@ -153,10 +170,6 @@ class ResolutionWorldImpact implements WorldImpact { |
} |
void registerInstantiatedType(InterfaceType type) { |
- // TODO(johnniwinther): Enable this when registration doesn't require a |
- // [Registry]. |
- throw new UnsupportedError( |
- 'Lazy registration of instantiated not supported.'); |
if (_instantiatedTypes == null) { |
_instantiatedTypes = new Setlet<InterfaceType>(); |
} |
@@ -169,6 +182,58 @@ class ResolutionWorldImpact implements WorldImpact { |
? _instantiatedTypes : const <InterfaceType>[]; |
} |
+ void registerTypeLiteral(DartType type) { |
+ if (_typeLiterals == null) { |
+ _typeLiterals = new Setlet<DartType>(); |
+ } |
+ _typeLiterals.add(type); |
+ } |
+ |
+ @override |
+ Iterable<DartType> get typeLiterals { |
+ return _typeLiterals != null |
+ ? _typeLiterals : const <DartType>[]; |
+ } |
+ |
+ void registerRequiredType(DartType type) { |
+ if (_requiredTypes == null) { |
+ _requiredTypes = new Setlet<DartType>(); |
+ } |
+ _requiredTypes.add(type); |
+ } |
+ |
+ @override |
+ Iterable<DartType> get requiredTypes { |
+ return _requiredTypes != null |
+ ? _requiredTypes : const <DartType>[]; |
+ } |
+ |
+ void registerMapLiteral(MapLiteralUse mapLiteralUse) { |
+ if (_mapLiterals == null) { |
+ _mapLiterals = new Setlet<MapLiteralUse>(); |
+ } |
+ _mapLiterals.add(mapLiteralUse); |
+ } |
+ |
+ @override |
+ Iterable<MapLiteralUse> get mapLiterals { |
+ return _mapLiterals != null |
+ ? _mapLiterals : const <MapLiteralUse>[]; |
+ } |
+ |
+ void registerListLiteral(ListLiteralUse listLiteralUse) { |
+ if (_listLiterals == null) { |
+ _listLiterals = new Setlet<ListLiteralUse>(); |
+ } |
+ _listLiterals.add(listLiteralUse); |
+ } |
+ |
+ @override |
+ Iterable<ListLiteralUse> get listLiterals { |
+ return _listLiterals != null |
+ ? _listLiterals : const <ListLiteralUse>[]; |
+ } |
+ |
void registerStaticUse(Element element) { |
if (_staticUses == null) { |
_staticUses = new Setlet<Element>(); |
@@ -181,17 +246,43 @@ class ResolutionWorldImpact implements WorldImpact { |
return _staticUses != null ? _staticUses : const <Element>[]; |
} |
- void registerCheckedType(DartType type) { |
- if (_checkedTypes == null) { |
- _checkedTypes = new Setlet<DartType>(); |
+ void registerIsCheck(DartType type) { |
+ if (_isChecks == null) { |
+ _isChecks = new Setlet<DartType>(); |
+ } |
+ _isChecks.add(type); |
+ } |
+ |
+ @override |
+ Iterable<DartType> get isChecks { |
+ return _isChecks != null |
+ ? _isChecks : const <DartType>[]; |
+ } |
+ |
+ void registerAsCast(DartType type) { |
+ if (_asCasts == null) { |
+ _asCasts = new Setlet<DartType>(); |
} |
- _checkedTypes.add(type); |
+ _asCasts.add(type); |
} |
@override |
- Iterable<DartType> get checkedTypes { |
- return _checkedTypes != null |
- ? _checkedTypes : const <DartType>[]; |
+ Iterable<DartType> get asCasts { |
+ return _asCasts != null |
+ ? _asCasts : const <DartType>[]; |
+ } |
+ |
+ void registerCheckedModeCheckedType(DartType type) { |
+ if (_checkedModeChecks == null) { |
+ _checkedModeChecks = new Setlet<DartType>(); |
+ } |
+ _checkedModeChecks.add(type); |
+ } |
+ |
+ @override |
+ Iterable<DartType> get checkedModeChecks { |
+ return _checkedModeChecks != null |
+ ? _checkedModeChecks : const <DartType>[]; |
} |
void registerClosurizedFunction(MethodElement element) { |
@@ -206,17 +297,61 @@ class ResolutionWorldImpact implements WorldImpact { |
return _closurizedFunctions != null |
? _closurizedFunctions : const <MethodElement>[]; |
} |
+ |
+ void registerClosure(LocalFunctionElement element) { |
+ if (_closures == null) { |
+ _closures = new Setlet<LocalFunctionElement>(); |
+ } |
+ _closures.add(element); |
+ } |
+ |
+ @override |
+ Iterable<LocalFunctionElement> get closures { |
+ return _closures != null |
+ ? _closures : const <LocalFunctionElement>[]; |
+ } |
+ |
+ void registerConstSymbolName(String name) { |
+ if (_constSymbolNames == null) { |
+ _constSymbolNames = new Setlet<String>(); |
+ } |
+ _constSymbolNames.add(name); |
+ } |
+ |
+ @override |
+ Iterable<String> get constSymbolNames { |
+ return _constSymbolNames != null |
+ ? _constSymbolNames : const <String>[]; |
+ } |
+ |
+ void registerFeature(Feature feature) { |
+ if (_features == null) { |
+ _features = new Setlet<Feature>(); |
+ } |
+ _features.add(feature); |
+ } |
+ |
+ @override |
+ Iterable<Feature> get features { |
+ return _features != null ? _features : const <Feature>[]; |
+ } |
+ |
+ String toString() => '$registry'; |
} |
+/// [ResolutionRegistry] collects all resolution information. It stores node |
+/// related information in a [TreeElements] mapping and registers calls with |
+/// [Backend], [World] and [Enqueuer]. |
+// TODO(johnniwinther): Split this into an interface and implementation class. |
class ResolutionRegistry implements Registry { |
final Compiler compiler; |
final TreeElementMapping mapping; |
- final ResolutionWorldImpact worldImpact; |
+ final _ResolutionWorldImpact worldImpact; |
ResolutionRegistry(Compiler compiler, TreeElementMapping mapping) |
: this.compiler = compiler, |
this.mapping = mapping, |
- this.worldImpact = new ResolutionWorldImpact(compiler, mapping); |
+ this.worldImpact = new _ResolutionWorldImpact(compiler, mapping); |
bool get isForResolution => true; |
@@ -401,7 +536,7 @@ class ResolutionRegistry implements Registry { |
} |
void registerImplicitSuperCall(FunctionElement superConstructor) { |
- universe.registerImplicitSuperCall(this, superConstructor); |
+ registerDependency(superConstructor); |
} |
// TODO(johnniwinther): Remove this. |
@@ -413,47 +548,49 @@ class ResolutionRegistry implements Registry { |
} |
void registerLazyField() { |
- backend.resolutionCallbacks.onLazyField(this); |
+ worldImpact.registerFeature(Feature.LAZY_FIELD); |
} |
- void registerMetadataConstant(MetadataAnnotation metadata, |
- Element annotatedElement) { |
- backend.registerMetadataConstant(metadata, annotatedElement, this); |
+ void registerMetadataConstant(MetadataAnnotation metadata) { |
+ backend.registerMetadataConstant(metadata, metadata.annotatedElement, this); |
} |
void registerThrowRuntimeError() { |
- backend.resolutionCallbacks.onThrowRuntimeError(this); |
+ worldImpact.registerFeature(Feature.THROW_RUNTIME_ERROR); |
} |
void registerCompileTimeError(ErroneousElement error) { |
- backend.resolutionCallbacks.onCompileTimeError(this, error); |
+ worldImpact.registerFeature(Feature.COMPILE_TIME_ERROR); |
} |
void registerTypeVariableBoundCheck() { |
- backend.resolutionCallbacks.onTypeVariableBoundCheck(this); |
+ worldImpact.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK); |
} |
void registerThrowNoSuchMethod() { |
- backend.resolutionCallbacks.onThrowNoSuchMethod(this); |
+ worldImpact.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
} |
+ /// Register a checked mode check against [type]. |
+ void registerCheckedModeCheck(DartType type) { |
+ worldImpact.registerCheckedModeCheckedType(type); |
+ mapping.addRequiredType(type); |
+ } |
+ |
+ /// Register an is-test or is-not-test of [type]. |
void registerIsCheck(DartType type) { |
- worldImpact.registerCheckedType(type); |
- backend.resolutionCallbacks.onIsCheck(type, this); |
+ worldImpact.registerIsCheck(type); |
mapping.addRequiredType(type); |
} |
- void registerAsCheck(DartType type) { |
- registerIsCheck(type); |
- backend.resolutionCallbacks.onAsCheck(type, this); |
+ /// Register an as-cast of [type]. |
+ void registerAsCast(DartType type) { |
+ worldImpact.registerAsCast(type); |
mapping.addRequiredType(type); |
} |
void registerClosure(LocalFunctionElement element) { |
- if (element.computeType(compiler.resolution).containsTypeVariables) { |
- backend.registerClosureWithFreeTypeVariables(element, world, this); |
- } |
- world.registerClosure(element); |
+ worldImpact.registerClosure(element); |
} |
void registerSuperUse(Node node) { |
@@ -465,22 +602,30 @@ class ResolutionRegistry implements Registry { |
} |
void registerSuperNoSuchMethod() { |
- backend.resolutionCallbacks.onSuperNoSuchMethod(this); |
- } |
- |
- void registerTypeVariableExpression(TypeVariableElement element) { |
- backend.resolutionCallbacks.onTypeVariableExpression(this, element); |
+ worldImpact.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
} |
void registerTypeLiteral(Send node, DartType type) { |
mapping.setType(node, type); |
- backend.resolutionCallbacks.onTypeLiteral(type, this); |
- backend.registerInstantiatedType(compiler.coreTypes.typeType, world, this); |
+ worldImpact.registerTypeLiteral(type); |
} |
- void registerMapLiteral(Node node, DartType type, bool isConstant) { |
+ void registerLiteralList(Node node, |
+ InterfaceType type, |
+ {bool isConstant, |
+ bool isEmpty}) { |
setType(node, type); |
- backend.resolutionCallbacks.onMapLiteral(this, type, isConstant); |
+ worldImpact.registerListLiteral( |
+ new ListLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty)); |
+ } |
+ |
+ void registerMapLiteral(Node node, |
+ InterfaceType type, |
+ {bool isConstant, |
+ bool isEmpty}) { |
+ setType(node, type); |
+ worldImpact.registerMapLiteral( |
+ new MapLiteralUse(type, isConstant: isConstant, isEmpty: isEmpty)); |
} |
void registerForeignCall(Node node, |
@@ -507,49 +652,49 @@ class ResolutionRegistry implements Registry { |
} |
void registerConstSymbol(String name) { |
- backend.registerConstSymbol(name, this); |
+ worldImpact.registerConstSymbolName(name); |
} |
void registerSymbolConstructor() { |
- backend.resolutionCallbacks.onSymbolConstructor(this); |
+ worldImpact.registerFeature(Feature.SYMBOL_CONSTRUCTOR); |
} |
void registerInstantiatedType(InterfaceType type) { |
- backend.registerInstantiatedType(type, world, this); |
+ worldImpact.registerInstantiatedType(type); |
mapping.addRequiredType(type); |
} |
void registerAbstractClassInstantiation() { |
- backend.resolutionCallbacks.onAbstractClassInstantiation(this); |
+ worldImpact.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION); |
} |
void registerNewSymbol() { |
- backend.registerNewSymbol(this); |
+ worldImpact.registerFeature(Feature.NEW_SYMBOL); |
} |
void registerRequiredType(DartType type, Element enclosingElement) { |
- backend.registerRequiredType(type, enclosingElement); |
+ worldImpact.registerRequiredType(type); |
mapping.addRequiredType(type); |
} |
void registerStringInterpolation() { |
- backend.resolutionCallbacks.onStringInterpolation(this); |
+ worldImpact.registerFeature(Feature.STRING_INTERPOLATION); |
} |
void registerFallThroughError() { |
- backend.resolutionCallbacks.onFallThroughError(this); |
+ worldImpact.registerFeature(Feature.FALL_THROUGH_ERROR); |
} |
void registerCatchStatement() { |
- backend.resolutionCallbacks.onCatchStatement(this); |
+ worldImpact.registerFeature(Feature.CATCH_STATEMENT); |
} |
void registerStackTraceInCatch() { |
- backend.resolutionCallbacks.onStackTraceInCatch(this); |
+ worldImpact.registerFeature(Feature.STACK_TRACE_IN_CATCH); |
} |
void registerSyncForIn(Node node) { |
- backend.resolutionCallbacks.onSyncForIn(this); |
+ worldImpact.registerFeature(Feature.SYNC_FOR_IN); |
} |
ClassElement defaultSuperclass(ClassElement element) { |
@@ -562,7 +707,7 @@ class ResolutionRegistry implements Registry { |
} |
void registerThrowExpression() { |
- backend.resolutionCallbacks.onThrowExpression(this); |
+ worldImpact.registerFeature(Feature.THROW_EXPRESSION); |
} |
void registerDependency(Element element) { |
@@ -580,11 +725,12 @@ class ResolutionRegistry implements Registry { |
} |
void registerInstantiation(InterfaceType type) { |
- backend.registerInstantiatedType(type, world, this); |
+ registerInstantiatedType(type); |
} |
void registerAssert(bool hasMessage) { |
- backend.resolutionCallbacks.onAssert(hasMessage, this); |
+ worldImpact.registerFeature( |
+ hasMessage ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT); |
} |
void registerSendStructure(Send node, SendStructure sendStructure) { |
@@ -598,15 +744,27 @@ class ResolutionRegistry implements Registry { |
} |
void registerAsyncMarker(FunctionElement element) { |
- backend.registerAsyncMarker(element, world, this); |
+ switch (element.asyncMarker) { |
+ case AsyncMarker.SYNC: |
+ break; |
+ case AsyncMarker.SYNC_STAR: |
+ worldImpact.registerFeature(Feature.SYNC_STAR); |
+ break; |
+ case AsyncMarker.ASYNC: |
+ worldImpact.registerFeature(Feature.ASYNC); |
+ break; |
+ case AsyncMarker.ASYNC_STAR: |
+ worldImpact.registerFeature(Feature.ASYNC_STAR); |
+ break; |
+ } |
} |
void registerAsyncForIn(AsyncForIn node) { |
- backend.resolutionCallbacks.onAsyncForIn(node, this); |
+ worldImpact.registerFeature(Feature.ASYNC_FOR_IN); |
} |
void registerIncDecOperation() { |
- backend.resolutionCallbacks.onIncDecOperation(this); |
+ worldImpact.registerFeature(Feature.INC_DEC_OPERATION); |
} |
void registerTryStatement() { |