Chromium Code Reviews| 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); |
|
Siggi Cherem (dart-lang)
2017/06/23 19:49:28
Was this basically dead code?
I'm guessing this u
Johnni Winther
2017/06/26 09:17:44
Yes. Yes.
|
| - } |
| + 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( |