Index: pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart |
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart |
index 692676b58445d4f8d4c11e4d0109e089604a7e89..c9d418f3e2f036ab2433b1768ef91c695e4188f3 100644 |
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart |
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart |
@@ -8,11 +8,9 @@ import '../closure.dart' |
show ClosureRepresentationInfo, ClosureFieldElement, ClosureConversionTask; |
import '../common.dart'; |
import '../common/names.dart' show Identifiers; |
-import '../common_elements.dart' show CommonElements; |
-import '../elements/resolution_types.dart' |
- show ResolutionDartType, ResolutionFunctionType, ResolutionInterfaceType; |
+import '../common_elements.dart' show CommonElements, ElementEnvironment; |
import '../elements/elements.dart' |
- show ClassElement, Element, FunctionElement, MixinApplicationElement; |
+ show ClassElement, MethodElement, MixinApplicationElement; |
import '../elements/entities.dart'; |
import '../elements/types.dart'; |
import '../js/js.dart' as jsAst; |
@@ -30,15 +28,16 @@ import '../js_backend/runtime_types.dart' |
TypeCheck, |
TypeChecks; |
import '../util/util.dart' show Setlet; |
+import '../world.dart'; |
import 'code_emitter_task.dart' show CodeEmitterTask; |
import 'type_test_registry.dart' show TypeTestRegistry; |
// Function signatures used in the generation of runtime type information. |
typedef void FunctionTypeSignatureEmitter( |
- Element method, ResolutionFunctionType methodType); |
+ FunctionEntity method, FunctionType methodType); |
-typedef void SubstitutionEmitter(Element element, {bool emitNull}); |
+typedef void SubstitutionEmitter(ClassEntity element, {bool emitNull}); |
class TypeTestProperties { |
/// The index of the function type into the metadata. |
@@ -51,13 +50,16 @@ class TypeTestProperties { |
jsAst.Expression functionTypeIndex; |
/// The properties that must be installed on the prototype of the |
- /// JS constructor of the [ClassElement] for which the is checks were |
+ /// JS constructor of the [ClassEntity] for which the is checks were |
/// generated. |
final Map<jsAst.Name, jsAst.Node> properties = <jsAst.Name, jsAst.Node>{}; |
} |
class RuntimeTypeGenerator { |
+ final ElementEnvironment _elementEnvironment; |
final CommonElements _commonElements; |
+ final DartTypes _types; |
+ final ClosedWorld _closedWorld; |
final ClosureConversionTask _closureDataLookup; |
final CodeEmitterTask emitterTask; |
final Namer _namer; |
@@ -69,7 +71,10 @@ class RuntimeTypeGenerator { |
final JsInteropAnalysis _jsInteropAnalysis; |
RuntimeTypeGenerator( |
+ this._elementEnvironment, |
this._commonElements, |
+ this._types, |
+ this._closedWorld, |
this._closureDataLookup, |
this.emitterTask, |
this._namer, |
@@ -100,30 +105,28 @@ class RuntimeTypeGenerator { |
/// type (if class has one) in the metadata object and stores its index in |
/// the result. This is only possible for function types that do not contain |
/// type variables. |
- TypeTestProperties generateIsTests(ClassEntity cls, |
+ TypeTestProperties generateIsTests(ClassEntity classElement, |
{bool storeFunctionTypeInMetadata: true}) { |
TypeTestProperties result = new TypeTestProperties(); |
- if (cls is! ClassElement) return result; |
- // TODO(johnniwinther): Handle class entities. |
- ClassElement classElement = cls; |
- assert(classElement.isDeclaration, failedAt(classElement)); |
+ assert(!(classElement is ClassElement && !classElement.isDeclaration), |
+ failedAt(classElement)); |
/// Generates an is-test if the test is not inherited from a superclass |
/// This assumes that for every class an is-tests is generated |
/// dynamically at runtime. We also always generate tests against |
/// native classes. |
/// TODO(herhut): Generate tests for native classes dynamically, as well. |
- void generateIsTest(ClassElement other) { |
+ void generateIsTest(ClassEntity other) { |
if (_nativeData.isNativeClass(classElement) || |
- !classElement.isSubclassOf(other)) { |
+ !_closedWorld.isSubclassOf(classElement, other)) { |
result.properties[_namer.operatorIs(other)] = js('1'); |
} |
} |
void generateFunctionTypeSignature( |
- FunctionElement method, ResolutionFunctionType type) { |
- assert(method.isImplementation); |
+ FunctionEntity method, FunctionType type) { |
+ assert(!(method is MethodElement && !method.isImplementation)); |
jsAst.Expression thisAccess = new jsAst.This(); |
if (!method.isAbstract) { |
ClosureRepresentationInfo closureData = |
@@ -148,8 +151,8 @@ class RuntimeTypeGenerator { |
} |
} |
- void generateSubstitution(ClassElement cls, {bool emitNull: false}) { |
- if (cls.typeVariables.isEmpty) return; |
+ void generateSubstitution(ClassEntity cls, {bool emitNull: false}) { |
+ if (!_elementEnvironment.isGenericClass(cls)) return; |
jsAst.Expression expression; |
bool needsNativeCheck = |
emitterTask.nativeEmitter.requiresNativeIsCheck(cls); |
@@ -168,7 +171,7 @@ class RuntimeTypeGenerator { |
} |
void generateTypeCheck(TypeCheck check) { |
- ClassElement checkedClass = check.cls; |
+ ClassEntity checkedClass = check.cls; |
generateIsTest(checkedClass); |
Substitution substitution = check.substitution; |
if (substitution != null) { |
@@ -178,12 +181,11 @@ class RuntimeTypeGenerator { |
} |
} |
- _generateIsTestsOn(classElement, (Element e) { |
- generateIsTest(e); |
- }, (Element e, ResolutionFunctionType t) { |
- generateFunctionTypeSignature(e, t); |
- }, |
- (Element e, {bool emitNull: false}) => |
+ _generateIsTestsOn( |
+ classElement, |
+ generateIsTest, |
+ generateFunctionTypeSignature, |
+ (ClassEntity e, {bool emitNull: false}) => |
generateSubstitution(e, emitNull: emitNull), |
generateTypeCheck); |
@@ -208,12 +210,12 @@ class RuntimeTypeGenerator { |
* substitutions, because they may have changed. |
*/ |
void _generateIsTestsOn( |
- ClassElement cls, |
- void generateIsTest(Element element), |
+ ClassEntity cls, |
+ void generateIsTest(ClassEntity element), |
FunctionTypeSignatureEmitter generateFunctionTypeSignature, |
SubstitutionEmitter generateSubstitution, |
void emitTypeCheck(TypeCheck check)) { |
- Setlet<ClassElement> generated = new Setlet<ClassElement>(); |
+ Setlet<ClassEntity> generated = new Setlet<ClassEntity>(); |
if (checkedClasses.contains(cls)) { |
generateIsTest(cls); |
@@ -233,9 +235,9 @@ class RuntimeTypeGenerator { |
} |
} |
- ClassElement superclass = cls.superclass; |
+ ClassEntity superclass = _elementEnvironment.getSuperClass(cls); |
- bool haveSameTypeVariables(ClassElement a, ClassElement b) { |
+ bool haveSameTypeVariables(ClassEntity a, ClassEntity b) { |
if (a.isClosure) return true; |
return _rtiSubstitutions.isTrivialSubstitution(a, b); |
} |
@@ -257,7 +259,7 @@ class RuntimeTypeGenerator { |
generateSubstitution(superclass, emitNull: true); |
generated.add(superclass); |
} |
- superclass = superclass.superclass; |
+ superclass = _elementEnvironment.getSuperClass(superclass); |
} |
supertypesNeedSubstitutions = true; |
} |
@@ -267,9 +269,9 @@ class RuntimeTypeGenerator { |
} |
if (supertypesNeedSubstitutions) { |
- for (ResolutionInterfaceType supertype in cls.allSupertypes) { |
- ClassElement superclass = supertype.element; |
- if (generated.contains(superclass)) continue; |
+ _elementEnvironment.forEachSupertype(cls, (InterfaceType supertype) { |
+ ClassEntity superclass = supertype.element; |
+ if (generated.contains(superclass)) return; |
if (classesUsingTypeVariableTests.contains(superclass) || |
_rtiNeed.classUsesTypeVariableExpression(superclass) || |
@@ -279,7 +281,7 @@ class RuntimeTypeGenerator { |
// super classes. |
generateSubstitution(superclass, emitNull: true); |
} |
- } |
+ }); |
void emitNothing(_, {emitNull}) {} |
@@ -290,25 +292,25 @@ class RuntimeTypeGenerator { |
// [Function] and needs checks for all typedefs that are used in is-checks. |
if (checkedClasses.contains(_commonElements.functionClass) || |
checkedFunctionTypes.isNotEmpty) { |
- Element call = cls.lookupLocalMember(Identifiers.call); |
- if (call == null) { |
- // If [cls] is a closure, it has a synthetic call operator method. |
- call = cls.lookupConstructorBody(Identifiers.call); |
- } |
+ MemberEntity call = |
+ _elementEnvironment.lookupClassMember(cls, Identifiers.call); |
if (call != null && call.isFunction) { |
- FunctionElement callFunction = call; |
+ FunctionEntity callFunction = call; |
// A superclass might already implement the Function interface. In such |
- // a case, we can avoid emiting the is test here. |
- if (!cls.superclass.implementsFunction(_commonElements)) { |
+ // a case, we can avoid emitting the is test here. |
+ ClassEntity superclass = _elementEnvironment.getSuperClass(cls); |
+ if (!_closedWorld.isSubclassOf( |
+ superclass, _commonElements.functionClass)) { |
_generateInterfacesIsTests(_commonElements.functionClass, |
generateIsTest, generateSubstitution, generated); |
} |
- ResolutionFunctionType callType = callFunction.type; |
+ FunctionType callType = |
+ _elementEnvironment.getFunctionType(callFunction); |
generateFunctionTypeSignature(callFunction, callType); |
} |
} |
- for (ResolutionDartType interfaceType in cls.interfaces) { |
+ for (InterfaceType interfaceType in _types.getInterfaces(cls)) { |
_generateInterfacesIsTests(interfaceType.element, generateIsTest, |
generateSubstitution, generated); |
} |
@@ -318,11 +320,11 @@ class RuntimeTypeGenerator { |
* Generate "is tests" where [cls] is being implemented. |
*/ |
void _generateInterfacesIsTests( |
- ClassElement cls, |
- void generateIsTest(ClassElement element), |
+ ClassEntity cls, |
+ void generateIsTest(ClassEntity element), |
SubstitutionEmitter generateSubstitution, |
- Set<Element> alreadyGenerated) { |
- void tryEmitTest(ClassElement check) { |
+ Set<ClassEntity> alreadyGenerated) { |
+ void tryEmitTest(ClassEntity check) { |
if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) { |
alreadyGenerated.add(check); |
generateIsTest(check); |
@@ -332,15 +334,15 @@ class RuntimeTypeGenerator { |
tryEmitTest(cls); |
- for (ResolutionDartType interfaceType in cls.interfaces) { |
- Element element = interfaceType.element; |
+ for (InterfaceType interfaceType in _types.getInterfaces(cls)) { |
+ ClassEntity element = interfaceType.element; |
tryEmitTest(element); |
_generateInterfacesIsTests( |
element, generateIsTest, generateSubstitution, alreadyGenerated); |
} |
// We need to also emit "is checks" for the superclass and its supertypes. |
- ClassElement superclass = cls.superclass; |
+ ClassEntity superclass = _elementEnvironment.getSuperClass(cls); |
if (superclass != null) { |
tryEmitTest(superclass); |
_generateInterfacesIsTests( |