| 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 void computeSelectorsForNsmHandlers(Map<String, Selector> jsNames) { |
| 116 |
| 117 // Do not generate no such method handlers if there is no class. |
| 118 if (compiler.codegenWorld.directlyInstantiatedClasses.isEmpty) return; |
| 119 |
| 120 void addNoSuchMethodHandlers(String ignore, Set<Selector> selectors) { |
| 121 // Cache the object class and type. |
| 122 ClassElement objectClass = compiler.objectClass; |
| 123 DartType objectType = objectClass.rawType; |
| 124 |
| 125 for (Selector selector in selectors) { |
| 126 TypeMask mask = selector.mask; |
| 127 if (mask == null) { |
| 128 mask = new TypeMask.subclass(compiler.objectClass, |
| 129 compiler.world); |
| 130 } |
| 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 } |
| 144 |
| 145 jsAst.Expression generateStubForNoSuchMethod(Selector selector) { |
| 146 // Values match JSInvocationMirror in js-helper library. |
| 147 int type = selector.invocationMirrorKind; |
| 148 List<String> parameterNames = |
| 149 new List.generate(selector.argumentCount, (i) => '\$$i'); |
| 150 |
| 151 List<jsAst.Expression> argNames = |
| 152 selector.getOrderedNamedArguments().map((String name) => |
| 153 js.string(name)).toList(); |
| 154 |
| 155 String methodName = selector.invocationMirrorMemberName; |
| 156 String internalName = namer.invocationMirrorInternalName(selector); |
| 157 |
| 158 assert(backend.isInterceptedName(Compiler.NO_SUCH_METHOD)); |
| 159 jsAst.Expression expression = |
| 160 js('''this.#noSuchMethodName(this, |
| 161 #createInvocationMirror(#methodName, |
| 162 #internalName, |
| 163 #type, |
| 164 #arguments, |
| 165 #namedArguments))''', |
| 166 {'noSuchMethodName': namer.noSuchMethodName, |
| 167 'createInvocationMirror': |
| 168 backend.emitter.staticFunctionAccess( |
| 169 backend.getCreateInvocationMirror()), |
| 170 'methodName': |
| 171 js.string(compiler.enableMinification |
| 172 ? internalName : methodName), |
| 173 'internalName': js.string(internalName), |
| 174 'type': js.number(type), |
| 175 'arguments': |
| 176 new jsAst.ArrayInitializer(parameterNames.map(js).toList()), |
| 177 'namedArguments': new jsAst.ArrayInitializer(argNames)}); |
| 178 |
| 179 if (backend.isInterceptedName(selector.name)) { |
| 180 return js(r'function($receiver, #) { return # }', |
| 181 [parameterNames, expression]); |
| 182 } else { |
| 183 return js(r'function(#) { return # }', [parameterNames, expression]); |
| 184 } |
| 185 } |
| 114 } | 186 } |
| OLD | NEW |