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

Unified Diff: pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart

Issue 2954493002: Less inequivalence on Hello World! (Closed)
Patch Set: Updated cf. comments Created 3 years, 6 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_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(

Powered by Google App Engine
This is Rietveld 408576698