From cb6bef3cb4f251538f3643d1237a9ebdac936fd8 Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Thu, 13 Jul 2017 11:14:01 +0200 Subject: [PATCH] Introduce TypedefEntity R=sigmund@google.com Review-Url: https://codereview.chromium.org/2981633002 . --- pkg/compiler/lib/src/common_elements.dart | 6 +++++- pkg/compiler/lib/src/elements/elements.dart | 6 +++++- pkg/compiler/lib/src/elements/entities.dart | 4 ++++ .../lib/src/js_backend/mirrors_data.dart | 17 ++++++++++------- pkg/compiler/lib/src/js_backend/namer.dart | 5 ++--- .../src/js_emitter/full_emitter/emitter.dart | 15 +++++++-------- .../js_emitter/program_builder/collector.dart | 5 ++--- .../program_builder/program_builder.dart | 4 +--- pkg/compiler/lib/src/js_emitter/sorter.dart | 8 ++++++++ pkg/compiler/lib/src/js_model/js_strategy.dart | 5 ++--- .../lib/src/kernel/element_map_impl.dart | 8 +++++++- .../lib/src/kernel/kernel_backend_strategy.dart | 7 +++++++ .../lib/src/resolution/resolution_strategy.dart | 6 ++++++ .../src/universe/resolution_world_builder.dart | 4 ++-- pkg/compiler/lib/src/world.dart | 15 +++++++-------- 15 files changed, 75 insertions(+), 40 deletions(-) diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart index d2442253623..58b7f9db19d 100644 --- a/pkg/compiler/lib/src/common_elements.dart +++ b/pkg/compiler/lib/src/common_elements.dart @@ -1323,7 +1323,8 @@ abstract class ElementEnvironment { /// Returns the type of the [local] function. FunctionType getLocalFunctionType(Local local); - /// Returns the unaliased type of [type]. + /// Returns the 'unaliased' type of [type]. For typedefs this is the function + /// type it is an alias of, for other types it is the type itself. /// /// Use this during resolution to ensure that the alias has been computed. // TODO(johnniwinther): Remove this when the resolver is removed. @@ -1335,4 +1336,7 @@ abstract class ElementEnvironment { /// Returns the metadata constants declared on [member]. Iterable getMemberMetadata(MemberEntity member); + + /// Returns the function type that is an alias of a [typedef]. + FunctionType getFunctionTypeOfTypedef(TypedefEntity typedef); } diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart index 4fc31e85fcf..0292b009a85 100644 --- a/pkg/compiler/lib/src/elements/elements.dart +++ b/pkg/compiler/lib/src/elements/elements.dart @@ -1055,7 +1055,11 @@ abstract class PrefixElement extends Element { /// A type alias definition. abstract class TypedefElement extends Element - implements AstElement, TypeDeclarationElement, FunctionTypedElement { + implements + AstElement, + TypeDeclarationElement, + FunctionTypedElement, + TypedefEntity { /// The type defined by this typedef with the type variables as its type /// arguments. /// diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart index 80e8489fd8e..2e89c2b4738 100644 --- a/pkg/compiler/lib/src/elements/entities.dart +++ b/pkg/compiler/lib/src/elements/entities.dart @@ -51,6 +51,10 @@ abstract class ClassEntity extends Entity { bool get isAbstract; } +abstract class TypedefEntity extends Entity { + LibraryEntity get library; +} + abstract class TypeVariableEntity extends Entity { /// The class or generic method that declared this type variable. Entity get typeDeclaration; diff --git a/pkg/compiler/lib/src/js_backend/mirrors_data.dart b/pkg/compiler/lib/src/js_backend/mirrors_data.dart index 65222f7f702..413b5dde507 100644 --- a/pkg/compiler/lib/src/js_backend/mirrors_data.dart +++ b/pkg/compiler/lib/src/js_backend/mirrors_data.dart @@ -100,7 +100,7 @@ abstract class MirrorsData { /// checked by the runtime system to throw an exception if an element is /// accessed (invoked, get, set) that is not accessible for the reflective /// system. - bool isTypedefAccessibleByReflection(TypedefElement element); + bool isTypedefAccessibleByReflection(covariant TypedefEntity element); /// Returns `true` if the class [element] needs reflection information at /// runtime. @@ -126,7 +126,7 @@ abstract class MirrorsData { bool retainMetadataOfLibrary(covariant LibraryEntity element, {bool addForEmission: true}); - bool retainMetadataOfTypedef(TypedefElement element); + bool retainMetadataOfTypedef(covariant TypedefEntity element); bool retainMetadataOfClass(covariant ClassEntity element); bool retainMetadataOfMember(covariant MemberEntity element); bool retainMetadataOfParameter(ParameterElement element); @@ -193,8 +193,8 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder { final Set classesInMirrorsUsedTargets = new Set(); final Set librariesInMirrorsUsedTargets = new Set(); - final Set _typedefsInMirrorsUsedTargets = - new Set(); + final Set _typedefsInMirrorsUsedTargets = + new Set(); /// List of annotations provided by user that indicate that the annotated /// element must be retained. @@ -345,7 +345,7 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder { } else if (target.isClass) { classesInMirrorsUsedTargets.add(target as ClassEntity); } else if (target.isTypedef) { - _typedefsInMirrorsUsedTargets.add(target); + _typedefsInMirrorsUsedTargets.add(target as TypedefEntity); } else if (target.isLibrary) { librariesInMirrorsUsedTargets.add(target as LibraryEntity); } else if (target != null) { @@ -657,8 +657,11 @@ class MirrorsDataImpl implements MirrorsData, MirrorsDataBuilder { _classesNeededForReflection.add(cls); } // Add typedefs. - _typedefsNeededForReflection.addAll( - closedWorld.allTypedefs.where(isTypedefReferencedFromMirrorSystem)); + for (TypedefElement element in closedWorld.allTypedefs) { + if (isTypedefReferencedFromMirrorSystem(element)) { + _typedefsNeededForReflection.add(element); + } + } // Register all symbols of reflectable elements for (ClassElement element in _classesNeededForReflection) { symbolsUsed.add(element.name); diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart index 0ecb90e72c6..2ef33ba22b6 100644 --- a/pkg/compiler/lib/src/js_backend/namer.dart +++ b/pkg/compiler/lib/src/js_backend/namer.dart @@ -21,8 +21,7 @@ import '../elements/elements.dart' Elements, FieldElement, MemberElement, - MixinApplicationElement, - TypedefElement; + MixinApplicationElement; import '../elements/entities.dart'; import '../elements/entity_utils.dart' as utils; import '../elements/jumps.dart'; @@ -1532,7 +1531,7 @@ class Namer { } String globalObjectForType(Entity element) { - if (element is TypedefElement) { + if (element is TypedefEntity) { return globalObjectForLibrary(element.library); } return globalObjectForClass(element); diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart index fbea728430c..e47b9f1abbd 100644 --- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart +++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart @@ -16,11 +16,10 @@ import '../../common.dart'; import '../../compiler.dart' show Compiler; import '../../constants/values.dart'; import '../../common_elements.dart' show CommonElements, ElementEnvironment; -import '../../elements/resolution_types.dart' show ResolutionDartType; import '../../deferred_load.dart' show OutputUnit; -import '../../elements/elements.dart' show LibraryElement, TypedefElement; import '../../elements/entities.dart'; import '../../elements/entity_utils.dart' as utils; +import '../../elements/types.dart'; import '../../elements/names.dart'; import '../../hash/sha1.dart' show Hasher; import '../../io/code_output.dart'; @@ -91,7 +90,7 @@ class Emitter extends js_emitter.EmitterBase { // collector. Map> outputStaticNonFinalFieldLists; Map> outputLibraryLists; - List typedefsNeededForReflection; + List typedefsNeededForReflection; final ContainerBuilder containerBuilder = new ContainerBuilder(); final ClassEmitter classEmitter; @@ -513,13 +512,13 @@ class Emitter extends js_emitter.EmitterBase { return null; } - /// Returns the "reflection name" of a [TypedefElement], if needed. + /// Returns the "reflection name" of a [TypedefEntity], if needed. /// /// The reflection name of typedef 'F' is 'F'. /// /// This is used by js_mirrors.dart. String getReflectionTypedefName( - TypedefElement typedef, jsAst.Name mangledName) { + TypedefEntity typedef, jsAst.Name mangledName) { String name = typedef.name; if (backend.mirrorsData.shouldRetainName(name)) { // TODO(ahe): Enable the next line when I can tell the difference between @@ -1157,10 +1156,10 @@ class Emitter extends js_emitter.EmitterBase { // Emit all required typedef declarations into the main output unit. // TODO(karlklose): unify required classes and typedefs to declarations // and have builders for each kind. - for (TypedefElement typedef in typedefsNeededForReflection) { - LibraryElement library = typedef.library; + for (TypedefEntity typedef in typedefsNeededForReflection) { + LibraryEntity library = typedef.library; // TODO(karlklose): add a TypedefBuilder and move this code there. - ResolutionDartType type = typedef.alias; + FunctionType type = _elementEnvironment.getFunctionTypeOfTypedef(typedef); // TODO(zarah): reify type variables once reflection on type arguments of // typedefs is supported. jsAst.Expression typeIndex = diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart index 2eb33f56780..76007aaeda9 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart @@ -50,7 +50,7 @@ class Collector { final List nativeClassesAndSubclasses = []; - List typedefsNeededForReflection; + List typedefsNeededForReflection; Collector( this._options, @@ -197,8 +197,7 @@ class Collector { /// Compute all the classes and typedefs that must be emitted. void computeNeededDeclarations() { // Compute needed typedefs. - typedefsNeededForReflection = Elements.sortedByPosition(_closedWorld - .allTypedefs + typedefsNeededForReflection = _sorter.sortTypedefs(_closedWorld.allTypedefs .where(_mirrorsData.isTypedefAccessibleByReflection) .toList()); diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart index 9b4955b8d10..c6b13181777 100644 --- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart +++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart @@ -17,15 +17,13 @@ import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; import '../../elements/elements.dart' show ClassElement, - Elements, FieldElement, FunctionSignature, GetterElement, LibraryElement, MemberElement, MethodElement, - ParameterElement, - TypedefElement; + ParameterElement; import '../../elements/entities.dart'; import '../../elements/resolution_types.dart' show ResolutionDartType, ResolutionFunctionType, ResolutionTypedefType; diff --git a/pkg/compiler/lib/src/js_emitter/sorter.dart b/pkg/compiler/lib/src/js_emitter/sorter.dart index fbe60820a64..0443577cf3a 100644 --- a/pkg/compiler/lib/src/js_emitter/sorter.dart +++ b/pkg/compiler/lib/src/js_emitter/sorter.dart @@ -15,6 +15,9 @@ abstract class Sorter { /// Returns a sorted list of [classes]. Iterable sortClasses(Iterable classes); + /// Returns a sorted list of [typedefs]. + Iterable sortTypedefs(Iterable typedefs); + /// Returns a sorted list of [members]. Iterable sortMembers(Iterable members); } @@ -32,6 +35,11 @@ class ElementSorter implements Sorter { return Elements.sortedByPosition(new List.from(classes, growable: false)); } + @override + Iterable sortTypedefs(Iterable typedefs) { + return Elements.sortedByPosition(new List.from(typedefs, growable: false)); + } + @override List sortMembers(Iterable members) { return Elements.sortedByPosition(new List.from(members, growable: false)); diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart index d43c778b541..39e66bf21dd 100644 --- a/pkg/compiler/lib/src/js_model/js_strategy.dart +++ b/pkg/compiler/lib/src/js_model/js_strategy.dart @@ -10,7 +10,6 @@ import '../common/tasks.dart'; import '../common_elements.dart'; import '../compiler.dart'; import '../constants/constant_system.dart'; -import '../elements/elements.dart' show TypedefElement; import '../elements/entities.dart'; import '../elements/types.dart'; import '../enqueue.dart'; @@ -297,7 +296,7 @@ class JsBackendStrategy implements KernelBackendStrategy { mixinUses: mixinUses, typesImplementedBySubclasses: typesImplementedBySubclasses, // TODO(johnniwinther): Support this: - allTypedefs: new ImmutableEmptySet()); + allTypedefs: new ImmutableEmptySet()); } @override @@ -360,7 +359,7 @@ class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin { Iterable liveNativeClasses, Iterable liveInstanceMembers, Iterable assignedInstanceMembers, - Set allTypedefs, + Set allTypedefs, Map> mixinUses, Map> typesImplementedBySubclasses, Map classHierarchyNodes, diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart index 2d0056da154..fd3010471b0 100644 --- a/pkg/compiler/lib/src/kernel/element_map_impl.dart +++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart @@ -1288,6 +1288,12 @@ class KernelElementEnvironment implements ElementEnvironment { MemberData memberData = elementMap._memberData[member.memberIndex]; return memberData.getMetadata(elementMap); } + + @override + FunctionType getFunctionTypeOfTypedef(TypedefEntity typedef) { + // TODO(redemption): Support this. + throw new UnsupportedError('ElementEnvironment.getTypedefAlias'); + } } /// Visitor that converts kernel dart types into [DartType]. @@ -1602,7 +1608,7 @@ class KernelClosedWorld extends ClosedWorldBase Iterable liveNativeClasses, Iterable liveInstanceMembers, Iterable assignedInstanceMembers, - Set allTypedefs, + Set allTypedefs, Map> mixinUses, Map> typesImplementedBySubclasses, Map classHierarchyNodes, diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart index 2b6c380ff94..6802220b334 100644 --- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart +++ b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart @@ -241,4 +241,11 @@ class KernelSorter implements Sorter { a, elementMap.getClassNode(a), b, elementMap.getClassNode(b)); }); } + + @override + Iterable sortTypedefs(Iterable typedefs) { + // TODO(redemption): Support this. + assert(typedefs.isEmpty); + return typedefs; + } } diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart index fff581f574b..98222e2b3d4 100644 --- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart +++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart @@ -678,6 +678,12 @@ class _CompilerElementEnvironment implements ElementEnvironment { }); return values; } + + @override + ResolutionFunctionType getFunctionTypeOfTypedef( + covariant TypedefElement typedef) { + return typedef.alias; + } } /// AST-based logic for processing annotations. These annotations are processed diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart index 2f2ba48da25..44c865aefc7 100644 --- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart +++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart @@ -359,7 +359,7 @@ abstract class ResolutionWorldBuilderBase ClosedWorld _closedWorldCache; final Set _liveInstanceMembers = new Set(); - final Set _allTypedefs = new Set(); + final Set _allTypedefs = new Set(); final Map> _mixinUses = new Map>(); @@ -776,7 +776,7 @@ abstract class ResolutionWorldBuilderBase return uses != null ? uses : const []; } - void registerTypedef(TypedefElement typdef) { + void registerTypedef(TypedefEntity typdef) { _allTypedefs.add(typdef); } diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart index b7adef57004..09a3bde487e 100644 --- a/pkg/compiler/lib/src/world.dart +++ b/pkg/compiler/lib/src/world.dart @@ -14,8 +14,7 @@ import 'elements/elements.dart' Element, MemberElement, MethodElement, - MixinApplicationElement, - TypedefElement; + MixinApplicationElement; import 'elements/resolution_types.dart'; import 'elements/types.dart'; import 'js_backend/backend_usage.dart' show BackendUsage; @@ -292,7 +291,7 @@ abstract class ClosedWorld implements World { TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask); /// Returns all resolved typedefs. - Iterable get allTypedefs; + Iterable get allTypedefs; /// Returns the mask for the potential receivers of a dynamic call to /// [selector] on [mask]. @@ -389,7 +388,7 @@ abstract class OpenWorld implements World { void registerClass(covariant ClassEntity cls); void registerUsedElement(MemberEntity element); - void registerTypedef(TypedefElement typedef); + void registerTypedef(TypedefEntity typedef); ClosedWorld closeWorld(); @@ -418,7 +417,7 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner { FunctionSet _allFunctions; - final Set _allTypedefs; + final Set _allTypedefs; final Map> mixinUses; Map> _liveMixinUses; @@ -474,7 +473,7 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner { this.liveNativeClasses, this.liveInstanceMembers, this.assignedInstanceMembers, - Set allTypedefs, + Set allTypedefs, this.mixinUses, this.typesImplementedBySubclasses, Map classHierarchyNodes, @@ -1017,7 +1016,7 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner { return _classSets[cls]; } - Iterable get allTypedefs => _allTypedefs; + Iterable get allTypedefs => _allTypedefs; void _ensureFunctionSet() { if (_allFunctions == null) { @@ -1207,7 +1206,7 @@ class ClosedWorldImpl extends ClosedWorldBase with ClosedWorldRtiNeedMixin { Iterable liveNativeClasses, Iterable liveInstanceMembers, Iterable assignedInstanceMembers, - Set allTypedefs, + Set allTypedefs, Map> mixinUses, Map> typesImplementedBySubclasses, Map classHierarchyNodes,