Chromium Code Reviews| Index: pkg/compiler/lib/src/js_emitter/class_stub_generator.dart |
| diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart |
| index f2f48ca0ab1a52c61c1983a1025ddbb19a3308eb..d7e1578c9962a0ecc46ba159681e45a0fd10f593 100644 |
| --- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart |
| +++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart |
| @@ -40,4 +40,75 @@ class ClassStubGenerator { |
| return js('function(#, v) { return #.# = v; }', |
| [args, receiver, fieldName]); |
| } |
| + |
| + /** |
| + * Documentation wanted -- johnniwinther |
| + * |
| + * Invariant: [member] must be a declaration element. |
| + */ |
| + Map<String, jsAst.Expression> generateCallStubsForGetter( |
|
floitsch
2015/01/22 15:51:14
directly copied except for marked changes.
|
| + Element member, Set<Selector> selectors) { |
| + assert(invariant(member, member.isDeclaration)); |
| + |
| + // If the method is intercepted, the stub gets the |
| + // receiver explicitely and we need to pass it to the getter call. |
| + bool isInterceptedMethod = backend.isInterceptedMethod(member); |
| + bool isInterceptorClass = |
| + backend.isInterceptorClass(member.enclosingClass); |
| + |
| + const String receiverArgumentName = r'$receiver'; |
| + |
| + jsAst.Expression buildGetter() { |
| + jsAst.Expression receiver = |
| + js(isInterceptorClass ? receiverArgumentName : 'this'); |
| + if (member.isGetter) { |
| + String getterName = namer.getterName(member); |
| + if (isInterceptedMethod) { |
| + return js('this.#(#)', [getterName, receiver]); |
| + } |
| + return js('#.#()', [receiver, getterName]); |
| + } else { |
| + String fieldName = namer.instanceFieldPropertyName(member); |
| + return js('#.#', [receiver, fieldName]); |
| + } |
| + } |
| + |
| + Map<String, jsAst.Expression> generatedStubs = <String, jsAst.Expression>{}; |
| + |
| + // Two selectors may match but differ only in type. To avoid generating |
| + // identical stubs for each we track untyped selectors which already have |
| + // stubs. |
| + Set<Selector> generatedSelectors = new Set<Selector>(); |
| + for (Selector selector in selectors) { |
| + if (selector.applies(member, compiler.world)) { |
| + selector = selector.asUntyped; |
| + if (generatedSelectors.contains(selector)) continue; |
| + generatedSelectors.add(selector); |
| + |
| + String invocationName = namer.invocationName(selector); |
| + Selector callSelector = new Selector.callClosureFrom(selector); |
| + String closureCallName = namer.invocationName(callSelector); |
| + |
| + List<jsAst.Parameter> parameters = <jsAst.Parameter>[]; |
| + List<jsAst.Expression> arguments = <jsAst.Expression>[]; |
| + if (isInterceptedMethod) { |
| + parameters.add(new jsAst.Parameter(receiverArgumentName)); |
| + } |
| + |
| + for (int i = 0; i < selector.argumentCount; i++) { |
| + String name = 'arg$i'; |
| + parameters.add(new jsAst.Parameter(name)); |
| + arguments.add(js('#', name)); |
| + } |
| + |
| + jsAst.Fun function = js( |
| + 'function(#) { return #.#(#); }', |
| + [ parameters, buildGetter(), closureCallName, arguments]); |
| + |
| + generatedStubs[invocationName] = function; |
|
floitsch
2015/01/22 15:51:14
changes here and following lines.
|
| + } |
| + } |
| + |
| + return generatedStubs; |
| + } |
| } |