| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 ClassStubGenerator { | 7 class ClassStubGenerator { |
| 8 final Namer namer; | 8 final Namer namer; |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 final JavaScriptBackend backend; | 10 final JavaScriptBackend backend; |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 jsAst.Fun function = js( | 104 jsAst.Fun function = js( |
| 105 'function(#) { return #.#(#); }', | 105 'function(#) { return #.#(#); }', |
| 106 [ parameters, buildGetter(), closureCallName, arguments]); | 106 [ parameters, buildGetter(), closureCallName, arguments]); |
| 107 | 107 |
| 108 generatedStubs[invocationName] = function; | 108 generatedStubs[invocationName] = function; |
| 109 } | 109 } |
| 110 } | 110 } |
| 111 | 111 |
| 112 return generatedStubs; | 112 return generatedStubs; |
| 113 } | 113 } |
| 114 |
| 115 Map<String, Selector> computeSelectorsForNsmHandlers() { |
| 116 |
| 117 Map<String, Selector> jsNames = <String, Selector>{}; |
| 118 |
| 119 // Do not generate no such method handlers if there is no class. |
| 120 if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) { |
| 121 return jsNames; |
| 122 } |
| 123 |
| 124 void addNoSuchMethodHandlers(String ignore, Set<Selector> selectors) { |
| 125 TypeMask objectSubclassTypeMask = |
| 126 new TypeMask.subclass(compiler.objectClass, compiler.world); |
| 127 |
| 128 for (Selector selector in selectors) { |
| 129 TypeMask mask = selector.mask; |
| 130 if (mask == null) mask = objectSubclassTypeMask; |
| 131 |
| 132 if (!mask.needsNoSuchMethodHandling(selector, compiler.world)) { |
| 133 continue; |
| 134 } |
| 135 String jsName = namer.invocationMirrorInternalName(selector); |
| 136 jsNames[jsName] = selector; |
| 137 } |
| 138 } |
| 139 |
| 140 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); |
| 141 compiler.codegenWorld.invokedGetters.forEach(addNoSuchMethodHandlers); |
| 142 compiler.codegenWorld.invokedSetters.forEach(addNoSuchMethodHandlers); |
| 143 return jsNames; |
| 144 } |
| 145 |
| 146 jsAst.Expression generateStubForNoSuchMethod(Selector selector) { |
| 147 // Values match JSInvocationMirror in js-helper library. |
| 148 int type = selector.invocationMirrorKind; |
| 149 List<String> parameterNames = |
| 150 new List.generate(selector.argumentCount, (i) => '\$$i'); |
| 151 |
| 152 List<jsAst.Expression> argNames = |
| 153 selector.getOrderedNamedArguments().map((String name) => |
| 154 js.string(name)).toList(); |
| 155 |
| 156 String methodName = selector.invocationMirrorMemberName; |
| 157 String internalName = namer.invocationMirrorInternalName(selector); |
| 158 |
| 159 assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD)); |
| 160 jsAst.Expression expression = |
| 161 js('''this.#noSuchMethodName(this, |
| 162 #createInvocationMirror(#methodName, |
| 163 #internalName, |
| 164 #type, |
| 165 #arguments, |
| 166 #namedArguments))''', |
| 167 {'noSuchMethodName': namer.noSuchMethodName, |
| 168 'createInvocationMirror': |
| 169 backend.emitter.staticFunctionAccess( |
| 170 backend.getCreateInvocationMirror()), |
| 171 'methodName': |
| 172 js.string(compiler.enableMinification |
| 173 ? internalName : methodName), |
| 174 'internalName': js.string(internalName), |
| 175 'type': js.number(type), |
| 176 'arguments': |
| 177 new jsAst.ArrayInitializer(parameterNames.map(js).toList()), |
| 178 'namedArguments': new jsAst.ArrayInitializer(argNames)}); |
| 179 |
| 180 if (backend.isInterceptedName(selector.name)) { |
| 181 return js(r'function($receiver, #) { return # }', |
| 182 [parameterNames, expression]); |
| 183 } else { |
| 184 return js(r'function(#) { return # }', [parameterNames, expression]); |
| 185 } |
| 186 } |
| 114 } | 187 } |
| OLD | NEW |