Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Unified Diff: pkg/compiler/lib/src/js_backend/runtime_types.dart

Issue 2884233002: Use entities in runtime_types (Closed)
Patch Set: Remove debug print Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/js_backend/runtime_types.dart
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 9b54dcd33f539775817e284b82318634206d2440..5b8100ae2c50afb671a75a5702f661c15679880f 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -2,28 +2,46 @@
// 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.
-part of js_backend.backend;
+library js_backend.runtime_types;
+
+import '../common_elements.dart' show CommonElements, ElementEnvironment;
+import '../elements/elements.dart' show ClassElement;
+import '../elements/entities.dart';
+import '../elements/resolution_types.dart'
+ show
+ MalformedType,
+ MethodTypeVariableType,
+ ResolutionDartTypeVisitor,
+ ResolutionTypedefType,
+ Types;
+import '../elements/types.dart';
+import '../js/js.dart' as jsAst;
+import '../js/js.dart' show js;
+import '../js_emitter/js_emitter.dart' show Emitter;
+import '../universe/world_builder.dart';
+import '../world.dart' show ClosedWorld;
+import 'backend_usage.dart';
+import 'namer.dart';
/// For each class, stores the possible class subtype tests that could succeed.
abstract class TypeChecks {
/// Get the set of checks required for class [element].
- Iterable<TypeCheck> operator [](ClassElement element);
+ Iterable<TypeCheck> operator [](ClassEntity element);
/// Get the iterable for all classes that need type checks.
- Iterable<ClassElement> get classes;
+ Iterable<ClassEntity> get classes;
}
-typedef jsAst.Expression OnVariableCallback(
- ResolutionTypeVariableType variable);
+typedef jsAst.Expression OnVariableCallback(TypeVariableType variable);
typedef bool ShouldEncodeTypedefCallback(ResolutionTypedefType variable);
/// Interface for the classes and methods that need runtime types.
abstract class RuntimeTypesNeed {
- bool classNeedsRti(ClassElement cls);
- bool classNeedsRtiField(ClassElement cls);
- bool methodNeedsRti(MethodElement function);
- bool localFunctionNeedsRti(LocalFunctionElement function);
- bool classUsesTypeVariableExpression(ClassElement cls);
+ bool classNeedsRti(ClassEntity cls);
+ bool classNeedsRtiField(ClassEntity cls);
+ bool methodNeedsRti(FunctionEntity function);
+ bool localFunctionNeedsRti(Local function);
+ bool classUsesTypeVariableExpression(ClassEntity cls);
}
/// Interface for computing classes and methods that need runtime types.
@@ -63,44 +81,45 @@ abstract class RuntimeTypesChecks {
/// Return all classes that are referenced in the type of the function, i.e.,
/// in the return type or the argument types.
- Set<ClassElement> getReferencedClasses(ResolutionFunctionType type);
+ Set<ClassEntity> getReferencedClasses(FunctionType type);
/// Return all classes that are uses a type arguments.
- Set<ClassElement> getRequiredArgumentClasses();
+ Set<ClassEntity> getRequiredArgumentClasses();
}
/// Interface for computing the needed runtime type checks.
abstract class RuntimeTypesChecksBuilder {
void registerTypeVariableBoundsSubtypeCheck(
- ResolutionDartType typeArgument, ResolutionDartType bound);
+ DartType typeArgument, DartType bound);
/// Computes the [RuntimeTypesChecks] for the data in this builder.
- RuntimeTypesChecks computeRequiredChecks();
+ RuntimeTypesChecks computeRequiredChecks(
+ CodegenWorldBuilder codegenWorldBuilder);
/// Compute type arguments of classes that use one of their type variables in
/// is-checks and add the is-checks that they imply.
///
/// This function must be called after all is-checks have been registered.
void registerImplicitChecks(
- WorldBuilder worldBuilder, Iterable<ClassElement> classesUsingChecks);
+ WorldBuilder worldBuilder, Iterable<ClassEntity> classesUsingChecks);
}
/// Interface for computing substitutions need for runtime type checks.
abstract class RuntimeTypesSubstitutions {
- bool isTrivialSubstitution(ClassElement cls, ClassElement check);
+ bool isTrivialSubstitution(ClassEntity cls, ClassEntity check);
- Substitution getSubstitution(ClassElement cls, ClassElement other);
+ Substitution getSubstitution(ClassEntity cls, ClassEntity other);
/// Compute the required type checks and substitutions for the given
/// instantitated and checked classes.
TypeChecks computeChecks(
- Set<ClassElement> instantiated, Set<ClassElement> checked);
+ Set<ClassEntity> instantiated, Set<ClassEntity> checked);
- Set<ClassElement> getClassesUsedInSubstitutions(TypeChecks checks);
+ Set<ClassEntity> getClassesUsedInSubstitutions(TypeChecks checks);
- static bool hasTypeArguments(ResolutionDartType type) {
- if (type is ResolutionInterfaceType) {
- ResolutionInterfaceType interfaceType = type;
+ static bool hasTypeArguments(DartType type) {
+ if (type is InterfaceType) {
+ InterfaceType interfaceType = type;
return !interfaceType.treatAsRaw;
}
return false;
@@ -108,13 +127,13 @@ abstract class RuntimeTypesSubstitutions {
}
abstract class RuntimeTypesEncoder {
- bool isSimpleFunctionType(ResolutionFunctionType type);
+ bool isSimpleFunctionType(FunctionType type);
jsAst.Expression getSignatureEncoding(
- Emitter emitter, ResolutionDartType type, jsAst.Expression this_);
+ Emitter emitter, DartType type, jsAst.Expression this_);
- jsAst.Expression getSubstitutionRepresentation(Emitter emitter,
- List<ResolutionDartType> types, OnVariableCallback onVariable);
+ jsAst.Expression getSubstitutionRepresentation(
+ Emitter emitter, List<DartType> types, OnVariableCallback onVariable);
jsAst.Expression getSubstitutionCode(
Emitter emitter, Substitution substitution);
@@ -130,10 +149,10 @@ abstract class RuntimeTypesEncoder {
/// Returns a [jsAst.Expression] representing the given [type]. Type variables
/// are replaced by the [jsAst.Expression] returned by [onVariable].
jsAst.Expression getTypeRepresentation(
- Emitter emitter, ResolutionDartType type, OnVariableCallback onVariable,
+ Emitter emitter, DartType type, OnVariableCallback onVariable,
[ShouldEncodeTypedefCallback shouldEncodeTypedef]);
- String getTypeRepresentationForTypeConstant(ResolutionDartType type);
+ String getTypeRepresentationForTypeConstant(DartType type);
}
/// Common functionality for [_RuntimeTypesNeedBuilder] and [_RuntimeTypes].
@@ -236,12 +255,12 @@ class _RuntimeTypesNeed implements RuntimeTypesNeed {
return classesNeedingRti.contains(cls);
}
- bool methodNeedsRti(MethodElement function) {
+ bool methodNeedsRti(FunctionEntity function) {
return methodsNeedingRti.contains(function) ||
_backendUsage.isRuntimeTypeUsed;
}
- bool localFunctionNeedsRti(LocalFunctionElement function) {
+ bool localFunctionNeedsRti(Local function) {
return localFunctionsNeedingRti.contains(function) ||
_backendUsage.isRuntimeTypeUsed;
}
@@ -395,7 +414,7 @@ class RuntimeTypesNeedBuilderImpl extends _RuntimeTypesBase
// information.
resolutionWorldBuilder.isChecks.forEach((DartType type) {
if (type.isInterfaceType) {
- ResolutionInterfaceType itf = type;
+ InterfaceType itf = type;
if (!itf.treatAsRaw) {
potentiallyAddForRti(itf.element);
}
@@ -474,15 +493,15 @@ class ResolutionRuntimeTypesNeedBuilderImpl
class _RuntimeTypesChecks implements RuntimeTypesChecks {
final RuntimeTypesSubstitutions substitutions;
final TypeChecks requiredChecks;
- final Set<ClassElement> directlyInstantiatedArguments;
- final Set<ClassElement> checkedArguments;
+ final Set<ClassEntity> directlyInstantiatedArguments;
+ final Set<ClassEntity> checkedArguments;
_RuntimeTypesChecks(this.substitutions, this.requiredChecks,
this.directlyInstantiatedArguments, this.checkedArguments);
@override
- Set<ClassElement> getRequiredArgumentClasses() {
- Set<ClassElement> requiredArgumentClasses = new Set<ClassElement>.from(
+ Set<ClassEntity> getRequiredArgumentClasses() {
+ Set<ClassEntity> requiredArgumentClasses = new Set<ClassEntity>.from(
substitutions.getClassesUsedInSubstitutions(requiredChecks));
return requiredArgumentClasses
..addAll(directlyInstantiatedArguments)
@@ -490,41 +509,35 @@ class _RuntimeTypesChecks implements RuntimeTypesChecks {
}
@override
- Set<ClassElement> getReferencedClasses(ResolutionFunctionType type) {
+ Set<ClassEntity> getReferencedClasses(FunctionType type) {
FunctionArgumentCollector collector = new FunctionArgumentCollector();
collector.collect(type);
return collector.classes;
}
}
-class _RuntimeTypes extends _RuntimeTypesBase
+class RuntimeTypesImpl extends _RuntimeTypesBase
implements RuntimeTypesChecksBuilder, RuntimeTypesSubstitutions {
- final Compiler compiler;
+ final ElementEnvironment _elementEnvironment;
// The set of type arguments tested against type variable bounds.
- final Set<ResolutionDartType> checkedTypeArguments;
+ final Set<DartType> checkedTypeArguments = new Set<DartType>();
// The set of tested type variable bounds.
- final Set<ResolutionDartType> checkedBounds;
+ final Set<DartType> checkedBounds = new Set<DartType>();
TypeChecks cachedRequiredChecks;
- JavaScriptBackend get backend => compiler.backend;
-
bool rtiChecksBuilderClosed = false;
- _RuntimeTypes(Compiler compiler)
- : this.compiler = compiler,
- checkedTypeArguments = new Set<ResolutionDartType>(),
- checkedBounds = new Set<ResolutionDartType>(),
- super(compiler.types);
+ RuntimeTypesImpl(this._elementEnvironment, DartTypes types) : super(types);
- Set<ClassElement> directlyInstantiatedArguments;
- Set<ClassElement> allInstantiatedArguments;
- Set<ClassElement> checkedArguments;
+ Set<ClassEntity> directlyInstantiatedArguments;
+ Set<ClassEntity> allInstantiatedArguments;
+ Set<ClassEntity> checkedArguments;
@override
void registerTypeVariableBoundsSubtypeCheck(
- ResolutionDartType typeArgument, ResolutionDartType bound) {
+ DartType typeArgument, DartType bound) {
checkedTypeArguments.add(typeArgument);
checkedBounds.add(bound);
}
@@ -536,16 +549,14 @@ class _RuntimeTypes extends _RuntimeTypesBase
// arguments and record all combination where the element of a checked
// argument is a superclass of the element of an instantiated type.
TypeCheckMapping result = new TypeCheckMapping();
- for (ClassElement element in instantiated) {
+ for (ClassEntity element in instantiated) {
if (checked.contains(element)) {
result.add(element, element, null);
}
// Find all supertypes of [element] in [checkedArguments] and add checks
// and precompute the substitutions for them.
- assert(invariant(element, element.allSupertypes != null,
- message: 'Supertypes have not been computed for $element.'));
- for (ResolutionInterfaceType supertype in element.allSupertypes) {
- ClassElement superelement = supertype.element;
+ for (InterfaceType supertype in _types.getSupertypes(element)) {
+ ClassEntity superelement = supertype.element;
if (checked.contains(superelement)) {
Substitution substitution =
computeSubstitution(element, superelement);
@@ -556,11 +567,12 @@ class _RuntimeTypes extends _RuntimeTypesBase
return result;
}
- RuntimeTypesChecks computeRequiredChecks() {
- Set<ResolutionDartType> isChecks = compiler.codegenWorldBuilder.isChecks;
+ RuntimeTypesChecks computeRequiredChecks(
+ CodegenWorldBuilder codegenWorldBuilder) {
+ Set<DartType> isChecks = codegenWorldBuilder.isChecks;
// These types are needed for is-checks against function types.
- Set<ResolutionDartType> instantiatedTypesAndClosures =
- computeInstantiatedTypesAndClosures(compiler.codegenWorldBuilder);
+ Set<DartType> instantiatedTypesAndClosures =
+ computeInstantiatedTypesAndClosures(codegenWorldBuilder);
computeInstantiatedArguments(instantiatedTypesAndClosures, isChecks);
computeCheckedArguments(instantiatedTypesAndClosures, isChecks);
cachedRequiredChecks =
@@ -570,27 +582,24 @@ class _RuntimeTypes extends _RuntimeTypesBase
directlyInstantiatedArguments, checkedArguments);
}
- Set<ResolutionDartType> computeInstantiatedTypesAndClosures(
- CodegenWorldBuilder worldBuilder) {
- Set<ResolutionDartType> instantiatedTypes =
- new Set<ResolutionDartType>.from(worldBuilder.instantiatedTypes);
- for (ResolutionInterfaceType instantiatedType
- in worldBuilder.instantiatedTypes) {
- ResolutionFunctionType callType = instantiatedType.callType;
+ Set<DartType> computeInstantiatedTypesAndClosures(
+ CodegenWorldBuilder codegenWorldBuilder) {
+ Set<DartType> instantiatedTypes =
+ new Set<DartType>.from(codegenWorldBuilder.instantiatedTypes);
+ for (InterfaceType instantiatedType
+ in codegenWorldBuilder.instantiatedTypes) {
+ FunctionType callType = _types.getCallType(instantiatedType);
if (callType != null) {
instantiatedTypes.add(callType);
}
}
- for (FunctionElement element in worldBuilder.staticFunctionsNeedingGetter) {
- instantiatedTypes.add(element.type);
+ for (FunctionEntity element
+ in codegenWorldBuilder.staticFunctionsNeedingGetter) {
+ instantiatedTypes.add(_elementEnvironment.getFunctionType(element));
}
- // TODO(johnniwinther): We should get this information through the
- // [neededClasses] computed in the emitter instead of storing it and pulling
- // it from resolution, but currently it would introduce a cyclic dependency
- // between [computeRequiredChecks] and [computeNeededClasses].
- for (MethodElement element
- in compiler.resolutionWorldBuilder.closurizedMembers) {
- instantiatedTypes.add(element.type);
+
+ for (FunctionEntity element in codegenWorldBuilder.closurizedMembers) {
+ instantiatedTypes.add(_elementEnvironment.getFunctionType(element));
}
return instantiatedTypes;
}
@@ -602,8 +611,8 @@ class _RuntimeTypes extends _RuntimeTypesBase
* have a type check against this supertype that includes a check against
* the type arguments.
*/
- void computeInstantiatedArguments(Set<ResolutionDartType> instantiatedTypes,
- Set<ResolutionDartType> isChecks) {
+ void computeInstantiatedArguments(
+ Set<DartType> instantiatedTypes, Set<DartType> isChecks) {
ArgumentCollector superCollector = new ArgumentCollector();
ArgumentCollector directCollector = new ArgumentCollector();
FunctionArgumentCollector functionArgumentCollector =
@@ -611,8 +620,8 @@ class _RuntimeTypes extends _RuntimeTypesBase
// We need to add classes occurring in function type arguments, like for
// instance 'I' for [: o is C<f> :] where f is [: typedef I f(); :].
- void collectFunctionTypeArguments(Iterable<ResolutionDartType> types) {
- for (ResolutionDartType type in types) {
+ void collectFunctionTypeArguments(Iterable<DartType> types) {
+ for (DartType type in types) {
functionArgumentCollector.collect(type);
}
}
@@ -620,13 +629,13 @@ class _RuntimeTypes extends _RuntimeTypesBase
collectFunctionTypeArguments(isChecks);
collectFunctionTypeArguments(checkedBounds);
- void collectTypeArguments(Iterable<ResolutionDartType> types,
+ void collectTypeArguments(Iterable<DartType> types,
{bool isTypeArgument: false}) {
- for (ResolutionDartType type in types) {
+ for (DartType type in types) {
directCollector.collect(type, isTypeArgument: isTypeArgument);
- if (type.isInterfaceType) {
- ClassElement cls = type.element;
- for (ResolutionInterfaceType supertype in cls.allSupertypes) {
+ if (type is InterfaceType) {
+ ClassEntity cls = type.element;
+ for (InterfaceType supertype in _types.getSupertypes(cls)) {
superCollector.collect(supertype, isTypeArgument: isTypeArgument);
}
}
@@ -636,8 +645,8 @@ class _RuntimeTypes extends _RuntimeTypesBase
collectTypeArguments(instantiatedTypes);
collectTypeArguments(checkedTypeArguments, isTypeArgument: true);
- for (ClassElement cls in superCollector.classes.toList()) {
- for (ResolutionInterfaceType supertype in cls.allSupertypes) {
+ for (ClassEntity cls in superCollector.classes.toList()) {
+ for (InterfaceType supertype in _types.getSupertypes(cls)) {
superCollector.collect(supertype);
}
}
@@ -649,8 +658,8 @@ class _RuntimeTypes extends _RuntimeTypesBase
}
/// Collects all type arguments used in is-checks.
- void computeCheckedArguments(Set<ResolutionDartType> instantiatedTypes,
- Set<ResolutionDartType> isChecks) {
+ void computeCheckedArguments(
+ Set<DartType> instantiatedTypes, Set<DartType> isChecks) {
ArgumentCollector collector = new ArgumentCollector();
FunctionArgumentCollector functionArgumentCollector =
new FunctionArgumentCollector();
@@ -658,8 +667,8 @@ class _RuntimeTypes extends _RuntimeTypesBase
// We need to add types occurring in function type arguments, like for
// instance 'J' for [: (J j) {} is f :] where f is
// [: typedef void f(I i); :] and 'J' is a subtype of 'I'.
- void collectFunctionTypeArguments(Iterable<ResolutionDartType> types) {
- for (ResolutionDartType type in types) {
+ void collectFunctionTypeArguments(Iterable<DartType> types) {
+ for (DartType type in types) {
functionArgumentCollector.collect(type);
}
}
@@ -667,9 +676,9 @@ class _RuntimeTypes extends _RuntimeTypesBase
collectFunctionTypeArguments(instantiatedTypes);
collectFunctionTypeArguments(checkedTypeArguments);
- void collectTypeArguments(Iterable<ResolutionDartType> types,
+ void collectTypeArguments(Iterable<DartType> types,
{bool isTypeArgument: false}) {
- for (ResolutionDartType type in types) {
+ for (DartType type in types) {
collector.collect(type, isTypeArgument: isTypeArgument);
}
}
@@ -682,10 +691,10 @@ class _RuntimeTypes extends _RuntimeTypesBase
}
@override
- Set<ClassElement> getClassesUsedInSubstitutions(TypeChecks checks) {
- Set<ClassElement> instantiated = new Set<ClassElement>();
+ Set<ClassEntity> getClassesUsedInSubstitutions(TypeChecks checks) {
+ Set<ClassEntity> instantiated = new Set<ClassEntity>();
ArgumentCollector collector = new ArgumentCollector();
- for (ClassElement target in checks.classes) {
+ for (ClassEntity target in checks.classes) {
instantiated.add(target);
for (TypeCheck check in checks[target]) {
Substitution substitution = check.substitution;
@@ -702,7 +711,7 @@ class _RuntimeTypes extends _RuntimeTypesBase
// TODO(karlklose): maybe precompute this value and store it in typeChecks?
@override
- bool isTrivialSubstitution(ClassElement cls, ClassElement check) {
+ bool isTrivialSubstitution(ClassEntity cls, ClassEntity check) {
if (cls.isClosure) {
// TODO(karlklose): handle closures.
return true;
@@ -710,12 +719,12 @@ class _RuntimeTypes extends _RuntimeTypesBase
// If there are no type variables or the type is the same, we do not need
// a substitution.
- if (check.typeVariables.isEmpty || cls == check) {
+ if (!_elementEnvironment.isGenericClass(check) || cls == check) {
return true;
}
- ResolutionInterfaceType originalType = cls.thisType;
- ResolutionInterfaceType type = originalType.asInstanceOf(check);
+ InterfaceType originalType = _elementEnvironment.getThisType(cls);
+ InterfaceType type = _types.asInstanceOf(originalType, check);
// [type] is not a subtype of [check]. we do not generate a check and do not
// need a substitution.
if (type == null) return true;
@@ -723,13 +732,13 @@ class _RuntimeTypes extends _RuntimeTypesBase
// Run through both lists of type variables and check if the type variables
// are identical at each position. If they are not, we need to calculate a
// substitution function.
- List<ResolutionDartType> variables = cls.typeVariables;
- List<ResolutionDartType> arguments = type.typeArguments;
+ List<DartType> variables = originalType.typeArguments;
+ List<DartType> arguments = type.typeArguments;
if (variables.length != arguments.length) {
return false;
}
for (int index = 0; index < variables.length; index++) {
- if (variables[index].element != arguments[index].element) {
+ if (variables[index] != arguments[index]) {
return false;
}
}
@@ -737,7 +746,7 @@ class _RuntimeTypes extends _RuntimeTypesBase
}
@override
- Substitution getSubstitution(ClassElement cls, ClassElement other) {
+ Substitution getSubstitution(ClassEntity cls, ClassEntity other) {
// Look for a precomputed check.
for (TypeCheck check in cachedRequiredChecks[cls]) {
if (check.cls == other) {
@@ -749,16 +758,16 @@ class _RuntimeTypes extends _RuntimeTypesBase
return computeSubstitution(cls, other);
}
- Substitution computeSubstitution(ClassElement cls, ClassElement check,
+ Substitution computeSubstitution(ClassEntity cls, ClassEntity check,
{bool alwaysGenerateFunction: false}) {
if (isTrivialSubstitution(cls, check)) return null;
// Unnamed mixin application classes do not need substitutions, because they
// are never instantiated and their checks are overwritten by the class that
// they are mixed into.
- ResolutionInterfaceType type = cls.thisType;
- ResolutionInterfaceType target = type.asInstanceOf(check);
- List<ResolutionDartType> typeVariables = cls.typeVariables;
+ InterfaceType type = _elementEnvironment.getThisType(cls);
+ InterfaceType target = _types.asInstanceOf(type, check);
+ List<DartType> typeVariables = type.typeArguments;
if (typeVariables.isEmpty && !alwaysGenerateFunction) {
return new Substitution.list(target.typeArguments);
} else {
@@ -767,20 +776,22 @@ class _RuntimeTypes extends _RuntimeTypesBase
}
}
-class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
+class RuntimeTypesEncoderImpl implements RuntimeTypesEncoder {
final Namer namer;
+ final ElementEnvironment _elementEnvironment;
final CommonElements commonElements;
final TypeRepresentationGenerator _representationGenerator;
- _RuntimeTypesEncoder(this.namer, this.commonElements)
+ RuntimeTypesEncoderImpl(
+ this.namer, this._elementEnvironment, this.commonElements)
: _representationGenerator = new TypeRepresentationGenerator(namer);
@override
- bool isSimpleFunctionType(ResolutionFunctionType type) {
+ bool isSimpleFunctionType(FunctionType type) {
if (!type.returnType.isDynamic) return false;
if (!type.optionalParameterTypes.isEmpty) return false;
if (!type.namedParameterTypes.isEmpty) return false;
- for (ResolutionDartType parameter in type.parameterTypes) {
+ for (DartType parameter in type.parameterTypes) {
if (!parameter.isDynamic) return false;
}
return true;
@@ -802,29 +813,32 @@ class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
@override
jsAst.Expression getTypeRepresentation(
- Emitter emitter, ResolutionDartType type, OnVariableCallback onVariable,
+ Emitter emitter, DartType type, OnVariableCallback onVariable,
[ShouldEncodeTypedefCallback shouldEncodeTypedef]) {
// GENERIC_METHODS: When generic method support is complete enough to
// include a runtime value for method type variables this must be updated.
- return _representationGenerator.getTypeRepresentation(emitter,
- type.dynamifyMethodTypeVariableType, onVariable, shouldEncodeTypedef);
+ return _representationGenerator.getTypeRepresentation(
+ emitter,
+ type /*.dynamifyMethodTypeVariableType*/,
Siggi Cherem (dart-lang) 2017/05/17 16:14:11 rewrite as TODO to make it easier to grep for?
Johnni Winther 2017/05/18 08:10:56 Should just have been removed. The dynamification
+ onVariable,
+ shouldEncodeTypedef);
}
@override
- jsAst.Expression getSubstitutionRepresentation(Emitter emitter,
- List<ResolutionDartType> types, OnVariableCallback onVariable) {
+ jsAst.Expression getSubstitutionRepresentation(
+ Emitter emitter, List<DartType> types, OnVariableCallback onVariable) {
List<jsAst.Expression> elements = types
- .map((ResolutionDartType type) =>
- getTypeRepresentation(emitter, type, onVariable))
+ .map(
+ (DartType type) => getTypeRepresentation(emitter, type, onVariable))
.toList(growable: false);
return new jsAst.ArrayInitializer(elements);
}
- jsAst.Expression getTypeEncoding(Emitter emitter, ResolutionDartType type,
+ jsAst.Expression getTypeEncoding(Emitter emitter, DartType type,
{bool alwaysGenerateFunction: false}) {
- ClassElement contextClass = Types.getClassContext(type);
- jsAst.Expression onVariable(ResolutionTypeVariableType v) {
- return new jsAst.VariableUse(v.name);
+ ClassEntity contextClass = Types.getClassContext(type);
+ jsAst.Expression onVariable(TypeVariableType v) {
+ return new jsAst.VariableUse(v.element.name);
}
jsAst.Expression encoding =
@@ -834,8 +848,11 @@ class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
} else {
List<String> parameters = const <String>[];
if (contextClass != null) {
- parameters = contextClass.typeVariables.map((type) {
- return type.name;
+ parameters = _elementEnvironment
+ .getThisType(contextClass)
+ .typeArguments
+ .map((TypeVariableType type) {
+ return type.element.name;
}).toList();
}
return js('function(#) { return # }', [parameters, encoding]);
@@ -844,8 +861,8 @@ class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
@override
jsAst.Expression getSignatureEncoding(
- Emitter emitter, ResolutionDartType type, jsAst.Expression this_) {
- ClassElement contextClass = Types.getClassContext(type);
+ Emitter emitter, DartType type, jsAst.Expression this_) {
+ ClassEntity contextClass = Types.getClassContext(type);
jsAst.Expression encoding =
getTypeEncoding(emitter, type, alwaysGenerateFunction: true);
if (contextClass != null) {
@@ -878,23 +895,22 @@ class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
@override
jsAst.Expression getSubstitutionCode(
Emitter emitter, Substitution substitution) {
- jsAst.Expression declaration(ResolutionTypeVariableType variable) {
- return new jsAst.Parameter(getVariableName(variable.name));
+ jsAst.Expression declaration(TypeVariableType variable) {
+ return new jsAst.Parameter(getVariableName(variable.element.name));
}
- jsAst.Expression use(ResolutionTypeVariableType variable) {
- return new jsAst.VariableUse(getVariableName(variable.name));
+ jsAst.Expression use(TypeVariableType variable) {
+ return new jsAst.VariableUse(getVariableName(variable.element.name));
}
- if (substitution.arguments
- .every((ResolutionDartType type) => type.isDynamic)) {
+ if (substitution.arguments.every((DartType type) => type.isDynamic)) {
return emitter.generateFunctionThatReturnsNull();
} else {
jsAst.Expression value =
getSubstitutionRepresentation(emitter, substitution.arguments, use);
if (substitution.isFunction) {
Iterable<jsAst.Expression> formals =
- substitution.parameters.map(declaration);
+ substitution.parameters.map((type) => declaration(type));
Siggi Cherem (dart-lang) 2017/05/17 16:14:11 undo?
Johnni Winther 2017/05/18 08:10:56 Can't do (stupid type system!): [declaration] has
return js('function(#) { return # }', [formals, value]);
} else {
return js('function() { return # }', value);
@@ -911,19 +927,24 @@ class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
namer.internalGlobal('functionThatReturnsNull');
@override
- String getTypeRepresentationForTypeConstant(ResolutionDartType type) {
+ String getTypeRepresentationForTypeConstant(DartType type) {
if (type.isDynamic) return "dynamic";
- String name = namer.uniqueNameForTypeConstantElement(type.element);
- if (!type.element.isClass) return name;
- ResolutionInterfaceType interface = type;
- List<ResolutionDartType> variables = interface.element.typeVariables;
+ if (type is ResolutionTypedefType) {
+ return namer.uniqueNameForTypeConstantElement(
+ type.element.library, type.element);
+ }
+ InterfaceType interface = type;
+ String name = namer.uniqueNameForTypeConstantElement(
+ interface.element.library, interface.element);
+
// Type constants can currently only be raw types, so there is no point
// adding ground-term type parameters, as they would just be 'dynamic'.
// TODO(sra): Since the result string is used only in constructing constant
// names, it would result in more readable names if the final string was a
// legal JavaScript identifer.
- if (variables.isEmpty) return name;
- String arguments = new List.filled(variables.length, 'dynamic').join(', ');
+ if (interface.typeArguments.isEmpty) return name;
+ String arguments =
+ new List.filled(interface.typeArguments.length, 'dynamic').join(', ');
return '$name<$arguments>';
}
}
@@ -932,7 +953,7 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
final Namer namer;
OnVariableCallback onVariable;
ShouldEncodeTypedefCallback shouldEncodeTypedef;
- Map<ResolutionTypeVariableType, jsAst.Expression> typedefBindings;
+ Map<TypeVariableType, jsAst.Expression> typedefBindings;
TypeRepresentationGenerator(this.namer);
@@ -942,7 +963,7 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
*/
jsAst.Expression getTypeRepresentation(
Emitter emitter,
- ResolutionDartType type,
+ DartType type,
OnVariableCallback onVariable,
ShouldEncodeTypedefCallback encodeTypedef) {
assert(typedefBindings == null);
@@ -956,14 +977,22 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
return representation;
}
- jsAst.Expression getJavaScriptClassName(Element element, Emitter emitter) {
+ jsAst.Expression getJavaScriptClassName(Entity element, Emitter emitter) {
return emitter.typeAccess(element);
}
- @override
- visit(ResolutionDartType type, Emitter emitter) => type.accept(this, emitter);
+ jsAst.Expression getDynamicValue() => js('null');
- visitTypeVariableType(ResolutionTypeVariableType type, Emitter emitter) {
+ @override
+ visit(DartType type, Emitter emitter) => type.accept(this, emitter);
+
+ visitTypeVariableType(TypeVariableType type, Emitter emitter) {
+ if (type.element.typeDeclaration is! ClassEntity) {
+ /// A [TypeVariableType] from a generic method is replaced by a
Siggi Cherem (dart-lang) 2017/05/17 16:14:11 this appears to be new - bug fix? should we add a
Johnni Winther 2017/05/18 08:10:56 This is instead of using [dynamifyMethodTypeVariab
+ /// [DynamicType].
+ /// GENERIC_METHODS: Temporary, only used with '--generic-method-syntax'.
+ return getDynamicValue();
+ }
if (typedefBindings != null) {
assert(typedefBindings[type] != null);
return typedefBindings[type];
@@ -971,24 +1000,24 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
return onVariable(type);
}
- visitDynamicType(ResolutionDynamicType type, Emitter emitter) {
- return js('null');
+ visitDynamicType(DynamicType type, Emitter emitter) {
+ return getDynamicValue();
}
- visitInterfaceType(ResolutionInterfaceType type, Emitter emitter) {
+ visitInterfaceType(InterfaceType type, Emitter emitter) {
jsAst.Expression name = getJavaScriptClassName(type.element, emitter);
return type.treatAsRaw
? name
: visitList(type.typeArguments, emitter, head: name);
}
- jsAst.Expression visitList(List<ResolutionDartType> types, Emitter emitter,
+ jsAst.Expression visitList(List<DartType> types, Emitter emitter,
{jsAst.Expression head}) {
List<jsAst.Expression> elements = <jsAst.Expression>[];
if (head != null) {
elements.add(head);
}
- for (ResolutionDartType type in types) {
+ for (DartType type in types) {
jsAst.Expression element = visit(type, emitter);
if (element is jsAst.LiteralNull) {
elements.add(new jsAst.ArrayHole());
@@ -1014,7 +1043,7 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
.expressionTemplateFor('{ ${namer.functionTypeTag}: "dynafunc" }');
}
- visitFunctionType(ResolutionFunctionType type, Emitter emitter) {
+ visitFunctionType(FunctionType type, Emitter emitter) {
List<jsAst.Property> properties = <jsAst.Property>[];
void addProperty(String name, jsAst.Expression value) {
@@ -1041,7 +1070,7 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
if (!type.namedParameterTypes.isEmpty) {
List<jsAst.Property> namedArguments = <jsAst.Property>[];
List<String> names = type.namedParameters;
- List<ResolutionDartType> types = type.namedParameterTypes;
+ List<DartType> types = type.namedParameterTypes;
assert(types.length == names.length);
for (int index = 0; index < types.length; index++) {
jsAst.Expression name = js.string(names[index]);
@@ -1059,14 +1088,14 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
return js('null');
}
- visitVoidType(ResolutionVoidType type, Emitter emitter) {
+ visitVoidType(VoidType type, Emitter emitter) {
// TODO(ahe): Reify void type ("null" means "dynamic").
return js('null');
}
visitTypedefType(ResolutionTypedefType type, Emitter emitter) {
bool shouldEncode = shouldEncodeTypedef(type);
- ResolutionDartType unaliasedType = type.unaliased;
+ DartType unaliasedType = type.unaliased;
var oldBindings = typedefBindings;
if (typedefBindings == null) {
@@ -1090,8 +1119,8 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
// HTypeInfoExpression). This would share all the Set<T> subexpressions
// instead of duplicating them. This would require HTypeInfoExpression
// inputs to correspond to type variables AND typedefs.
- typedefBindings = <ResolutionTypeVariableType, jsAst.Expression>{};
- type.forEachTypeVariable((variable) {
+ typedefBindings = <TypeVariableType, jsAst.Expression>{};
+ type.forEachTypeVariable((TypeVariableType variable) {
if (variable is! MethodTypeVariableType) {
typedefBindings[variable] = onVariable(variable);
}
@@ -1122,25 +1151,25 @@ class TypeRepresentationGenerator implements ResolutionDartTypeVisitor {
}
class TypeCheckMapping implements TypeChecks {
- final Map<ClassElement, Set<TypeCheck>> map =
- new Map<ClassElement, Set<TypeCheck>>();
+ final Map<ClassEntity, Set<TypeCheck>> map =
+ new Map<ClassEntity, Set<TypeCheck>>();
- Iterable<TypeCheck> operator [](ClassElement element) {
+ Iterable<TypeCheck> operator [](ClassEntity element) {
Set<TypeCheck> result = map[element];
return result != null ? result : const <TypeCheck>[];
}
- void add(ClassElement cls, ClassElement check, Substitution substitution) {
+ void add(ClassEntity cls, ClassEntity check, Substitution substitution) {
map.putIfAbsent(cls, () => new Set<TypeCheck>());
map[cls].add(new TypeCheck(check, substitution));
}
- Iterable<ClassElement> get classes => map.keys;
+ Iterable<ClassEntity> get classes => map.keys;
String toString() {
StringBuffer sb = new StringBuffer();
- for (ClassElement holder in classes) {
- for (ClassElement check in [holder]) {
+ for (ClassEntity holder in classes) {
+ for (ClassEntity check in [holder]) {
sb.write('${holder.name}.' '${check.name}, ');
}
}
@@ -1149,64 +1178,68 @@ class TypeCheckMapping implements TypeChecks {
}
class ArgumentCollector extends ResolutionDartTypeVisitor {
- final Set<ClassElement> classes = new Set<ClassElement>();
+ final Set<ClassEntity> classes = new Set<ClassEntity>();
- collect(ResolutionDartType type, {bool isTypeArgument: false}) {
+ collect(DartType type, {bool isTypeArgument: false}) {
visit(type, isTypeArgument);
}
/// Collect all types in the list as if they were arguments of an
/// InterfaceType.
- collectAll(List<ResolutionDartType> types) {
- for (ResolutionDartType type in types) {
+ collectAll(List<DartType> types, {bool isTypeArgument: false}) {
+ for (DartType type in types) {
visit(type, true);
}
}
visitTypedefType(ResolutionTypedefType type, bool isTypeArgument) {
- type.unaliased.accept(this, isTypeArgument);
+ collect(type.unaliased, isTypeArgument: isTypeArgument);
}
- visitInterfaceType(ResolutionInterfaceType type, bool isTypeArgument) {
+ visitInterfaceType(InterfaceType type, bool isTypeArgument) {
if (isTypeArgument) classes.add(type.element);
- type.visitChildren(this, true);
+ collectAll(type.typeArguments, isTypeArgument: true);
}
- visitFunctionType(ResolutionFunctionType type, _) {
- type.visitChildren(this, true);
+ visitFunctionType(FunctionType type, _) {
+ collect(type.returnType, isTypeArgument: true);
+ collectAll(type.parameterTypes, isTypeArgument: true);
+ collectAll(type.optionalParameterTypes, isTypeArgument: true);
+ collectAll(type.namedParameterTypes, isTypeArgument: true);
}
}
class FunctionArgumentCollector extends ResolutionDartTypeVisitor {
- final Set<ClassElement> classes = new Set<ClassElement>();
+ final Set<ClassEntity> classes = new Set<ClassEntity>();
FunctionArgumentCollector();
- collect(ResolutionDartType type) {
- visit(type, false);
+ collect(DartType type, {bool inFunctionType: false}) {
+ visit(type, inFunctionType);
}
- /// Collect all types in the list as if they were arguments of an
- /// InterfaceType.
- collectAll(Link<ResolutionDartType> types) {
- for (ResolutionDartType type in types) {
- visit(type, true);
+ collectAll(List<DartType> types, {bool inFunctionType: false}) {
+ for (DartType type in types) {
+ visit(type, inFunctionType);
}
}
visitTypedefType(ResolutionTypedefType type, bool inFunctionType) {
- type.unaliased.accept(this, inFunctionType);
+ collect(type.unaliased, inFunctionType: inFunctionType);
}
- visitInterfaceType(ResolutionInterfaceType type, bool inFunctionType) {
+ visitInterfaceType(InterfaceType type, bool inFunctionType) {
if (inFunctionType) {
classes.add(type.element);
}
- type.visitChildren(this, inFunctionType);
+ collectAll(type.typeArguments, inFunctionType: inFunctionType);
}
- visitFunctionType(ResolutionFunctionType type, _) {
- type.visitChildren(this, true);
+ visitFunctionType(FunctionType type, _) {
+ collect(type.returnType, inFunctionType: true);
+ collectAll(type.parameterTypes, inFunctionType: true);
+ collectAll(type.optionalParameterTypes, inFunctionType: true);
+ collectAll(type.namedParameterTypes, inFunctionType: true);
}
}
@@ -1222,12 +1255,12 @@ class FunctionArgumentCollector extends ResolutionDartTypeVisitor {
//TODO(floitsch): Remove support for non-function substitutions.
class Substitution {
final bool isFunction;
- final List<ResolutionDartType> arguments;
- final List<ResolutionDartType> parameters;
+ final List<DartType> arguments;
+ final List<DartType> parameters;
Substitution.list(this.arguments)
: isFunction = false,
- parameters = const <ResolutionDartType>[];
+ parameters = const <DartType>[];
Substitution.function(this.arguments, this.parameters) : isFunction = true;
}
@@ -1237,7 +1270,7 @@ class Substitution {
* substition for this check.
*/
class TypeCheck {
- final ClassElement cls;
+ final ClassEntity cls;
final Substitution substitution;
final int hashCode = _nextHash = (_nextHash + 100003).toUnsigned(30);
static int _nextHash = 0;

Powered by Google App Engine
This is Rietveld 408576698