| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library universe; | 5 library universe; |
| 6 | 6 |
| 7 import '../closure.dart'; | 7 import '../closure.dart'; |
| 8 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 9 import '../dart2jslib.dart'; | 9 import '../dart2jslib.dart'; |
| 10 import '../runtime_types.dart'; | 10 import '../runtime_types.dart'; |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 | 129 |
| 130 Selector( | 130 Selector( |
| 131 this.kind, | 131 this.kind, |
| 132 SourceString name, | 132 SourceString name, |
| 133 LibraryElement library, | 133 LibraryElement library, |
| 134 this.argumentCount, | 134 this.argumentCount, |
| 135 [List<SourceString> namedArguments = const <SourceString>[]]) | 135 [List<SourceString> namedArguments = const <SourceString>[]]) |
| 136 : this.name = name, | 136 : this.name = name, |
| 137 this.library = name.isPrivate() ? library : null, | 137 this.library = name.isPrivate() ? library : null, |
| 138 this.namedArguments = namedArguments, | 138 this.namedArguments = namedArguments, |
| 139 this.orderedNamedArguments = namedArguments.isEmpty() | 139 this.orderedNamedArguments = namedArguments.isEmpty |
| 140 ? namedArguments | 140 ? namedArguments |
| 141 : <SourceString>[] { | 141 : <SourceString>[] { |
| 142 assert(!name.isPrivate() || library != null); | 142 assert(!name.isPrivate() || library != null); |
| 143 } | 143 } |
| 144 | 144 |
| 145 Selector.getter(SourceString name, LibraryElement library) | 145 Selector.getter(SourceString name, LibraryElement library) |
| 146 : this(SelectorKind.GETTER, name, library, 0); | 146 : this(SelectorKind.GETTER, name, library, 0); |
| 147 | 147 |
| 148 Selector.getterFrom(Selector selector) | 148 Selector.getterFrom(Selector selector) |
| 149 : this(SelectorKind.GETTER, selector.name, selector.library, 0); | 149 : this(SelectorKind.GETTER, selector.name, selector.library, 0); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 // TODO(5074): Remove this check once we don't accept the | 239 // TODO(5074): Remove this check once we don't accept the |
| 240 // deprecated parameter specification. | 240 // deprecated parameter specification. |
| 241 if (!Compiler.REJECT_NAMED_ARGUMENT_AS_POSITIONAL) { | 241 if (!Compiler.REJECT_NAMED_ARGUMENT_AS_POSITIONAL) { |
| 242 return optionalParametersAppliesDEPRECATED(element, compiler); | 242 return optionalParametersAppliesDEPRECATED(element, compiler); |
| 243 } else { | 243 } else { |
| 244 // We have already checked that the number of arguments are | 244 // We have already checked that the number of arguments are |
| 245 // not greater than the number of parameters. Therefore the | 245 // not greater than the number of parameters. Therefore the |
| 246 // number of positional arguments are not greater than the | 246 // number of positional arguments are not greater than the |
| 247 // number of parameters. | 247 // number of parameters. |
| 248 assert(positionalArgumentCount <= parameters.parameterCount); | 248 assert(positionalArgumentCount <= parameters.parameterCount); |
| 249 return namedArguments.isEmpty(); | 249 return namedArguments.isEmpty; |
| 250 } | 250 } |
| 251 } else { | 251 } else { |
| 252 if (positionalArgumentCount > requiredParameterCount) return false; | 252 if (positionalArgumentCount > requiredParameterCount) return false; |
| 253 assert(positionalArgumentCount == requiredParameterCount); | 253 assert(positionalArgumentCount == requiredParameterCount); |
| 254 if (namedArgumentCount > optionalParameterCount) return false; | 254 if (namedArgumentCount > optionalParameterCount) return false; |
| 255 Set<SourceString> nameSet = new Set<SourceString>(); | 255 Set<SourceString> nameSet = new Set<SourceString>(); |
| 256 parameters.optionalParameters.forEach((Element element) { | 256 parameters.optionalParameters.forEach((Element element) { |
| 257 nameSet.add(element.name); | 257 nameSet.add(element.name); |
| 258 }); | 258 }); |
| 259 for (SourceString name in namedArguments) { | 259 for (SourceString name in namedArguments) { |
| 260 if (!nameSet.contains(name)) return false; | 260 if (!nameSet.contains(name)) return false; |
| 261 // TODO(5213): By removing from the set we are checking | 261 // TODO(5213): By removing from the set we are checking |
| 262 // that we are not passing the name twice. We should have this | 262 // that we are not passing the name twice. We should have this |
| 263 // check in the resolver also. | 263 // check in the resolver also. |
| 264 nameSet.remove(name); | 264 nameSet.remove(name); |
| 265 } | 265 } |
| 266 return true; | 266 return true; |
| 267 } | 267 } |
| 268 } | 268 } |
| 269 | 269 |
| 270 // TODO(5074): Remove this method once we don't accept the | 270 // TODO(5074): Remove this method once we don't accept the |
| 271 // deprecated parameter specification. | 271 // deprecated parameter specification. |
| 272 bool optionalParametersAppliesDEPRECATED(FunctionElement function, | 272 bool optionalParametersAppliesDEPRECATED(FunctionElement function, |
| 273 Compiler compiler) { | 273 Compiler compiler) { |
| 274 FunctionSignature parameters = function.computeSignature(compiler); | 274 FunctionSignature parameters = function.computeSignature(compiler); |
| 275 int requiredParameterCount = parameters.requiredParameterCount; | 275 int requiredParameterCount = parameters.requiredParameterCount; |
| 276 int optionalParameterCount = parameters.optionalParameterCount; | 276 int optionalParameterCount = parameters.optionalParameterCount; |
| 277 | 277 |
| 278 bool hasOptionalParameters = !parameters.optionalParameters.isEmpty(); | 278 bool hasOptionalParameters = !parameters.optionalParameters.isEmpty; |
| 279 if (namedArguments.isEmpty()) { | 279 if (namedArguments.isEmpty) { |
| 280 if (!hasOptionalParameters) { | 280 if (!hasOptionalParameters) { |
| 281 return requiredParameterCount == argumentCount; | 281 return requiredParameterCount == argumentCount; |
| 282 } else { | 282 } else { |
| 283 return argumentCount >= requiredParameterCount && | 283 return argumentCount >= requiredParameterCount && |
| 284 argumentCount <= requiredParameterCount + optionalParameterCount; | 284 argumentCount <= requiredParameterCount + optionalParameterCount; |
| 285 } | 285 } |
| 286 } else { | 286 } else { |
| 287 if (!hasOptionalParameters) return false; | 287 if (!hasOptionalParameters) return false; |
| 288 Link<Element> remainingNamedParameters = parameters.optionalParameters; | 288 Link<Element> remainingNamedParameters = parameters.optionalParameters; |
| 289 for (int i = requiredParameterCount; i < positionalArgumentCount; i++) { | 289 for (int i = requiredParameterCount; i < positionalArgumentCount; i++) { |
| 290 remainingNamedParameters = remainingNamedParameters.tail; | 290 remainingNamedParameters = remainingNamedParameters.tail; |
| 291 } | 291 } |
| 292 Set<SourceString> nameSet = new Set<SourceString>(); | 292 Set<SourceString> nameSet = new Set<SourceString>(); |
| 293 for (; | 293 for (; |
| 294 !remainingNamedParameters.isEmpty(); | 294 !remainingNamedParameters.isEmpty; |
| 295 remainingNamedParameters = remainingNamedParameters.tail) { | 295 remainingNamedParameters = remainingNamedParameters.tail) { |
| 296 nameSet.add(remainingNamedParameters.head.name); | 296 nameSet.add(remainingNamedParameters.head.name); |
| 297 } | 297 } |
| 298 | 298 |
| 299 for (SourceString name in namedArguments) { | 299 for (SourceString name in namedArguments) { |
| 300 if (!nameSet.contains(name)) { | 300 if (!nameSet.contains(name)) { |
| 301 return false; | 301 return false; |
| 302 } | 302 } |
| 303 nameSet.remove(name); | 303 nameSet.remove(name); |
| 304 } | 304 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 321 | 321 |
| 322 // Visit positional arguments and add them to the list. | 322 // Visit positional arguments and add them to the list. |
| 323 for (int i = parameters.requiredParameterCount; | 323 for (int i = parameters.requiredParameterCount; |
| 324 i < positionalArgumentCount; | 324 i < positionalArgumentCount; |
| 325 arguments = arguments.tail, i++) { | 325 arguments = arguments.tail, i++) { |
| 326 list.add(compileArgument(arguments.head)); | 326 list.add(compileArgument(arguments.head)); |
| 327 } | 327 } |
| 328 | 328 |
| 329 // Visit named arguments and add them into a temporary list. | 329 // Visit named arguments and add them into a temporary list. |
| 330 List compiledNamedArguments = []; | 330 List compiledNamedArguments = []; |
| 331 for (; !arguments.isEmpty(); arguments = arguments.tail) { | 331 for (; !arguments.isEmpty; arguments = arguments.tail) { |
| 332 NamedArgument namedArgument = arguments.head; | 332 NamedArgument namedArgument = arguments.head; |
| 333 compiledNamedArguments.add(compileArgument(namedArgument.expression)); | 333 compiledNamedArguments.add(compileArgument(namedArgument.expression)); |
| 334 } | 334 } |
| 335 | 335 |
| 336 Link<Element> remainingNamedParameters = parameters.optionalParameters; | 336 Link<Element> remainingNamedParameters = parameters.optionalParameters; |
| 337 // Skip the optional parameters that have been given in the | 337 // Skip the optional parameters that have been given in the |
| 338 // positional arguments. | 338 // positional arguments. |
| 339 for (int i = parameters.requiredParameterCount; | 339 for (int i = parameters.requiredParameterCount; |
| 340 i < positionalArgumentCount; | 340 i < positionalArgumentCount; |
| 341 i++) { | 341 i++) { |
| 342 remainingNamedParameters = remainingNamedParameters.tail; | 342 remainingNamedParameters = remainingNamedParameters.tail; |
| 343 } | 343 } |
| 344 | 344 |
| 345 // Loop over the remaining named parameters, and try to find | 345 // Loop over the remaining named parameters, and try to find |
| 346 // their values: either in the temporary list or using the | 346 // their values: either in the temporary list or using the |
| 347 // default value. | 347 // default value. |
| 348 for (; | 348 for (; |
| 349 !remainingNamedParameters.isEmpty(); | 349 !remainingNamedParameters.isEmpty; |
| 350 remainingNamedParameters = remainingNamedParameters.tail) { | 350 remainingNamedParameters = remainingNamedParameters.tail) { |
| 351 Element parameter = remainingNamedParameters.head; | 351 Element parameter = remainingNamedParameters.head; |
| 352 int foundIndex = namedArguments.indexOf(parameter.name); | 352 int foundIndex = namedArguments.indexOf(parameter.name); |
| 353 if (foundIndex != -1) { | 353 if (foundIndex != -1) { |
| 354 list.add(compiledNamedArguments[foundIndex]); | 354 list.add(compiledNamedArguments[foundIndex]); |
| 355 } else { | 355 } else { |
| 356 list.add(compileConstant(parameter)); | 356 list.add(compileConstant(parameter)); |
| 357 } | 357 } |
| 358 } | 358 } |
| 359 } | 359 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 382 | 382 |
| 383 if (!parameters.optionalParametersAreNamed) { | 383 if (!parameters.optionalParametersAreNamed) { |
| 384 // TODO(5074): Remove this check once we don't accept the | 384 // TODO(5074): Remove this check once we don't accept the |
| 385 // deprecated parameter specification. | 385 // deprecated parameter specification. |
| 386 if (!Compiler.REJECT_NAMED_ARGUMENT_AS_POSITIONAL) { | 386 if (!Compiler.REJECT_NAMED_ARGUMENT_AS_POSITIONAL) { |
| 387 addOptionalArgumentsToListDEPRECATED( | 387 addOptionalArgumentsToListDEPRECATED( |
| 388 arguments, list, element, compileArgument, compileConstant, | 388 arguments, list, element, compileArgument, compileConstant, |
| 389 compiler); | 389 compiler); |
| 390 } else { | 390 } else { |
| 391 parameters.forEachOptionalParameter((element) { | 391 parameters.forEachOptionalParameter((element) { |
| 392 if (!arguments.isEmpty()) { | 392 if (!arguments.isEmpty) { |
| 393 list.add(compileArgument(arguments.head)); | 393 list.add(compileArgument(arguments.head)); |
| 394 arguments = arguments.tail; | 394 arguments = arguments.tail; |
| 395 } else { | 395 } else { |
| 396 list.add(compileConstant(element)); | 396 list.add(compileConstant(element)); |
| 397 } | 397 } |
| 398 }); | 398 }); |
| 399 } | 399 } |
| 400 } else { | 400 } else { |
| 401 // Visit named arguments and add them into a temporary list. | 401 // Visit named arguments and add them into a temporary list. |
| 402 List compiledNamedArguments = []; | 402 List compiledNamedArguments = []; |
| 403 for (; !arguments.isEmpty(); arguments = arguments.tail) { | 403 for (; !arguments.isEmpty; arguments = arguments.tail) { |
| 404 NamedArgument namedArgument = arguments.head; | 404 NamedArgument namedArgument = arguments.head; |
| 405 compiledNamedArguments.add(compileArgument(namedArgument.expression)); | 405 compiledNamedArguments.add(compileArgument(namedArgument.expression)); |
| 406 } | 406 } |
| 407 // Iterate over the optional parameters of the signature, and try to | 407 // Iterate over the optional parameters of the signature, and try to |
| 408 // find them in [compiledNamedArguments]. If found, we use the | 408 // find them in [compiledNamedArguments]. If found, we use the |
| 409 // value in the temporary list, otherwise the default value. | 409 // value in the temporary list, otherwise the default value. |
| 410 parameters.orderedOptionalParameters.forEach((element) { | 410 parameters.orderedOptionalParameters.forEach((element) { |
| 411 int foundIndex = namedArguments.indexOf(element.name); | 411 int foundIndex = namedArguments.indexOf(element.name); |
| 412 if (foundIndex != -1) { | 412 if (foundIndex != -1) { |
| 413 list.add(compiledNamedArguments[foundIndex]); | 413 list.add(compiledNamedArguments[foundIndex]); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 434 | 434 |
| 435 bool equalsUntyped(Selector other) { | 435 bool equalsUntyped(Selector other) { |
| 436 return name == other.name | 436 return name == other.name |
| 437 && identical(library, other.library) | 437 && identical(library, other.library) |
| 438 && argumentCount == other.argumentCount | 438 && argumentCount == other.argumentCount |
| 439 && namedArguments.length == other.namedArguments.length | 439 && namedArguments.length == other.namedArguments.length |
| 440 && sameNames(namedArguments, other.namedArguments); | 440 && sameNames(namedArguments, other.namedArguments); |
| 441 } | 441 } |
| 442 | 442 |
| 443 List<SourceString> getOrderedNamedArguments() { | 443 List<SourceString> getOrderedNamedArguments() { |
| 444 if (namedArguments.isEmpty()) return namedArguments; | 444 if (namedArguments.isEmpty) return namedArguments; |
| 445 if (!orderedNamedArguments.isEmpty()) return orderedNamedArguments; | 445 if (!orderedNamedArguments.isEmpty) return orderedNamedArguments; |
| 446 | 446 |
| 447 orderedNamedArguments.addAll(namedArguments); | 447 orderedNamedArguments.addAll(namedArguments); |
| 448 orderedNamedArguments.sort((SourceString first, SourceString second) { | 448 orderedNamedArguments.sort((SourceString first, SourceString second) { |
| 449 return first.slowToString().compareTo(second.slowToString()); | 449 return first.slowToString().compareTo(second.slowToString()); |
| 450 }); | 450 }); |
| 451 return orderedNamedArguments; | 451 return orderedNamedArguments; |
| 452 } | 452 } |
| 453 | 453 |
| 454 String namedArgumentsToString() { | 454 String namedArgumentsToString() { |
| 455 if (namedArgumentCount > 0) { | 455 if (namedArgumentCount > 0) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 529 |
| 530 if (!self.isInterface() && self.isSubclassOf(other)) { | 530 if (!self.isInterface() && self.isSubclassOf(other)) { |
| 531 // Resolve an invocation of [element.name] on [self]. If it | 531 // Resolve an invocation of [element.name] on [self]. If it |
| 532 // is found, this selector is a candidate. | 532 // is found, this selector is a candidate. |
| 533 return hasElementIn(self, element) && appliesUntyped(element, compiler); | 533 return hasElementIn(self, element) && appliesUntyped(element, compiler); |
| 534 } | 534 } |
| 535 | 535 |
| 536 return false; | 536 return false; |
| 537 } | 537 } |
| 538 } | 538 } |
| OLD | NEW |