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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 11478022: Implement is-checks with typedefs for callable objects. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 4d25e3a6beee49848c4bc94adbf2546da46d74ba..c4bed41ac71bf4dc9e9bbf6b27256288b1047478 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -59,6 +59,7 @@ class CodeEmitterTask extends CompilerTask {
*/
final Map<int, String> interceptorClosureCache;
Set<ClassElement> checkedClasses;
+ Set<TypedefElement> checkedTypedefs;
final bool generateSourceMap;
@@ -76,8 +77,13 @@ class CodeEmitterTask extends CompilerTask {
void computeRequiredTypeChecks() {
assert(checkedClasses == null);
checkedClasses = new Set<ClassElement>();
+ checkedTypedefs = new Set<TypedefElement>();
compiler.codegenWorld.isChecks.forEach((DartType t) {
- if (t is InterfaceType) checkedClasses.add(t.element);
+ if (t is InterfaceType) {
+ checkedClasses.add(t.element);
+ } else if (t is TypedefType) {
+ checkedTypedefs.add(t.element);
+ }
});
}
@@ -693,9 +699,9 @@ $lazyInitializerLogic
},
includeBackendMembers: true);
- generateIsTestsOn(classElement, (ClassElement other) {
+ generateIsTestsOn(classElement, (Element other) {
String code;
- if (other.isObject(compiler)) return;
+ if (compiler.objectClass == other) return;
if (nativeEmitter.requiresNativeIsCheck(other)) {
code = 'function() { return true; }';
} else {
@@ -1023,16 +1029,30 @@ $lazyInitializerLogic
* super class because they will be inherited at runtime.
*/
void generateIsTestsOn(ClassElement cls,
- void emitIsTest(ClassElement element)) {
+ void emitIsTest(Element element)) {
if (checkedClasses.contains(cls)) {
emitIsTest(cls);
}
+
Set<Element> generated = new Set<Element>();
// A class that defines a [:call:] method implicitly implements
- // [Function].
- if (checkedClasses.contains(compiler.functionClass)
- && cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME) != null) {
- generateInterfacesIsTests(compiler.functionClass, emitIsTest, generated);
+ // [Function] and needs checks for all typedefs that are used in is-checks.
+ if (checkedClasses.contains(compiler.functionClass) ||
+ !checkedTypedefs.isEmpty) {
+ FunctionElement call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
+ if (call != null) {
+ generateInterfacesIsTests(compiler.functionClass,
+ emitIsTest,
+ generated);
+ FunctionType callType = call.computeType(compiler);
+ for (TypedefElement typedef in checkedTypedefs) {
+ FunctionType typedefType =
+ typedef.computeType(compiler).unalias(compiler);
+ if (compiler.types.isSubtype(callType, typedefType)) {
+ emitIsTest(typedef);
+ }
+ }
+ }
}
for (DartType interfaceType in cls.interfaces) {
generateInterfacesIsTests(interfaceType.element, emitIsTest, generated);

Powered by Google App Engine
This is Rietveld 408576698