| 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 '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 fields, | 48 fields, |
| 49 typeParameters, | 49 typeParameters, |
| 50 fields.map((name) => js('this.# = #', [name, name])), | 50 fields.map((name) => js('this.# = #', [name, name])), |
| 51 typeInits, | 51 typeInits, |
| 52 namer.deferredAction | 52 namer.deferredAction |
| 53 ]); | 53 ]); |
| 54 } | 54 } |
| 55 | 55 |
| 56 jsAst.Expression generateGetter(MemberEntity member, jsAst.Name fieldName) { | 56 jsAst.Expression generateGetter(MemberEntity member, jsAst.Name fieldName) { |
| 57 ClassEntity cls = member.enclosingClass; | 57 ClassEntity cls = member.enclosingClass; |
| 58 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 58 String receiver = |
| 59 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; | 59 backend.interceptorData.isInterceptorClass(cls) ? 'receiver' : 'this'; |
| 60 List<String> args = |
| 61 backend.interceptorData.isInterceptedMethod(member) ? ['receiver'] : []; |
| 60 return js('function(#) { return #.# }', [args, receiver, fieldName]); | 62 return js('function(#) { return #.# }', [args, receiver, fieldName]); |
| 61 } | 63 } |
| 62 | 64 |
| 63 jsAst.Expression generateSetter(MemberEntity member, jsAst.Name fieldName) { | 65 jsAst.Expression generateSetter(MemberEntity member, jsAst.Name fieldName) { |
| 64 ClassEntity cls = member.enclosingClass; | 66 ClassEntity cls = member.enclosingClass; |
| 65 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 67 String receiver = |
| 66 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; | 68 backend.interceptorData.isInterceptorClass(cls) ? 'receiver' : 'this'; |
| 69 List<String> args = |
| 70 backend.interceptorData.isInterceptedMethod(member) ? ['receiver'] : []; |
| 67 // TODO(floitsch): remove 'return'? | 71 // TODO(floitsch): remove 'return'? |
| 68 return js( | 72 return js( |
| 69 'function(#, v) { return #.# = v; }', [args, receiver, fieldName]); | 73 'function(#, v) { return #.# = v; }', [args, receiver, fieldName]); |
| 70 } | 74 } |
| 71 | 75 |
| 72 /** | 76 /** |
| 73 * Documentation wanted -- johnniwinther | 77 * Documentation wanted -- johnniwinther |
| 74 * | 78 * |
| 75 * Invariant: [member] must be a declaration element. | 79 * Invariant: [member] must be a declaration element. |
| 76 */ | 80 */ |
| 77 Map<jsAst.Name, jsAst.Expression> generateCallStubsForGetter( | 81 Map<jsAst.Name, jsAst.Expression> generateCallStubsForGetter( |
| 78 MemberEntity member, Map<Selector, SelectorConstraints> selectors) { | 82 MemberEntity member, Map<Selector, SelectorConstraints> selectors) { |
| 79 // If the method is intercepted, the stub gets the | 83 // If the method is intercepted, the stub gets the |
| 80 // receiver explicitely and we need to pass it to the getter call. | 84 // receiver explicitely and we need to pass it to the getter call. |
| 81 bool isInterceptedMethod = backend.isInterceptedMethod(member); | 85 bool isInterceptedMethod = |
| 82 bool isInterceptorClass = backend.isInterceptorClass(member.enclosingClass); | 86 backend.interceptorData.isInterceptedMethod(member); |
| 87 bool isInterceptorClass = |
| 88 backend.interceptorData.isInterceptorClass(member.enclosingClass); |
| 83 | 89 |
| 84 const String receiverArgumentName = r'$receiver'; | 90 const String receiverArgumentName = r'$receiver'; |
| 85 | 91 |
| 86 jsAst.Expression buildGetter() { | 92 jsAst.Expression buildGetter() { |
| 87 jsAst.Expression receiver = | 93 jsAst.Expression receiver = |
| 88 js(isInterceptorClass ? receiverArgumentName : 'this'); | 94 js(isInterceptorClass ? receiverArgumentName : 'this'); |
| 89 if (member.isGetter) { | 95 if (member.isGetter) { |
| 90 jsAst.Name getterName = namer.getterForElement(member); | 96 jsAst.Name getterName = namer.getterForElement(member); |
| 91 if (isInterceptedMethod) { | 97 if (isInterceptedMethod) { |
| 92 return js('this.#(#)', [getterName, receiver]); | 98 return js('this.#(#)', [getterName, receiver]); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 new List.generate(selector.argumentCount, (i) => '\$$i'); | 175 new List.generate(selector.argumentCount, (i) => '\$$i'); |
| 170 | 176 |
| 171 List<jsAst.Expression> argNames = selector.callStructure | 177 List<jsAst.Expression> argNames = selector.callStructure |
| 172 .getOrderedNamedArguments() | 178 .getOrderedNamedArguments() |
| 173 .map((String name) => js.string(name)) | 179 .map((String name) => js.string(name)) |
| 174 .toList(); | 180 .toList(); |
| 175 | 181 |
| 176 jsAst.Name methodName = namer.asName(selector.invocationMirrorMemberName); | 182 jsAst.Name methodName = namer.asName(selector.invocationMirrorMemberName); |
| 177 jsAst.Name internalName = namer.invocationMirrorInternalName(selector); | 183 jsAst.Name internalName = namer.invocationMirrorInternalName(selector); |
| 178 | 184 |
| 179 assert(backend.isInterceptedName(Identifiers.noSuchMethod_)); | 185 assert( |
| 180 bool isIntercepted = backend.isInterceptedName(selector.name); | 186 backend.interceptorData.isInterceptedName(Identifiers.noSuchMethod_)); |
| 187 bool isIntercepted = |
| 188 backend.interceptorData.isInterceptedName(selector.name); |
| 181 jsAst.Expression expression = js( | 189 jsAst.Expression expression = js( |
| 182 '''this.#noSuchMethodName(#receiver, | 190 '''this.#noSuchMethodName(#receiver, |
| 183 #createInvocationMirror(#methodName, | 191 #createInvocationMirror(#methodName, |
| 184 #internalName, | 192 #internalName, |
| 185 #type, | 193 #type, |
| 186 #arguments, | 194 #arguments, |
| 187 #namedArguments))''', | 195 #namedArguments))''', |
| 188 { | 196 { |
| 189 'receiver': isIntercepted ? r'$receiver' : 'this', | 197 'receiver': isIntercepted ? r'$receiver' : 'this', |
| 190 'noSuchMethodName': namer.noSuchMethodName, | 198 'noSuchMethodName': namer.noSuchMethodName, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 if (cache === void 0) cache = #tearOff( | 313 if (cache === void 0) cache = #tearOff( |
| 306 this, funcs, reflectionInfo, true, [], name).prototype; | 314 this, funcs, reflectionInfo, true, [], name).prototype; |
| 307 return cache; | 315 return cache; |
| 308 } | 316 } |
| 309 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); | 317 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); |
| 310 }''', | 318 }''', |
| 311 {'tearOff': tearOffAccessExpression}); | 319 {'tearOff': tearOffAccessExpression}); |
| 312 | 320 |
| 313 return <jsAst.Statement>[tearOffGetter, tearOff]; | 321 return <jsAst.Statement>[tearOffGetter, tearOff]; |
| 314 } | 322 } |
| OLD | NEW |