Chromium Code Reviews| 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..8e2383d255f91a7997e175093a4d8e047e419944 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,33 @@ class EagerRegistry implements Registry { |
| String toString() => 'EagerRegistry for ${mapping.analyzedElement}'; |
| } |
| -class ResolutionWorldImpact implements WorldImpact { |
| +class _ResolutionWorldImpact implements ResolutionWorldImpact { |
| final Registry registry; |
| 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 +168,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 +180,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 +244,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>(); |
|
sigurdm
2015/10/06 09:17:14
Is it worth it not just initializing these in the
Johnni Winther
2015/10/06 10:48:43
Maybe. Have to investigate further. Adding a TODO.
|
| + } |
| + _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 +295,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 +534,7 @@ class ResolutionRegistry implements Registry { |
| } |
| void registerImplicitSuperCall(FunctionElement superConstructor) { |
| - universe.registerImplicitSuperCall(this, superConstructor); |
| + registerDependency(superConstructor); |
| } |
| // TODO(johnniwinther): Remove this. |
| @@ -413,47 +546,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) { |
|
sigurdm
2015/10/06 09:17:14
?
Johnni Winther
2015/10/06 10:48:43
Code is moved to .transformImpact
|
| - if (element.computeType(compiler.resolution).containsTypeVariables) { |
| - backend.registerClosureWithFreeTypeVariables(element, world, this); |
| - } |
| - world.registerClosure(element); |
| + worldImpact.registerClosure(element); |
| } |
| void registerSuperUse(Node node) { |
| @@ -465,22 +600,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 +650,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 +705,7 @@ class ResolutionRegistry implements Registry { |
| } |
| void registerThrowExpression() { |
| - backend.resolutionCallbacks.onThrowExpression(this); |
| + worldImpact.registerFeature(Feature.THROW_EXPRESSION); |
| } |
| void registerDependency(Element element) { |
| @@ -580,11 +723,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 +742,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() { |