Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/js_backend/backend.dart |
| =================================================================== |
| --- sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (revision 15192) |
| +++ sdk/lib/_internal/compiler/implementation/js_backend/backend.dart (working copy) |
| @@ -695,7 +695,7 @@ |
| * name to the list of members that have that name. This map is used |
| * by the codegen to know whether a send must be intercepted or not. |
| */ |
| - final Map<SourceString, List<Element>> interceptedElements; |
| + final Map<SourceString, Set<Element>> interceptedElements; |
| List<CompilerTask> get tasks { |
| return <CompilerTask>[builder, optimizer, generator, emitter]; |
| @@ -709,7 +709,7 @@ |
| invalidateAfterCodegen = new List<Element>(), |
| interceptors = new Interceptors(compiler), |
| usedInterceptors = new Set<Selector>(), |
| - interceptedElements = new Map<SourceString, List<Element>>(), |
| + interceptedElements = new Map<SourceString, Set<Element>>(), |
| rti = new RuntimeTypeInformation(compiler), |
| super(compiler, JAVA_SCRIPT_CONSTANT_SYSTEM) { |
| emitter = disableEval |
| @@ -744,13 +744,22 @@ |
| usedInterceptors.add(selector); |
| } |
| - bool shouldInterceptSelector(Selector selector) { |
| - List<Element> intercepted = interceptedElements[selector.name]; |
| - if (intercepted == null) return false; |
| + /** |
| + * Returns a set of interceptor classes that contain a member whose |
| + * signature matches the given [selector]. Returns [:null:] if there |
| + * is no class. |
| + */ |
| + Set<ClassElement> getInterceptedClassesOn(Selector selector) { |
|
ahe
2012/11/22 13:26:11
How about computing the reverse mapping? This see
ngeoffray
2012/11/22 13:37:59
As discussed, we already have the reverse mapping,
|
| + Set<Element> intercepted = interceptedElements[selector.name]; |
| + if (intercepted == null) return null; |
| + Set<ClassElement> result = new Set<ClassElement>(); |
| for (Element element in intercepted) { |
| - if (selector.applies(element, compiler)) return true; |
| + if (selector.applies(element, compiler)) { |
| + result.add(element.getEnclosingClass()); |
| + } |
| } |
| - return false; |
| + if (result.isEmpty) return null; |
| + return result; |
| } |
| void initializeInterceptorElements() { |
| @@ -787,12 +796,11 @@ |
| void addInterceptors(ClassElement cls) { |
| cls.ensureResolved(compiler); |
| cls.forEachMember((ClassElement classElement, Element member) { |
| - // TODO(ngeoffray): Support interceptors on Object methods. |
| - if (classElement == compiler.objectClass) return; |
| - List<Element> list = interceptedElements.putIfAbsent( |
| - member.name, () => new List<Element>()); |
| - list.add(member); |
| - }, includeSuperMembers: true); |
| + Set<Element> set = interceptedElements.putIfAbsent( |
| + member.name, () => new Set<Element>()); |
| + set.add(member); |
| + }, |
| + includeSuperMembers: true); |
| } |
| void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { |
| @@ -812,6 +820,7 @@ |
| addInterceptors(jsFunctionClass); |
| enqueuer.registerInstantiatedClass(jsFunctionClass); |
| } |
| + enqueuer.addToWorkList(getInterceptorMethod); |
| } |
| if (cls == compiler.stringClass) { |
| result = jsStringClass; |
| @@ -840,10 +849,6 @@ |
| return new JavaScriptItemCompilationContext(); |
| } |
| - Element getInterceptor(Selector selector) { |
| - return interceptors.getStaticInterceptor(selector); |
| - } |
| - |
| void enqueueHelpers(Enqueuer world) { |
| enqueueAllTopLevelFunctions(compiler.jsHelperLibrary, world); |