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 library dart2js.js_emitter.class_stub_generator; | 5 library dart2js.js_emitter.class_stub_generator; |
6 | 6 |
7 import '../common/names.dart' show Identifiers; | 7 import '../common/names.dart' show Identifiers; |
8 import '../common_elements.dart' show CommonElements; | 8 import '../common_elements.dart' show CommonElements; |
9 import '../elements/entities.dart'; | 9 import '../elements/entities.dart'; |
10 import '../js/js.dart' as jsAst; | 10 import '../js/js.dart' as jsAst; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 List<jsAst.Expression> argNames = selector.callStructure | 182 List<jsAst.Expression> argNames = selector.callStructure |
183 .getOrderedNamedArguments() | 183 .getOrderedNamedArguments() |
184 .map((String name) => js.string(name)) | 184 .map((String name) => js.string(name)) |
185 .toList(); | 185 .toList(); |
186 | 186 |
187 jsAst.Name methodName = _namer.asName(selector.invocationMirrorMemberName); | 187 jsAst.Name methodName = _namer.asName(selector.invocationMirrorMemberName); |
188 jsAst.Name internalName = _namer.invocationMirrorInternalName(selector); | 188 jsAst.Name internalName = _namer.invocationMirrorInternalName(selector); |
189 | 189 |
190 assert(_interceptorData.isInterceptedName(Identifiers.noSuchMethod_)); | 190 assert(_interceptorData.isInterceptedName(Identifiers.noSuchMethod_)); |
191 bool isIntercepted = _interceptorData.isInterceptedName(selector.name); | 191 bool isIntercepted = _interceptorData.isInterceptedName(selector.name); |
192 jsAst.Expression expression = js( | 192 jsAst.Expression expression = js('''this.#noSuchMethodName(#receiver, |
193 '''this.#noSuchMethodName(#receiver, | |
194 #createInvocationMirror(#methodName, | 193 #createInvocationMirror(#methodName, |
195 #internalName, | 194 #internalName, |
196 #type, | 195 #type, |
197 #arguments, | 196 #arguments, |
198 #namedArguments))''', | 197 #namedArguments))''', { |
199 { | 198 'receiver': isIntercepted ? r'$receiver' : 'this', |
200 'receiver': isIntercepted ? r'$receiver' : 'this', | 199 'noSuchMethodName': _namer.noSuchMethodName, |
201 'noSuchMethodName': _namer.noSuchMethodName, | 200 'createInvocationMirror': |
202 'createInvocationMirror': _emitter | 201 _emitter.staticFunctionAccess(_commonElements.createInvocationMirror), |
203 .staticFunctionAccess(_commonElements.createInvocationMirror), | 202 'methodName': |
204 'methodName': | 203 js.quoteName(enableMinification ? internalName : methodName), |
205 js.quoteName(enableMinification ? internalName : methodName), | 204 'internalName': js.quoteName(internalName), |
206 'internalName': js.quoteName(internalName), | 205 'type': js.number(type), |
207 'type': js.number(type), | 206 'arguments': new jsAst.ArrayInitializer(parameterNames.map(js).toList()), |
208 'arguments': | 207 'namedArguments': new jsAst.ArrayInitializer(argNames) |
209 new jsAst.ArrayInitializer(parameterNames.map(js).toList()), | 208 }); |
210 'namedArguments': new jsAst.ArrayInitializer(argNames) | |
211 }); | |
212 | 209 |
213 jsAst.Expression function; | 210 jsAst.Expression function; |
214 if (isIntercepted) { | 211 if (isIntercepted) { |
215 function = js( | 212 function = js( |
216 r'function($receiver, #) { return # }', [parameterNames, expression]); | 213 r'function($receiver, #) { return # }', [parameterNames, expression]); |
217 } else { | 214 } else { |
218 function = js(r'function(#) { return # }', [parameterNames, expression]); | 215 function = js(r'function(#) { return # }', [parameterNames, expression]); |
219 } | 216 } |
220 return new StubMethod(name, function); | 217 return new StubMethod(name, function); |
221 } | 218 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 js(r'''function() { throw "Helper 'closureFromTearOff' missing." }'''); | 250 js(r'''function() { throw "Helper 'closureFromTearOff' missing." }'''); |
254 tearOffGlobalObjectString = js.string('MissingHelperFunction'); | 251 tearOffGlobalObjectString = js.string('MissingHelperFunction'); |
255 tearOffGlobalObject = js( | 252 tearOffGlobalObject = js( |
256 r'''(function() { throw "Helper 'closureFromTearOff' missing." })()'''); | 253 r'''(function() { throw "Helper 'closureFromTearOff' missing." })()'''); |
257 } | 254 } |
258 | 255 |
259 jsAst.Statement tearOffGetter; | 256 jsAst.Statement tearOffGetter; |
260 if (!options.useContentSecurityPolicy) { | 257 if (!options.useContentSecurityPolicy) { |
261 jsAst.Expression tearOffAccessText = | 258 jsAst.Expression tearOffAccessText = |
262 new jsAst.UnparsedNode(tearOffAccessExpression, options, false); | 259 new jsAst.UnparsedNode(tearOffAccessExpression, options, false); |
263 tearOffGetter = js.statement( | 260 tearOffGetter = js.statement(''' |
264 ''' | |
265 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { | 261 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
266 return isIntercepted | 262 return isIntercepted |
267 ? new Function("funcs", "reflectionInfo", "name", | 263 ? new Function("funcs", "reflectionInfo", "name", |
268 #tearOffGlobalObjectString, "c", | 264 #tearOffGlobalObjectString, "c", |
269 "return function tearOff_" + name + (functionCounter++) + "(x) {" + | 265 "return function tearOff_" + name + (functionCounter++) + "(x) {" + |
270 "if (c === null) c = " + #tearOffAccessText + "(" + | 266 "if (c === null) c = " + #tearOffAccessText + "(" + |
271 "this, funcs, reflectionInfo, false, [x], name);" + | 267 "this, funcs, reflectionInfo, false, [x], name);" + |
272 "return new c(this, funcs[0], x, name);" + | 268 "return new c(this, funcs[0], x, name);" + |
273 "}")(funcs, reflectionInfo, name, #tearOffGlobalObject, null) | 269 "}")(funcs, reflectionInfo, name, #tearOffGlobalObject, null) |
274 : new Function("funcs", "reflectionInfo", "name", | 270 : new Function("funcs", "reflectionInfo", "name", |
275 #tearOffGlobalObjectString, "c", | 271 #tearOffGlobalObjectString, "c", |
276 "return function tearOff_" + name + (functionCounter++)+ "() {" + | 272 "return function tearOff_" + name + (functionCounter++)+ "() {" + |
277 "if (c === null) c = " + #tearOffAccessText + "(" + | 273 "if (c === null) c = " + #tearOffAccessText + "(" + |
278 "this, funcs, reflectionInfo, false, [], name);" + | 274 "this, funcs, reflectionInfo, false, [], name);" + |
279 "return new c(this, funcs[0], null, name);" + | 275 "return new c(this, funcs[0], null, name);" + |
280 "}")(funcs, reflectionInfo, name, #tearOffGlobalObject, null); | 276 "}")(funcs, reflectionInfo, name, #tearOffGlobalObject, null); |
281 }''', | 277 }''', { |
282 { | 278 'tearOffAccessText': tearOffAccessText, |
283 'tearOffAccessText': tearOffAccessText, | 279 'tearOffGlobalObject': tearOffGlobalObject, |
284 'tearOffGlobalObject': tearOffGlobalObject, | 280 'tearOffGlobalObjectString': tearOffGlobalObjectString |
285 'tearOffGlobalObjectString': tearOffGlobalObjectString | 281 }); |
286 }); | |
287 } else { | 282 } else { |
288 tearOffGetter = js.statement( | 283 tearOffGetter = js.statement(''' |
289 ''' | |
290 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { | 284 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) { |
291 var cache = null; | 285 var cache = null; |
292 return isIntercepted | 286 return isIntercepted |
293 ? function(x) { | 287 ? function(x) { |
294 if (cache === null) cache = #( | 288 if (cache === null) cache = #( |
295 this, funcs, reflectionInfo, false, [x], name); | 289 this, funcs, reflectionInfo, false, [x], name); |
296 return new cache(this, funcs[0], x, name); | 290 return new cache(this, funcs[0], x, name); |
297 } | 291 } |
298 : function() { | 292 : function() { |
299 if (cache === null) cache = #( | 293 if (cache === null) cache = #( |
300 this, funcs, reflectionInfo, false, [], name); | 294 this, funcs, reflectionInfo, false, [], name); |
301 return new cache(this, funcs[0], null, name); | 295 return new cache(this, funcs[0], null, name); |
302 }; | 296 }; |
303 }''', | 297 }''', [tearOffAccessExpression, tearOffAccessExpression]); |
304 [tearOffAccessExpression, tearOffAccessExpression]); | |
305 } | 298 } |
306 | 299 |
307 jsAst.Statement tearOff = js.statement( | 300 jsAst.Statement tearOff = js.statement(''' |
308 ''' | |
309 function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) { | 301 function tearOff(funcs, reflectionInfo, isStatic, name, isIntercepted) { |
310 var cache; | 302 var cache; |
311 return isStatic | 303 return isStatic |
312 ? function() { | 304 ? function() { |
313 if (cache === void 0) cache = #tearOff( | 305 if (cache === void 0) cache = #tearOff( |
314 this, funcs, reflectionInfo, true, [], name).prototype; | 306 this, funcs, reflectionInfo, true, [], name).prototype; |
315 return cache; | 307 return cache; |
316 } | 308 } |
317 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); | 309 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); |
318 }''', | 310 }''', {'tearOff': tearOffAccessExpression}); |
319 {'tearOff': tearOffAccessExpression}); | |
320 | 311 |
321 return <jsAst.Statement>[tearOffGetter, tearOff]; | 312 return <jsAst.Statement>[tearOffGetter, tearOff]; |
322 } | 313 } |
OLD | NEW |