(StarlarkThread.Frame fr, CallExpression call)
| 666 | } |
| 667 | |
| 668 | private static Object evalCall(StarlarkThread.Frame fr, CallExpression call) |
| 669 | throws EvalException, InterruptedException { |
| 670 | fr.thread.checkInterrupt(); |
| 671 | |
| 672 | Object fn = eval(fr, call.getFunction()); |
| 673 | |
| 674 | // Starlark arguments are ordered: positionals < keywords < *args < **kwargs. |
| 675 | // |
| 676 | // This is stricter than Python2, which doesn't constrain keywords wrt *args, |
| 677 | // but this ensures that the effects of evaluation of Starlark arguments occur |
| 678 | // in source order. |
| 679 | // |
| 680 | // Starlark does not support Python3's multiple *args and **kwargs |
| 681 | // nor freer ordering, such as f(a, *list, *list, **dict, **dict, b=1). |
| 682 | // Supporting it would complicate a compiler, and produce effects out of order. |
| 683 | // Also, Python's argument ordering rules are complex and the errors sometimes cryptic. |
| 684 | |
| 685 | // StarStar and Star args are guaranteed to be last, if they occur. |
| 686 | ImmutableList<Argument> arguments = call.getArguments(); |
| 687 | int numNonStarArgs = arguments.size(); |
| 688 | Argument.StarStar starstar = null; |
| 689 | if (numNonStarArgs > 0 && arguments.get(numNonStarArgs - 1) instanceof Argument.StarStar) { |
| 690 | starstar = (Argument.StarStar) arguments.get(numNonStarArgs - 1); |
| 691 | numNonStarArgs--; |
| 692 | } |
| 693 | Argument.Star star = null; |
| 694 | if (numNonStarArgs > 0 && arguments.get(numNonStarArgs - 1) instanceof Argument.Star) { |
| 695 | star = (Argument.Star) arguments.get(numNonStarArgs - 1); |
| 696 | numNonStarArgs--; |
| 697 | } |
| 698 | // Inv: numNonStarArgs = |positional| + |named| |
| 699 | |
| 700 | StarlarkCallable callable = Starlark.getStarlarkCallable(fr.thread, fn); |
| 701 | int numPositionalArguments = call.getNumPositionalArguments(); |
| 702 | |
| 703 | if (numNonStarArgs == numPositionalArguments // no named args |
| 704 | && star == null |
| 705 | && starstar == null) { |
| 706 | return evalPositionalOnlyCall(fr, callable, call, arguments, numPositionalArguments); |
| 707 | } |
| 708 | |
| 709 | StarlarkCallable.ArgumentProcessor argumentProcessor = |
| 710 | Starlark.requestArgumentProcessor(fr.thread, callable); |
| 711 | |
| 712 | // Set the location of the call before the first calls to argumentProcessor.add*Arg(). |
| 713 | Location loc = call.getLparenLocation(); |
| 714 | fr.setLocation(loc); |
| 715 | |
| 716 | // f(expr) -- positional args |
| 717 | int i; |
| 718 | for (i = 0; i < numPositionalArguments; i++) { |
| 719 | Argument arg = arguments.get(i); |
| 720 | argumentProcessor.addPositionalArg(eval(fr, arg.getValue())); |
| 721 | } |
| 722 | |
| 723 | // f(id=expr) -- named args |
| 724 | for (; i < numNonStarArgs; i++) { |
| 725 | Argument arg = arguments.get(i); |
no test coverage detected