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