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 '../dart_types.dart'; | 10 import '../dart_types.dart'; |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 return appliesUnnamed(element, compiler); | 369 return appliesUnnamed(element, compiler); |
370 } | 370 } |
371 | 371 |
372 /** | 372 /** |
373 * Fills [list] with the arguments in a defined order. | 373 * Fills [list] with the arguments in a defined order. |
374 * | 374 * |
375 * [compileArgument] is a function that returns a compiled version | 375 * [compileArgument] is a function that returns a compiled version |
376 * of an argument located in [arguments]. | 376 * of an argument located in [arguments]. |
377 * | 377 * |
378 * [compileConstant] is a function that returns a compiled constant | 378 * [compileConstant] is a function that returns a compiled constant |
379 * of an optional argument that is not in [arguments. | 379 * of an optional argument that is not in [arguments]. |
380 * | 380 * |
381 * Returns [:true:] if the selector and the [element] match; [:false:] | 381 * Returns [:true:] if the selector and the [element] match; [:false:] |
382 * otherwise. | 382 * otherwise. |
383 * | 383 * |
384 * Invariant: [element] must be the implementation element. | 384 * Invariant: [element] must be the implementation element. |
385 */ | 385 */ |
386 bool addArgumentsToList(Link<Node> arguments, | 386 bool addArgumentsToList(Link<Node> arguments, |
387 List list, | 387 List list, |
388 FunctionElement element, | 388 FunctionElement element, |
389 compileArgument(Node argument), | 389 compileArgument(Node argument), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 if (foundIndex != -1) { | 422 if (foundIndex != -1) { |
423 list.add(compiledNamedArguments[foundIndex]); | 423 list.add(compiledNamedArguments[foundIndex]); |
424 } else { | 424 } else { |
425 list.add(compileConstant(element)); | 425 list.add(compileConstant(element)); |
426 } | 426 } |
427 }); | 427 }); |
428 } | 428 } |
429 return true; | 429 return true; |
430 } | 430 } |
431 | 431 |
| 432 /** |
| 433 * Fills [list] with the arguments in the order expected by |
| 434 * [callee], and where [caller] is a synthesized element |
| 435 * |
| 436 * [compileArgument] is a function that returns a compiled version |
| 437 * of a parameter of [callee]. |
| 438 * |
| 439 * [compileConstant] is a function that returns a compiled constant |
| 440 * of an optional argument that is not in the parameters of [callee]. |
| 441 * |
| 442 * Returns [:true:] if the signature of the [caller] matches the |
| 443 * signature of the [callee], [:false:] otherwise. |
| 444 */ |
| 445 static bool addForwardingElementArgumentsToList( |
| 446 FunctionElement caller, |
| 447 List list, |
| 448 FunctionElement callee, |
| 449 compileArgument(Element element), |
| 450 compileConstant(Element element), |
| 451 Compiler compiler) { |
| 452 |
| 453 FunctionSignature signature = caller.computeSignature(compiler); |
| 454 Map mapping = new Map(); |
| 455 |
| 456 // TODO(ngeoffray): This is a hack that fakes up AST nodes, so |
| 457 // that we can call [addArgumentsToList]. |
| 458 Link computeCallNodesFromParameters() { |
| 459 LinkBuilder builder = new LinkBuilder(); |
| 460 signature.forEachRequiredParameter((Element element) { |
| 461 Node node = element.parseNode(compiler); |
| 462 mapping[node] = element; |
| 463 builder.addLast(node); |
| 464 }); |
| 465 if (signature.optionalParametersAreNamed) { |
| 466 signature.forEachOptionalParameter((Element element) { |
| 467 Node node = element.parseNode(compiler); |
| 468 mapping[node] = element; |
| 469 builder.addLast(new NamedArgument(null, null, node)); |
| 470 }); |
| 471 } else { |
| 472 signature.forEachOptionalParameter((Element element) { |
| 473 Node node = element.parseNode(compiler); |
| 474 mapping[node] = element; |
| 475 builder.addLast(node); |
| 476 }); |
| 477 } |
| 478 return builder.toLink(); |
| 479 } |
| 480 |
| 481 internalCompileArgument(Node node) => compileArgument(mapping[node]); |
| 482 |
| 483 Link<Node> nodes = computeCallNodesFromParameters(); |
| 484 |
| 485 // Synthesize a selector for the call. |
| 486 // TODO(ngeoffray): Should the resolver do it instead? |
| 487 List<SourceString> namedParameters; |
| 488 if (signature.optionalParametersAreNamed) { |
| 489 namedParameters = |
| 490 signature.optionalParameters.toList().map((e) => e.name).toList(); |
| 491 } |
| 492 Selector selector = new Selector.call(callee.name, |
| 493 caller.getLibrary(), |
| 494 signature.parameterCount, |
| 495 namedParameters); |
| 496 |
| 497 return selector.addArgumentsToList(nodes, |
| 498 list, |
| 499 callee, |
| 500 internalCompileArgument, |
| 501 compileConstant, |
| 502 compiler); |
| 503 } |
| 504 |
432 static bool sameNames(List<SourceString> first, List<SourceString> second) { | 505 static bool sameNames(List<SourceString> first, List<SourceString> second) { |
433 for (int i = 0; i < first.length; i++) { | 506 for (int i = 0; i < first.length; i++) { |
434 if (first[i] != second[i]) return false; | 507 if (first[i] != second[i]) return false; |
435 } | 508 } |
436 return true; | 509 return true; |
437 } | 510 } |
438 | 511 |
439 bool operator ==(other) { | 512 bool operator ==(other) { |
440 if (other is !Selector) return false; | 513 if (other is !Selector) return false; |
441 if (identical(this, other)) return true; | 514 if (identical(this, other)) return true; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 // bar() => foo(); // The call to 'foo' is a typed selector. | 636 // bar() => foo(); // The call to 'foo' is a typed selector. |
564 // } | 637 // } |
565 if (element.getEnclosingClass().isClosure()) { | 638 if (element.getEnclosingClass().isClosure()) { |
566 return appliesUntyped(element, compiler); | 639 return appliesUntyped(element, compiler); |
567 } | 640 } |
568 | 641 |
569 if (!mask.canHit(element, this, compiler)) return false; | 642 if (!mask.canHit(element, this, compiler)) return false; |
570 return appliesUntyped(element, compiler); | 643 return appliesUntyped(element, compiler); |
571 } | 644 } |
572 } | 645 } |
OLD | NEW |