Chromium Code Reviews| 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.dart'; | |
| 8 import '../common/names.dart' show Identifiers; | 7 import '../common/names.dart' show Identifiers; |
| 9 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 10 import '../elements/elements.dart' | 9 import '../elements/entities.dart'; |
| 11 show | |
| 12 ClassElement, | |
| 13 Element; | |
| 14 import '../js/js.dart' as jsAst; | 10 import '../js/js.dart' as jsAst; |
| 15 import '../js/js.dart' show js; | 11 import '../js/js.dart' show js; |
| 16 import '../js_backend/js_backend.dart' | 12 import '../js_backend/js_backend.dart' show JavaScriptBackend, Namer; |
|
Siggi Cherem (dart-lang)
2017/01/19 16:44:42
I see that you are fixing format here after the ot
| |
| 17 show | |
| 18 JavaScriptBackend, | |
| 19 Namer; | |
| 20 import '../universe/selector.dart' show Selector; | 13 import '../universe/selector.dart' show Selector; |
| 21 import '../universe/world_builder.dart' | 14 import '../universe/world_builder.dart' |
| 22 show CodegenWorldBuilder, SelectorConstraints; | 15 show CodegenWorldBuilder, SelectorConstraints; |
| 23 import '../world.dart' show ClosedWorld; | 16 import '../world.dart' show ClosedWorld; |
| 24 | 17 |
| 25 import 'model.dart'; | 18 import 'model.dart'; |
| 26 | 19 |
| 27 class ClassStubGenerator { | 20 class ClassStubGenerator { |
| 28 final Namer namer; | 21 final Namer namer; |
| 29 final JavaScriptBackend backend; | 22 final JavaScriptBackend backend; |
| 30 final CodegenWorldBuilder worldBuilder; | 23 final CodegenWorldBuilder worldBuilder; |
| 31 final ClosedWorld closedWorld; | 24 final ClosedWorld closedWorld; |
| 32 final bool enableMinification; | 25 final bool enableMinification; |
| 33 | 26 |
| 34 ClassStubGenerator( | 27 ClassStubGenerator( |
| 35 this.namer, this.backend, this.worldBuilder, this.closedWorld, | 28 this.namer, this.backend, this.worldBuilder, this.closedWorld, |
| 36 {this.enableMinification}); | 29 {this.enableMinification}); |
| 37 | 30 |
| 38 jsAst.Expression generateClassConstructor(ClassElement classElement, | 31 jsAst.Expression generateClassConstructor( |
| 39 Iterable<jsAst.Name> fields, bool hasRtiField) { | 32 ClassEntity classElement, Iterable<jsAst.Name> fields, bool hasRtiField) { |
| 40 // TODO(sra): Implement placeholders in VariableDeclaration position: | 33 // TODO(sra): Implement placeholders in VariableDeclaration position: |
| 41 // | 34 // |
| 42 // String constructorName = namer.getNameOfClass(classElement); | 35 // String constructorName = namer.getNameOfClass(classElement); |
| 43 // return js.statement('function #(#) { #; }', | 36 // return js.statement('function #(#) { #; }', |
| 44 // [ constructorName, fields, | 37 // [ constructorName, fields, |
| 45 // fields.map( | 38 // fields.map( |
| 46 // (name) => js('this.# = #', [name, name]))])); | 39 // (name) => js('this.# = #', [name, name]))])); |
| 47 var typeParameters = const <jsAst.Parameter>[]; | 40 var typeParameters = const <jsAst.Parameter>[]; |
| 48 var typeInits = const <jsAst.Expression>[]; | 41 var typeInits = const <jsAst.Expression>[]; |
| 49 if (hasRtiField) { | 42 if (hasRtiField) { |
| 50 String parameterName = r'$ti'; | 43 String parameterName = r'$ti'; |
| 51 typeParameters = parameterName; | 44 typeParameters = parameterName; |
| 52 typeInits = js('this.# = #', [namer.rtiFieldName, parameterName]); | 45 typeInits = js('this.# = #', [namer.rtiFieldName, parameterName]); |
| 53 } | 46 } |
| 54 return js('function(#, #) { #; #; this.#();}', [ | 47 return js('function(#, #) { #; #; this.#();}', [ |
| 55 fields, | 48 fields, |
| 56 typeParameters, | 49 typeParameters, |
| 57 fields.map((name) => js('this.# = #', [name, name])), | 50 fields.map((name) => js('this.# = #', [name, name])), |
| 58 typeInits, | 51 typeInits, |
| 59 namer.deferredAction | 52 namer.deferredAction |
| 60 ]); | 53 ]); |
| 61 } | 54 } |
| 62 | 55 |
| 63 jsAst.Expression generateGetter(Element member, jsAst.Name fieldName) { | 56 jsAst.Expression generateGetter(MemberEntity member, jsAst.Name fieldName) { |
| 64 ClassElement cls = member.enclosingClass; | 57 ClassEntity cls = member.enclosingClass; |
| 65 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 58 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; |
| 66 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; | 59 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; |
| 67 return js('function(#) { return #.# }', [args, receiver, fieldName]); | 60 return js('function(#) { return #.# }', [args, receiver, fieldName]); |
| 68 } | 61 } |
| 69 | 62 |
| 70 jsAst.Expression generateSetter(Element member, jsAst.Name fieldName) { | 63 jsAst.Expression generateSetter(MemberEntity member, jsAst.Name fieldName) { |
| 71 ClassElement cls = member.enclosingClass; | 64 ClassEntity cls = member.enclosingClass; |
| 72 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; | 65 String receiver = backend.isInterceptorClass(cls) ? 'receiver' : 'this'; |
| 73 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; | 66 List<String> args = backend.isInterceptedMethod(member) ? ['receiver'] : []; |
| 74 // TODO(floitsch): remove 'return'? | 67 // TODO(floitsch): remove 'return'? |
| 75 return js( | 68 return js( |
| 76 'function(#, v) { return #.# = v; }', [args, receiver, fieldName]); | 69 'function(#, v) { return #.# = v; }', [args, receiver, fieldName]); |
| 77 } | 70 } |
| 78 | 71 |
| 79 /** | 72 /** |
| 80 * Documentation wanted -- johnniwinther | 73 * Documentation wanted -- johnniwinther |
| 81 * | 74 * |
| 82 * Invariant: [member] must be a declaration element. | 75 * Invariant: [member] must be a declaration element. |
| 83 */ | 76 */ |
| 84 Map<jsAst.Name, jsAst.Expression> generateCallStubsForGetter( | 77 Map<jsAst.Name, jsAst.Expression> generateCallStubsForGetter( |
| 85 Element member, Map<Selector, SelectorConstraints> selectors) { | 78 MemberEntity member, Map<Selector, SelectorConstraints> selectors) { |
| 86 assert(invariant(member, member.isDeclaration)); | |
| 87 | |
| 88 // If the method is intercepted, the stub gets the | 79 // If the method is intercepted, the stub gets the |
| 89 // receiver explicitely and we need to pass it to the getter call. | 80 // receiver explicitely and we need to pass it to the getter call. |
| 90 bool isInterceptedMethod = backend.isInterceptedMethod(member); | 81 bool isInterceptedMethod = backend.isInterceptedMethod(member); |
| 91 bool isInterceptorClass = backend.isInterceptorClass(member.enclosingClass); | 82 bool isInterceptorClass = backend.isInterceptorClass(member.enclosingClass); |
| 92 | 83 |
| 93 const String receiverArgumentName = r'$receiver'; | 84 const String receiverArgumentName = r'$receiver'; |
| 94 | 85 |
| 95 jsAst.Expression buildGetter() { | 86 jsAst.Expression buildGetter() { |
| 96 jsAst.Expression receiver = | 87 jsAst.Expression receiver = |
| 97 js(isInterceptorClass ? receiverArgumentName : 'this'); | 88 js(isInterceptorClass ? receiverArgumentName : 'this'); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 /// Each function must have the `$callName` property set. | 221 /// Each function must have the `$callName` property set. |
| 231 /// * `reflectionInfo`: contains reflective information, and the function | 222 /// * `reflectionInfo`: contains reflective information, and the function |
| 232 /// type. TODO(floitsch): point to where this is specified. | 223 /// type. TODO(floitsch): point to where this is specified. |
| 233 /// * `isStatic`. | 224 /// * `isStatic`. |
| 234 /// * `name`. | 225 /// * `name`. |
| 235 /// * `isIntercepted. | 226 /// * `isIntercepted. |
| 236 List<jsAst.Statement> buildTearOffCode(JavaScriptBackend backend) { | 227 List<jsAst.Statement> buildTearOffCode(JavaScriptBackend backend) { |
| 237 Namer namer = backend.namer; | 228 Namer namer = backend.namer; |
| 238 Compiler compiler = backend.compiler; | 229 Compiler compiler = backend.compiler; |
| 239 | 230 |
| 240 Element closureFromTearOff = backend.helpers.closureFromTearOff; | 231 FunctionEntity closureFromTearOff = backend.helpers.closureFromTearOff; |
| 241 jsAst.Expression tearOffAccessExpression; | 232 jsAst.Expression tearOffAccessExpression; |
| 242 jsAst.Expression tearOffGlobalObjectString; | 233 jsAst.Expression tearOffGlobalObjectString; |
| 243 jsAst.Expression tearOffGlobalObject; | 234 jsAst.Expression tearOffGlobalObject; |
| 244 if (closureFromTearOff != null) { | 235 if (closureFromTearOff != null) { |
| 245 tearOffAccessExpression = | 236 tearOffAccessExpression = |
| 246 backend.emitter.staticFunctionAccess(closureFromTearOff); | 237 backend.emitter.staticFunctionAccess(closureFromTearOff); |
| 247 tearOffGlobalObject = | 238 tearOffGlobalObject = |
| 248 js.stringPart(namer.globalObjectFor(closureFromTearOff)); | 239 js.stringPart(namer.globalObjectForMethod(closureFromTearOff)); |
| 249 tearOffGlobalObjectString = | 240 tearOffGlobalObjectString = |
| 250 js.string(namer.globalObjectFor(closureFromTearOff)); | 241 js.string(namer.globalObjectForMethod(closureFromTearOff)); |
| 251 } else { | 242 } else { |
| 252 // Default values for mocked-up test libraries. | 243 // Default values for mocked-up test libraries. |
| 253 tearOffAccessExpression = | 244 tearOffAccessExpression = |
| 254 js(r'''function() { throw "Helper 'closureFromTearOff' missing." }'''); | 245 js(r'''function() { throw "Helper 'closureFromTearOff' missing." }'''); |
| 255 tearOffGlobalObjectString = js.string('MissingHelperFunction'); | 246 tearOffGlobalObjectString = js.string('MissingHelperFunction'); |
| 256 tearOffGlobalObject = js( | 247 tearOffGlobalObject = js( |
| 257 r'''(function() { throw "Helper 'closureFromTearOff' missing." })()'''); | 248 r'''(function() { throw "Helper 'closureFromTearOff' missing." })()'''); |
| 258 } | 249 } |
| 259 | 250 |
| 260 jsAst.Statement tearOffGetter; | 251 jsAst.Statement tearOffGetter; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 314 if (cache === void 0) cache = #tearOff( | 305 if (cache === void 0) cache = #tearOff( |
| 315 this, funcs, reflectionInfo, true, [], name).prototype; | 306 this, funcs, reflectionInfo, true, [], name).prototype; |
| 316 return cache; | 307 return cache; |
| 317 } | 308 } |
| 318 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); | 309 : tearOffGetter(funcs, reflectionInfo, name, isIntercepted); |
| 319 }''', | 310 }''', |
| 320 {'tearOff': tearOffAccessExpression}); | 311 {'tearOff': tearOffAccessExpression}); |
| 321 | 312 |
| 322 return <jsAst.Statement>[tearOffGetter, tearOff]; | 313 return <jsAst.Statement>[tearOffGetter, tearOff]; |
| 323 } | 314 } |
| OLD | NEW |