| 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 |