| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| library dart2js.common.codegen; | |
| import '../common_elements.dart'; | |
| import '../elements/entities.dart'; | |
| import '../elements/types.dart' show DartType, InterfaceType; | |
| import '../universe/feature.dart'; | |
| import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse; | |
| import '../universe/world_impact.dart' | |
| show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor; | |
| import '../util/enumset.dart'; | |
| import '../util/util.dart' show Pair, Setlet; | |
| import 'work.dart' show WorkItem; | |
| class CodegenImpact extends WorldImpact { | |
| const CodegenImpact(); | |
| Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { | |
| return const <Pair<DartType, DartType>>[]; | |
| } | |
| Iterable<String> get constSymbols => const <String>[]; | |
| Iterable<Set<ClassEntity>> get specializedGetInterceptors { | |
| return const <Set<ClassEntity>>[]; | |
| } | |
| bool get usesInterceptor => false; | |
| Iterable<AsyncMarker> get asyncMarkers => const <AsyncMarker>[]; | |
| Iterable<GenericInstantiation> get genericInstantiations => | |
| const <GenericInstantiation>[]; | |
| } | |
| class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact { | |
| Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks; | |
| Setlet<String> _constSymbols; | |
| List<Set<ClassEntity>> _specializedGetInterceptors; | |
| bool _usesInterceptor = false; | |
| EnumSet<AsyncMarker> _asyncMarkers; | |
| Set<GenericInstantiation> _genericInstantiations; | |
| _CodegenImpact(); | |
| void apply(WorldImpactVisitor visitor) { | |
| staticUses.forEach(visitor.visitStaticUse); | |
| dynamicUses.forEach(visitor.visitDynamicUse); | |
| typeUses.forEach(visitor.visitTypeUse); | |
| } | |
| void registerTypeVariableBoundsSubtypeCheck( | |
| DartType subtype, DartType supertype) { | |
| _typeVariableBoundsSubtypeChecks ??= new Setlet<Pair<DartType, DartType>>(); | |
| _typeVariableBoundsSubtypeChecks | |
| .add(new Pair<DartType, DartType>(subtype, supertype)); | |
| } | |
| Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { | |
| return _typeVariableBoundsSubtypeChecks != null | |
| ? _typeVariableBoundsSubtypeChecks | |
| : const <Pair<DartType, DartType>>[]; | |
| } | |
| void registerConstSymbol(String name) { | |
| _constSymbols ??= new Setlet<String>(); | |
| _constSymbols.add(name); | |
| } | |
| Iterable<String> get constSymbols { | |
| return _constSymbols != null ? _constSymbols : const <String>[]; | |
| } | |
| void registerSpecializedGetInterceptor(Set<ClassEntity> classes) { | |
| _specializedGetInterceptors ??= <Set<ClassEntity>>[]; | |
| _specializedGetInterceptors.add(classes); | |
| } | |
| Iterable<Set<ClassEntity>> get specializedGetInterceptors { | |
| return _specializedGetInterceptors != null | |
| ? _specializedGetInterceptors | |
| : const <Set<ClassEntity>>[]; | |
| } | |
| void registerUseInterceptor() { | |
| _usesInterceptor = true; | |
| } | |
| bool get usesInterceptor => _usesInterceptor; | |
| void registerAsyncMarker(AsyncMarker asyncMarker) { | |
| _asyncMarkers ??= new EnumSet<AsyncMarker>(); | |
| _asyncMarkers.add(asyncMarker); | |
| } | |
| Iterable<AsyncMarker> get asyncMarkers { | |
| return _asyncMarkers != null | |
| ? _asyncMarkers.iterable(AsyncMarker.values) | |
| : const <AsyncMarker>[]; | |
| } | |
| void registerGenericInstantiation(GenericInstantiation instantiation) { | |
| _genericInstantiations ??= new Set<GenericInstantiation>(); | |
| _genericInstantiations.add(instantiation); | |
| } | |
| @override | |
| Iterable<GenericInstantiation> get genericInstantiations { | |
| return _genericInstantiations ?? const <GenericInstantiation>[]; | |
| } | |
| } | |
| // TODO(johnniwinther): Split this class into interface and implementation. | |
| // TODO(johnniwinther): Move this implementation to the JS backend. | |
| class CodegenRegistry { | |
| final ElementEnvironment _elementEnvironment; | |
| final MemberEntity currentElement; | |
| final _CodegenImpact worldImpact; | |
| CodegenRegistry(this._elementEnvironment, this.currentElement) | |
| : this.worldImpact = new _CodegenImpact(); | |
| bool get isForResolution => false; | |
| String toString() => 'CodegenRegistry for $currentElement'; | |
| @deprecated | |
| void registerInstantiatedClass(ClassEntity element) { | |
| registerInstantiation(_elementEnvironment.getRawType(element)); | |
| } | |
| void registerStaticUse(StaticUse staticUse) { | |
| worldImpact.registerStaticUse(staticUse); | |
| } | |
| void registerDynamicUse(DynamicUse dynamicUse) { | |
| worldImpact.registerDynamicUse(dynamicUse); | |
| } | |
| void registerTypeUse(TypeUse typeUse) { | |
| worldImpact.registerTypeUse(typeUse); | |
| } | |
| void registerConstantUse(ConstantUse constantUse) { | |
| worldImpact.registerConstantUse(constantUse); | |
| } | |
| void registerTypeVariableBoundsSubtypeCheck( | |
| DartType subtype, DartType supertype) { | |
| worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | |
| } | |
| void registerInstantiatedClosure(FunctionEntity element) { | |
| worldImpact.registerStaticUse(new StaticUse.callMethod(element)); | |
| } | |
| void registerConstSymbol(String name) { | |
| worldImpact.registerConstSymbol(name); | |
| } | |
| void registerSpecializedGetInterceptor(Set<ClassEntity> classes) { | |
| worldImpact.registerSpecializedGetInterceptor(classes); | |
| } | |
| void registerUseInterceptor() { | |
| worldImpact.registerUseInterceptor(); | |
| } | |
| void registerInstantiation(InterfaceType type) { | |
| registerTypeUse(new TypeUse.instantiation(type)); | |
| } | |
| void registerAsyncMarker(AsyncMarker asyncMarker) { | |
| worldImpact.registerAsyncMarker(asyncMarker); | |
| } | |
| void registerGenericInstantiation(GenericInstantiation instantiation) { | |
| worldImpact.registerGenericInstantiation(instantiation); | |
| } | |
| } | |
| /// [WorkItem] used exclusively by the [CodegenEnqueuer]. | |
| abstract class CodegenWorkItem extends WorkItem { | |
| CodegenRegistry get registry; | |
| } |