OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /// Represents an entry's position in one of the global metadata arrays. | 7 /// Represents an entry's position in one of the global metadata arrays. |
8 /// | 8 /// |
9 /// [_rc] is used to count the number of references of the token in the | 9 /// [_rc] is used to count the number of references of the token in the |
10 /// ast for a program. | 10 /// ast for a program. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 metadata.add(_emitter.constantReference(constant)); | 171 metadata.add(_emitter.constantReference(constant)); |
172 } | 172 } |
173 } | 173 } |
174 if (metadata.isEmpty) return null; | 174 if (metadata.isEmpty) return null; |
175 return js('function() { return # }', | 175 return js('function() { return # }', |
176 new jsAst.ArrayInitializer(metadata)); | 176 new jsAst.ArrayInitializer(metadata)); |
177 }); | 177 }); |
178 } | 178 } |
179 | 179 |
180 List<jsAst.DeferredNumber> reifyDefaultArguments(FunctionElement function) { | 180 List<jsAst.DeferredNumber> reifyDefaultArguments(FunctionElement function) { |
| 181 function = function.implementation; |
181 FunctionSignature signature = function.functionSignature; | 182 FunctionSignature signature = function.functionSignature; |
182 if (signature.optionalParameterCount == 0) return const []; | 183 if (signature.optionalParameterCount == 0) return const []; |
| 184 |
| 185 // Optional parameters of redirecting factory constructors take their |
| 186 // defaults from the corresponding parameters of the redirection target. |
| 187 Map<ParameterElement, ParameterElement> targetParameterMap; |
| 188 if (function is ConstructorElement) { |
| 189 // TODO(sra): dart2js generates a redirecting factory constructor body |
| 190 // that has the signature of the redirecting constructor that calls the |
| 191 // redirection target. This is wrong - it should have the signature of the |
| 192 // target. This would make the reified default arguments trivial. |
| 193 |
| 194 ConstructorElement constructor = function; |
| 195 while (constructor.isRedirectingFactory && |
| 196 !constructor.isCyclicRedirection) { |
| 197 // TODO(sra): Remove the loop once effectiveTarget forwards to patches. |
| 198 constructor = constructor.effectiveTarget.implementation; |
| 199 } |
| 200 |
| 201 if (constructor != function) { |
| 202 if (signature.hasOptionalParameters) { |
| 203 targetParameterMap = |
| 204 mapRedirectingFactoryConstructorOptionalParameters( |
| 205 signature, constructor.functionSignature); |
| 206 } |
| 207 } |
| 208 } |
| 209 |
183 List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[]; | 210 List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[]; |
184 for (ParameterElement element in signature.optionalParameters) { | 211 for (ParameterElement element in signature.optionalParameters) { |
185 ConstantValue constant = | 212 ParameterElement parameter = |
186 _backend.constants.getConstantValueForVariable(element); | 213 (targetParameterMap == null) ? element : targetParameterMap[element]; |
| 214 ConstantValue constant = (parameter == null) |
| 215 ? null |
| 216 : _backend.constants.getConstantValueForVariable(parameter); |
187 jsAst.Expression expression = (constant == null) | 217 jsAst.Expression expression = (constant == null) |
188 ? new jsAst.LiteralNull() | 218 ? new jsAst.LiteralNull() |
189 : _emitter.constantReference(constant); | 219 : _emitter.constantReference(constant); |
190 defaultValues.add(_addGlobalMetadata(expression)); | 220 defaultValues.add(_addGlobalMetadata(expression)); |
191 } | 221 } |
192 return defaultValues; | 222 return defaultValues; |
193 } | 223 } |
194 | 224 |
| 225 Map<ParameterElement, ParameterElement> |
| 226 mapRedirectingFactoryConstructorOptionalParameters( |
| 227 FunctionSignature source, FunctionSignature target) { |
| 228 var map = <ParameterElement, ParameterElement>{}; |
| 229 |
| 230 if (source.optionalParametersAreNamed != |
| 231 target.optionalParametersAreNamed) { |
| 232 // No legal optional arguments due to mismatch between named vs positional |
| 233 // optional arguments. |
| 234 return map; |
| 235 } |
| 236 |
| 237 if (source.optionalParametersAreNamed) { |
| 238 for (ParameterElement element in source.optionalParameters) { |
| 239 for (ParameterElement redirectedElement in target.optionalParameters) { |
| 240 if (element.name == redirectedElement.name) { |
| 241 map[element] = redirectedElement; |
| 242 break; |
| 243 } |
| 244 } |
| 245 } |
| 246 } else { |
| 247 int i = source.requiredParameterCount; |
| 248 for (ParameterElement element in source.orderedOptionalParameters) { |
| 249 if (i >= target.requiredParameterCount && i < target.parameterCount) { |
| 250 map[element] = |
| 251 target.orderedOptionalParameters[i - target.requiredParameterCount
]; |
| 252 } |
| 253 ++i; |
| 254 } |
| 255 } |
| 256 return map; |
| 257 } |
| 258 |
195 jsAst.Expression reifyMetadata(MetadataAnnotation annotation) { | 259 jsAst.Expression reifyMetadata(MetadataAnnotation annotation) { |
196 ConstantValue constant = | 260 ConstantValue constant = |
197 _backend.constants.getConstantValueForMetadata(annotation); | 261 _backend.constants.getConstantValueForMetadata(annotation); |
198 if (constant == null) { | 262 if (constant == null) { |
199 reporter.internalError(annotation, 'Annotation value is null.'); | 263 reporter.internalError(annotation, 'Annotation value is null.'); |
200 return null; | 264 return null; |
201 } | 265 } |
202 return _addGlobalMetadata(_emitter.constantReference(constant)); | 266 return _addGlobalMetadata(_emitter.constantReference(constant)); |
203 } | 267 } |
204 | 268 |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 visitDeferredNumber(jsAst.DeferredNumber token) { | 422 visitDeferredNumber(jsAst.DeferredNumber token) { |
359 if (token is _ForwardingMetadataEntry && !token.isBound) { | 423 if (token is _ForwardingMetadataEntry && !token.isBound) { |
360 _foundUnboundToken = true; | 424 _foundUnboundToken = true; |
361 } | 425 } |
362 } | 426 } |
363 | 427 |
364 bool findUnboundPlaceholders(jsAst.Node node) { | 428 bool findUnboundPlaceholders(jsAst.Node node) { |
365 node.accept(this); | 429 node.accept(this); |
366 return _foundUnboundToken; | 430 return _foundUnboundToken; |
367 } | 431 } |
368 } | 432 } |
OLD | NEW |