| OLD | NEW | 
|---|
| 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; | 
| 6 | 6 | 
| 7 class InterceptorEmitter extends CodeEmitterHelper { | 7 class InterceptorEmitter extends CodeEmitterHelper { | 
| 8   final Set<String> interceptorInvocationNames = new Set<String>(); | 8   final Set<jsAst.Name> interceptorInvocationNames = | 
|  | 9       new Set<jsAst.Name>(); | 
| 9 | 10 | 
| 10   void recordMangledNameOfMemberMethod(FunctionElement member, String name) { | 11   void recordMangledNameOfMemberMethod(FunctionElement member, | 
|  | 12                                        jsAst.Name name) { | 
| 11     if (backend.isInterceptedMethod(member)) { | 13     if (backend.isInterceptedMethod(member)) { | 
| 12       interceptorInvocationNames.add(name); | 14       interceptorInvocationNames.add(name); | 
| 13     } | 15     } | 
| 14   } | 16   } | 
| 15 | 17 | 
| 16   jsAst.Expression buildGetInterceptorMethod(String key, | 18   jsAst.Expression buildGetInterceptorMethod(jsAst.Name key, | 
| 17                                              Set<ClassElement> classes) { | 19                                              Set<ClassElement> classes) { | 
| 18     InterceptorStubGenerator stubGenerator = | 20     InterceptorStubGenerator stubGenerator = | 
| 19         new InterceptorStubGenerator(compiler, namer, backend); | 21         new InterceptorStubGenerator(compiler, namer, backend); | 
| 20     jsAst.Expression function = | 22     jsAst.Expression function = | 
| 21         stubGenerator.generateGetInterceptorMethod(classes); | 23         stubGenerator.generateGetInterceptorMethod(classes); | 
| 22 | 24 | 
| 23     return function; | 25     return function; | 
| 24   } | 26   } | 
| 25 | 27 | 
| 26   /** | 28   /** | 
| 27    * Emit all versions of the [:getInterceptor:] method. | 29    * Emit all versions of the [:getInterceptor:] method. | 
| 28    */ | 30    */ | 
| 29   jsAst.Statement buildGetInterceptorMethods() { | 31   jsAst.Statement buildGetInterceptorMethods() { | 
| 30     List<jsAst.Statement> parts = <jsAst.Statement>[]; | 32     List<jsAst.Statement> parts = <jsAst.Statement>[]; | 
| 31 | 33 | 
| 32     parts.add(js.comment('getInterceptor methods')); | 34     parts.add(js.comment('getInterceptor methods')); | 
| 33 | 35 | 
| 34     Map<String, Set<ClassElement>> specializedGetInterceptors = | 36     Map<jsAst.Name, Set<ClassElement>> specializedGetInterceptors = | 
| 35         backend.specializedGetInterceptors; | 37         backend.specializedGetInterceptors; | 
| 36     for (String name in specializedGetInterceptors.keys.toList()..sort()) { | 38     List<jsAst.Name> names = specializedGetInterceptors.keys.toList() | 
|  | 39         ..sort(); | 
|  | 40     for (jsAst.Name name in names) { | 
| 37       Set<ClassElement> classes = specializedGetInterceptors[name]; | 41       Set<ClassElement> classes = specializedGetInterceptors[name]; | 
| 38       parts.add( | 42       parts.add( | 
| 39           js.statement('#.# = #', | 43           js.statement('#.# = #', | 
| 40                        [namer.globalObjectFor(backend.interceptorsLibrary), | 44                        [namer.globalObjectFor(backend.interceptorsLibrary), | 
| 41                         name, | 45                         name, | 
| 42                         buildGetInterceptorMethod(name, classes)])); | 46                         buildGetInterceptorMethod(name, classes)])); | 
| 43     } | 47     } | 
| 44 | 48 | 
| 45     return new jsAst.Block(parts); | 49     return new jsAst.Block(parts); | 
| 46   } | 50   } | 
| 47 | 51 | 
| 48   jsAst.Statement buildOneShotInterceptors() { | 52   jsAst.Statement buildOneShotInterceptors() { | 
| 49     List<jsAst.Statement> parts = <jsAst.Statement>[]; | 53     List<jsAst.Statement> parts = <jsAst.Statement>[]; | 
| 50     List<String> names = backend.oneShotInterceptors.keys.toList(); | 54     Iterable<jsAst.Name> names = backend.oneShotInterceptors.keys.toList() | 
| 51     names.sort(); | 55         ..sort(); | 
| 52 | 56 | 
| 53     InterceptorStubGenerator stubGenerator = | 57     InterceptorStubGenerator stubGenerator = | 
| 54         new InterceptorStubGenerator(compiler, namer, backend); | 58         new InterceptorStubGenerator(compiler, namer, backend); | 
| 55     String globalObject = namer.globalObjectFor(backend.interceptorsLibrary); | 59     String globalObject = namer.globalObjectFor(backend.interceptorsLibrary); | 
| 56     for (String name in names) { | 60     for (jsAst.Name name in names) { | 
| 57       jsAst.Expression function = | 61       jsAst.Expression function = | 
| 58           stubGenerator.generateOneShotInterceptor(name); | 62           stubGenerator.generateOneShotInterceptor(name); | 
| 59       parts.add(js.statement('${globalObject}.# = #', [name, function])); | 63       parts.add(js.statement('${globalObject}.# = #', [name, function])); | 
| 60     } | 64     } | 
| 61 | 65 | 
| 62     return new jsAst.Block(parts); | 66     return new jsAst.Block(parts); | 
| 63   } | 67   } | 
| 64 | 68 | 
| 65   /** | 69   /** | 
| 66    * If [JSInvocationMirror._invokeOn] has been compiled, emit all the | 70    * If [JSInvocationMirror._invokeOn] has been compiled, emit all the | 
| 67    * possible selector names that are intercepted into the | 71    * possible selector names that are intercepted into the | 
| 68    * [interceptedNames] embedded global. The implementation of | 72    * [interceptedNames] embedded global. The implementation of | 
| 69    * [_invokeOn] will use it to determine whether it should call the | 73    * [_invokeOn] will use it to determine whether it should call the | 
| 70    * method with an extra parameter. | 74    * method with an extra parameter. | 
| 71    */ | 75    */ | 
| 72   jsAst.ObjectInitializer generateInterceptedNamesSet() { | 76   jsAst.ObjectInitializer generateInterceptedNamesSet() { | 
| 73     // We could also generate the list of intercepted names at | 77     // We could also generate the list of intercepted names at | 
| 74     // runtime, by running through the subclasses of Interceptor | 78     // runtime, by running through the subclasses of Interceptor | 
| 75     // (which can easily be identified). | 79     // (which can easily be identified). | 
| 76     if (!compiler.enabledInvokeOn) return null; | 80     if (!compiler.enabledInvokeOn) return null; | 
| 77 | 81 | 
| 78     List<String> invocationNames = interceptorInvocationNames.toList()..sort(); | 82     Iterable<jsAst.Name> invocationNames = interceptorInvocationNames.toList() | 
| 79     List<jsAst.Property> properties = | 83         ..sort();; | 
| 80         new List<jsAst.Property>(invocationNames.length); | 84     List<jsAst.Property> properties = invocationNames.map((jsAst.Name name) { | 
| 81     for (int i = 0; i < invocationNames.length; i++) { | 85       return new jsAst.Property(js.quoteName(name), js.number(1)); | 
| 82       String name = invocationNames[i]; | 86     }).toList(); | 
| 83       properties[i] = new jsAst.Property(js.string(name), js.number(1)); |  | 
| 84     } |  | 
| 85     return new jsAst.ObjectInitializer(properties, isOneLiner: true); | 87     return new jsAst.ObjectInitializer(properties, isOneLiner: true); | 
| 86   } | 88   } | 
| 87 | 89 | 
| 88   /** | 90   /** | 
| 89    * Emit initializer for `typeToInterceptorMap` data structure used by | 91    * Emit initializer for `typeToInterceptorMap` data structure used by | 
| 90    * `findInterceptorForType`.  See declaration of `typeToInterceptor` in | 92    * `findInterceptorForType`.  See declaration of `typeToInterceptor` in | 
| 91    * `interceptors.dart`. | 93    * `interceptors.dart`. | 
| 92    */ | 94    */ | 
| 93   jsAst.Statement buildTypeToInterceptorMap(Program program) { | 95   jsAst.Statement buildTypeToInterceptorMap(Program program) { | 
| 94     jsAst.Expression array = program.typeToInterceptorMap; | 96     jsAst.Expression array = program.typeToInterceptorMap; | 
| 95     if (array == null) return js.comment("Empty type-to-interceptor map."); | 97     if (array == null) return js.comment("Empty type-to-interceptor map."); | 
| 96 | 98 | 
| 97     jsAst.Expression typeToInterceptorMap = emitter | 99     jsAst.Expression typeToInterceptorMap = emitter | 
| 98         .generateEmbeddedGlobalAccess(embeddedNames.TYPE_TO_INTERCEPTOR_MAP); | 100         .generateEmbeddedGlobalAccess(embeddedNames.TYPE_TO_INTERCEPTOR_MAP); | 
| 99     return js.statement('# = #', [typeToInterceptorMap, array]); | 101     return js.statement('# = #', [typeToInterceptorMap, array]); | 
| 100   } | 102   } | 
| 101 } | 103 } | 
| OLD | NEW | 
|---|