OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 class ParameterStubGenerator { | 7 class ParameterStubGenerator { |
8 static final Set<Selector> emptySelectorSet = new Set<Selector>(); | 8 static final Set<Selector> emptySelectorSet = new Set<Selector>(); |
9 | 9 |
10 final Namer namer; | 10 final Namer namer; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 return null; | 52 return null; |
53 } | 53 } |
54 JavaScriptConstantCompiler handler = backend.constants; | 54 JavaScriptConstantCompiler handler = backend.constants; |
55 List<String> names = selector.getOrderedNamedArguments(); | 55 List<String> names = selector.getOrderedNamedArguments(); |
56 | 56 |
57 bool isInterceptedMethod = backend.isInterceptedMethod(member); | 57 bool isInterceptedMethod = backend.isInterceptedMethod(member); |
58 | 58 |
59 // If the method is intercepted, we need to also pass the actual receiver. | 59 // If the method is intercepted, we need to also pass the actual receiver. |
60 int extraArgumentCount = isInterceptedMethod ? 1 : 0; | 60 int extraArgumentCount = isInterceptedMethod ? 1 : 0; |
61 // Use '$receiver' to avoid clashes with other parameter names. Using | 61 // Use '$receiver' to avoid clashes with other parameter names. Using |
62 // '$receiver' works because [:namer.safeName:] used for getting parameter | 62 // '$receiver' works because namer.safeVariableName used for getting paramet
er |
63 // names never returns a name beginning with a single '$'. | 63 // names never returns a name beginning with a single '$'. |
64 String receiverArgumentName = r'$receiver'; | 64 String receiverArgumentName = r'$receiver'; |
65 | 65 |
66 // The parameters that this stub takes. | 66 // The parameters that this stub takes. |
67 List<jsAst.Parameter> parametersBuffer = | 67 List<jsAst.Parameter> parametersBuffer = |
68 new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount); | 68 new List<jsAst.Parameter>(selector.argumentCount + extraArgumentCount); |
69 // The arguments that will be passed to the real method. | 69 // The arguments that will be passed to the real method. |
70 List<jsAst.Expression> argumentsBuffer = | 70 List<jsAst.Expression> argumentsBuffer = |
71 new List<jsAst.Expression>( | 71 new List<jsAst.Expression>( |
72 parameters.parameterCount + extraArgumentCount); | 72 parameters.parameterCount + extraArgumentCount); |
73 | 73 |
74 int count = 0; | 74 int count = 0; |
75 if (isInterceptedMethod) { | 75 if (isInterceptedMethod) { |
76 count++; | 76 count++; |
77 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName); | 77 parametersBuffer[0] = new jsAst.Parameter(receiverArgumentName); |
78 argumentsBuffer[0] = js('#', receiverArgumentName); | 78 argumentsBuffer[0] = js('#', receiverArgumentName); |
79 } | 79 } |
80 | 80 |
81 int optionalParameterStart = positionalArgumentCount + extraArgumentCount; | 81 int optionalParameterStart = positionalArgumentCount + extraArgumentCount; |
82 // Includes extra receiver argument when using interceptor convention | 82 // Includes extra receiver argument when using interceptor convention |
83 int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1; | 83 int indexOfLastOptionalArgumentInParameters = optionalParameterStart - 1; |
84 | 84 |
85 int parameterIndex = 0; | 85 int parameterIndex = 0; |
86 parameters.orderedForEachParameter((ParameterElement element) { | 86 parameters.orderedForEachParameter((ParameterElement element) { |
87 String jsName = backend.namer.safeName(element.name); | 87 String jsName = backend.namer.safeVariableName(element.name); |
88 assert(jsName != receiverArgumentName); | 88 assert(jsName != receiverArgumentName); |
89 if (count < optionalParameterStart) { | 89 if (count < optionalParameterStart) { |
90 parametersBuffer[count] = new jsAst.Parameter(jsName); | 90 parametersBuffer[count] = new jsAst.Parameter(jsName); |
91 argumentsBuffer[count] = js('#', jsName); | 91 argumentsBuffer[count] = js('#', jsName); |
92 } else { | 92 } else { |
93 int index = names.indexOf(element.name); | 93 int index = names.indexOf(element.name); |
94 if (index != -1) { | 94 if (index != -1) { |
95 indexOfLastOptionalArgumentInParameters = count; | 95 indexOfLastOptionalArgumentInParameters = count; |
96 // The order of the named arguments is not the same as the | 96 // The order of the named arguments is not the same as the |
97 // one in the real method (which is in Dart source order). | 97 // one in the real method (which is in Dart source order). |
(...skipping 21 matching lines...) Expand all Loading... |
119 | 119 |
120 var body; // List or jsAst.Statement. | 120 var body; // List or jsAst.Statement. |
121 if (member.hasFixedBackendName) { | 121 if (member.hasFixedBackendName) { |
122 body = emitterTask.nativeEmitter.generateParameterStubStatements( | 122 body = emitterTask.nativeEmitter.generateParameterStubStatements( |
123 member, isInterceptedMethod, namer.invocationName(selector), | 123 member, isInterceptedMethod, namer.invocationName(selector), |
124 parametersBuffer, argumentsBuffer, | 124 parametersBuffer, argumentsBuffer, |
125 indexOfLastOptionalArgumentInParameters); | 125 indexOfLastOptionalArgumentInParameters); |
126 } else if (member.isInstanceMember) { | 126 } else if (member.isInstanceMember) { |
127 if (needsSuperGetter(member)) { | 127 if (needsSuperGetter(member)) { |
128 ClassElement superClass = member.enclosingClass; | 128 ClassElement superClass = member.enclosingClass; |
129 String methodName = namer.getNameOfInstanceMember(member); | 129 String methodName = namer.instanceMethodName(member); |
130 // When redirecting, we must ensure that we don't end up in a subclass. | 130 // When redirecting, we must ensure that we don't end up in a subclass. |
131 // We thus can't just invoke `this.foo$1.call(filledInArguments)`. | 131 // We thus can't just invoke `this.foo$1.call(filledInArguments)`. |
132 // Instead we need to call the statically resolved target. | 132 // Instead we need to call the statically resolved target. |
133 // `<class>.prototype.bar$1.call(this, argument0, ...)`. | 133 // `<class>.prototype.bar$1.call(this, argument0, ...)`. |
134 body = js.statement( | 134 body = js.statement( |
135 'return #.#.call(this, #);', | 135 'return #.#.call(this, #);', |
136 [backend.emitter.prototypeAccess(superClass, | 136 [backend.emitter.prototypeAccess(superClass, |
137 hasBeenInstantiated: true), | 137 hasBeenInstantiated: true), |
138 methodName, | 138 methodName, |
139 argumentsBuffer]); | 139 argumentsBuffer]); |
140 } else { | 140 } else { |
141 body = js.statement( | 141 body = js.statement( |
142 'return this.#(#);', | 142 'return this.#(#);', |
143 [namer.getNameOfInstanceMember(member), argumentsBuffer]); | 143 [namer.instanceMethodName(member), argumentsBuffer]); |
144 } | 144 } |
145 } else { | 145 } else { |
146 body = js.statement('return #(#)', | 146 body = js.statement('return #(#)', |
147 [emitter.staticFunctionAccess(member), argumentsBuffer]); | 147 [emitter.staticFunctionAccess(member), argumentsBuffer]); |
148 } | 148 } |
149 | 149 |
150 jsAst.Fun function = js('function(#) { #; }', [parametersBuffer, body]); | 150 jsAst.Fun function = js('function(#) { #; }', [parametersBuffer, body]); |
151 | 151 |
152 String name = namer.invocationName(selector); | 152 String name = namer.invocationName(selector); |
153 String callName = | 153 String callName = |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 generateParameterStub(member, selector, null); | 271 generateParameterStub(member, selector, null); |
272 if (stub != null) { | 272 if (stub != null) { |
273 stubs.add(stub); | 273 stubs.add(stub); |
274 } | 274 } |
275 } | 275 } |
276 } | 276 } |
277 | 277 |
278 return stubs; | 278 return stubs; |
279 } | 279 } |
280 } | 280 } |
OLD | NEW |