Introduce TypedefEntity

R=sigmund@google.com

Review-Url: https://codereview.chromium.org/2981633002 .
This commit is contained in:
Johnni Winther 2017-07-13 11:14:01 +02:00
parent f644cffa33
commit cb6bef3cb4
15 changed files with 75 additions and 40 deletions

View file

@ -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<ConstantValue> getMemberMetadata(MemberEntity member);
/// Returns the function type that is an alias of a [typedef].
FunctionType getFunctionTypeOfTypedef(TypedefEntity typedef);
}

View file

@ -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.
///

View file

@ -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;

View file

@ -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<ClassEntity> classesInMirrorsUsedTargets = new Set<ClassEntity>();
final Set<LibraryEntity> librariesInMirrorsUsedTargets =
new Set<LibraryEntity>();
final Set<TypedefElement> _typedefsInMirrorsUsedTargets =
new Set<TypedefElement>();
final Set<TypedefEntity> _typedefsInMirrorsUsedTargets =
new Set<TypedefEntity>();
/// 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);

View file

@ -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);

View file

@ -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<OutputUnit, List<FieldEntity>> outputStaticNonFinalFieldLists;
Map<OutputUnit, Set<LibraryEntity>> outputLibraryLists;
List<TypedefElement> typedefsNeededForReflection;
List<TypedefEntity> 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 =

View file

@ -50,7 +50,7 @@ class Collector {
final List<ClassElement> nativeClassesAndSubclasses = <ClassElement>[];
List<TypedefElement> typedefsNeededForReflection;
List<TypedefEntity> 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());

View file

@ -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;

View file

@ -15,6 +15,9 @@ abstract class Sorter {
/// Returns a sorted list of [classes].
Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes);
/// Returns a sorted list of [typedefs].
Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs);
/// Returns a sorted list of [members].
Iterable<MemberEntity> sortMembers(Iterable<MemberEntity> members);
}
@ -32,6 +35,11 @@ class ElementSorter implements Sorter {
return Elements.sortedByPosition(new List.from(classes, growable: false));
}
@override
Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs) {
return Elements.sortedByPosition(new List.from(typedefs, growable: false));
}
@override
List<MemberEntity> sortMembers(Iterable<MemberEntity> members) {
return Elements.sortedByPosition(new List.from(members, growable: false));

View file

@ -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<TypedefElement>());
allTypedefs: new ImmutableEmptySet<TypedefEntity>());
}
@override
@ -360,7 +359,7 @@ class JsClosedWorld extends ClosedWorldBase with KernelClosedWorldMixin {
Iterable<ClassEntity> liveNativeClasses,
Iterable<MemberEntity> liveInstanceMembers,
Iterable<MemberEntity> assignedInstanceMembers,
Set<TypedefElement> allTypedefs,
Set<TypedefEntity> allTypedefs,
Map<ClassEntity, Set<ClassEntity>> mixinUses,
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,

View file

@ -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<ClassEntity> liveNativeClasses,
Iterable<MemberEntity> liveInstanceMembers,
Iterable<MemberEntity> assignedInstanceMembers,
Set<TypedefElement> allTypedefs,
Set<TypedefEntity> allTypedefs,
Map<ClassEntity, Set<ClassEntity>> mixinUses,
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,

View file

@ -241,4 +241,11 @@ class KernelSorter implements Sorter {
a, elementMap.getClassNode(a), b, elementMap.getClassNode(b));
});
}
@override
Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs) {
// TODO(redemption): Support this.
assert(typedefs.isEmpty);
return typedefs;
}
}

View file

@ -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

View file

@ -359,7 +359,7 @@ abstract class ResolutionWorldBuilderBase
ClosedWorld _closedWorldCache;
final Set<MemberEntity> _liveInstanceMembers = new Set<MemberEntity>();
final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>();
final Set<TypedefEntity> _allTypedefs = new Set<TypedefEntity>();
final Map<ClassEntity, Set<ClassEntity>> _mixinUses =
new Map<ClassEntity, Set<ClassEntity>>();
@ -776,7 +776,7 @@ abstract class ResolutionWorldBuilderBase
return uses != null ? uses : const <ClassEntity>[];
}
void registerTypedef(TypedefElement typdef) {
void registerTypedef(TypedefEntity typdef) {
_allTypedefs.add(typdef);
}

View file

@ -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<TypedefElement> get allTypedefs;
Iterable<TypedefEntity> 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<TypedefElement> _allTypedefs;
final Set<TypedefEntity> _allTypedefs;
final Map<ClassEntity, Set<ClassEntity>> mixinUses;
Map<ClassEntity, List<ClassEntity>> _liveMixinUses;
@ -474,7 +473,7 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
this.liveNativeClasses,
this.liveInstanceMembers,
this.assignedInstanceMembers,
Set<TypedefElement> allTypedefs,
Set<TypedefEntity> allTypedefs,
this.mixinUses,
this.typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
@ -1017,7 +1016,7 @@ abstract class ClosedWorldBase implements ClosedWorld, ClosedWorldRefiner {
return _classSets[cls];
}
Iterable<TypedefElement> get allTypedefs => _allTypedefs;
Iterable<TypedefEntity> get allTypedefs => _allTypedefs;
void _ensureFunctionSet() {
if (_allFunctions == null) {
@ -1207,7 +1206,7 @@ class ClosedWorldImpl extends ClosedWorldBase with ClosedWorldRtiNeedMixin {
Iterable<ClassEntity> liveNativeClasses,
Iterable<MemberEntity> liveInstanceMembers,
Iterable<MemberEntity> assignedInstanceMembers,
Set<TypedefElement> allTypedefs,
Set<TypedefEntity> allTypedefs,
Map<ClassEntity, Set<ClassEntity>> mixinUses,
Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,