| Index: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| index 290200313cb3634a17dbbb759586b8a4897f58b0..a2cffcf2f09c84d36757f28e83471cb10a9e35a2 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/js_backend/backend.dart
|
| @@ -739,7 +739,14 @@ class JavaScriptBackend extends Backend {
|
| /**
|
| * Set of classes whose methods are intercepted.
|
| */
|
| - final Set<ClassElement> interceptedClasses;
|
| + final Set<ClassElement> interceptedClasses = new Set<ClassElement>();
|
| +
|
| + /**
|
| + * Set of classes used as mixins on native classes. Methods on these classes
|
| + * might also be mixed in to non-native classes.
|
| + */
|
| + final Set<ClassElement> classesMixedIntoNativeClasses =
|
| + new Set<ClassElement>();
|
|
|
| /**
|
| * Set of classes whose `operator ==` methods handle `null` themselves.
|
| @@ -762,7 +769,6 @@ class JavaScriptBackend extends Backend {
|
| rti = new RuntimeTypes(compiler),
|
| specializedGetInterceptors =
|
| new Map<String, Collection<ClassElement>>(),
|
| - interceptedClasses = new Set<ClassElement>(),
|
| super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) {
|
| emitter = disableEval
|
| ? new CodeEmitterNoEvalTask(compiler, namer, generateSourceMap)
|
| @@ -783,7 +789,9 @@ class JavaScriptBackend extends Backend {
|
| bool isInterceptorClass(ClassElement element) {
|
| if (element == null) return false;
|
| if (element.isNative()) return true;
|
| - return interceptedClasses.contains(element);
|
| + if (interceptedClasses.contains(element)) return true;
|
| + if (classesMixedIntoNativeClasses.contains(element)) return true;
|
| + return false;
|
| }
|
|
|
| void addInterceptedSelector(Selector selector) {
|
| @@ -949,7 +957,19 @@ class JavaScriptBackend extends Backend {
|
| ClassElement cls, Enqueuer enqueuer) {
|
| if (enqueuer.isResolutionQueue) {
|
| cls.ensureResolved(compiler);
|
| - addInterceptorMembers(cls);
|
| + cls.forEachMember((ClassElement classElement, Element member) {
|
| + // All methods on [Object] are shadowed by [Interceptor].
|
| + if (classElement == compiler.objectClass) return;
|
| + Set<Element> set = interceptedElements.putIfAbsent(
|
| + member.name, () => new Set<Element>());
|
| + set.add(member);
|
| + if (!classElement.isNative()) {
|
| + MixinApplicationElement mixinApplication = classElement;
|
| + assert(member.getEnclosingClass() == mixinApplication.mixin);
|
| + classesMixedIntoNativeClasses.add(mixinApplication.mixin);
|
| + }
|
| + },
|
| + includeSuperMembers: true);
|
| }
|
| }
|
|
|
| @@ -958,22 +978,18 @@ class JavaScriptBackend extends Backend {
|
| TreeElements elements) {
|
| if (enqueuer.isResolutionQueue) {
|
| cls.ensureResolved(compiler);
|
| - addInterceptorMembers(cls);
|
| + cls.forEachMember((ClassElement classElement, Element member) {
|
| + // All methods on [Object] are shadowed by [Interceptor].
|
| + if (classElement == compiler.objectClass) return;
|
| + Set<Element> set = interceptedElements.putIfAbsent(
|
| + member.name, () => new Set<Element>());
|
| + set.add(member);
|
| + },
|
| + includeSuperMembers: true);
|
| }
|
| enqueuer.registerInstantiatedClass(cls, elements);
|
| }
|
|
|
| - void addInterceptorMembers(ClassElement cls) {
|
| - cls.forEachMember((ClassElement classElement, Element member) {
|
| - // All methods on [Object] are shadowed by [Interceptor].
|
| - if (classElement == compiler.objectClass) return;
|
| - Set<Element> set = interceptedElements.putIfAbsent(
|
| - member.name, () => new Set<Element>());
|
| - set.add(member);
|
| - },
|
| - includeSuperMembers: true);
|
| - }
|
| -
|
| void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
|
| String name = namer.getInterceptorName(getInterceptorMethod, classes);
|
| if (classes.contains(jsInterceptorClass)) {
|
|
|