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