Mirror of the Vim source from https://github.com/vim/vim
Revisión | 6af18c69c59d61ce6bd7bfc0fba5a57d8fce700f (tree) |
---|---|
Tiempo | 2022-01-17 06:00:04 |
Autor | Bram Moolenaar <Bram@vim....> |
Commiter | Bram Moolenaar |
patch 8.2.4116: Vim9: cannot use a method with a complex expression in :def
Commit: https://github.com/vim/vim/commit/c73499351aef8b611b13c70ef8706a7e98df67a8
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 16 20:59:39 2022 +0000
@@ -3140,7 +3140,6 @@ | ||
3140 | 3140 | CheckDefAndScriptSuccess(lines) |
3141 | 3141 | |
3142 | 3142 | lines =<< trim END |
3143 | - vim9script | |
3144 | 3143 | def SetNumber(n: number) |
3145 | 3144 | g:number = n |
3146 | 3145 | enddef |
@@ -3166,7 +3165,7 @@ | ||
3166 | 3165 | |
3167 | 3166 | unlet g:number |
3168 | 3167 | END |
3169 | - CheckScriptSuccess(lines) # TODO: CheckDefAndScriptSuccess() | |
3168 | + CheckDefAndScriptSuccess(lines) | |
3170 | 3169 | |
3171 | 3170 | lines =<< trim END |
3172 | 3171 | def RetVoid() |
@@ -751,6 +751,8 @@ | ||
751 | 751 | static int included_patches[] = |
752 | 752 | { /* Add new patch number below this line */ |
753 | 753 | /**/ |
754 | + 4116, | |
755 | +/**/ | |
754 | 756 | 4115, |
755 | 757 | /**/ |
756 | 758 | 4114, |
@@ -1583,6 +1583,8 @@ | ||
1583 | 1583 | return ret; |
1584 | 1584 | } |
1585 | 1585 | |
1586 | +static int compile_expr8(char_u **arg, cctx_T *cctx, ppconst_T *ppconst); | |
1587 | + | |
1586 | 1588 | /* |
1587 | 1589 | * Compile whatever comes after "name" or "name()". |
1588 | 1590 | * Advances "*arg" only when something was recognized. |
@@ -1651,13 +1653,15 @@ | ||
1651 | 1653 | } |
1652 | 1654 | else if (*p == '-' && p[1] == '>') |
1653 | 1655 | { |
1654 | - char_u *pstart = p; | |
1656 | + char_u *pstart = p; | |
1657 | + int alt; | |
1658 | + char_u *paren; | |
1655 | 1659 | |
1660 | + // something->method() | |
1656 | 1661 | if (generate_ppconst(cctx, ppconst) == FAIL) |
1657 | 1662 | return FAIL; |
1658 | 1663 | ppconst->pp_is_const = FALSE; |
1659 | 1664 | |
1660 | - // something->method() | |
1661 | 1665 | // Apply the '!', '-' and '+' first: |
1662 | 1666 | // -1.0->func() works like (-1.0)->func() |
1663 | 1667 | if (compile_leader(cctx, TRUE, start_leader, end_leader) == FAIL) |
@@ -1666,7 +1670,48 @@ | ||
1666 | 1670 | p += 2; |
1667 | 1671 | *arg = skipwhite(p); |
1668 | 1672 | // No line break supported right after "->". |
1673 | + | |
1674 | + // Three alternatives handled here: | |
1675 | + // 1. "base->name(" only a name, use compile_call() | |
1676 | + // 2. "base->(expr)(" evaluate "expr", then use PCALL | |
1677 | + // 3. "base->expr(" Same, find the end of "expr" by "(" | |
1669 | 1678 | if (**arg == '(') |
1679 | + alt = 2; | |
1680 | + else | |
1681 | + { | |
1682 | + // alternative 1 or 3 | |
1683 | + p = *arg; | |
1684 | + if (!eval_isnamec1(*p)) | |
1685 | + { | |
1686 | + semsg(_(e_trailing_characters_str), pstart); | |
1687 | + return FAIL; | |
1688 | + } | |
1689 | + if (ASCII_ISALPHA(*p) && p[1] == ':') | |
1690 | + p += 2; | |
1691 | + for ( ; eval_isnamec(*p); ++p) | |
1692 | + ; | |
1693 | + if (*p == '(') | |
1694 | + { | |
1695 | + // alternative 1 | |
1696 | + alt = 1; | |
1697 | + if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL) | |
1698 | + return FAIL; | |
1699 | + } | |
1700 | + else | |
1701 | + { | |
1702 | + // Must be alternative 3, find the "(". Only works within | |
1703 | + // one line. | |
1704 | + alt = 3; | |
1705 | + paren = vim_strchr(p, '('); | |
1706 | + if (paren == NULL) | |
1707 | + { | |
1708 | + semsg(_(e_missing_parenthesis_str), *arg); | |
1709 | + return FAIL; | |
1710 | + } | |
1711 | + } | |
1712 | + } | |
1713 | + | |
1714 | + if (alt != 1) | |
1670 | 1715 | { |
1671 | 1716 | int argcount = 1; |
1672 | 1717 | garray_T *stack = &cctx->ctx_type_stack; |
@@ -1676,12 +1721,27 @@ | ||
1676 | 1721 | int expr_isn_end; |
1677 | 1722 | int arg_isn_count; |
1678 | 1723 | |
1679 | - // Funcref call: list->(Refs[2])(arg) | |
1680 | - // or lambda: list->((arg) => expr)(arg) | |
1681 | - // | |
1682 | - // Fist compile the function expression. | |
1683 | - if (compile_parenthesis(arg, cctx, ppconst) == FAIL) | |
1684 | - return FAIL; | |
1724 | + if (alt == 2) | |
1725 | + { | |
1726 | + // Funcref call: list->(Refs[2])(arg) | |
1727 | + // or lambda: list->((arg) => expr)(arg) | |
1728 | + // | |
1729 | + // Fist compile the function expression. | |
1730 | + if (compile_parenthesis(arg, cctx, ppconst) == FAIL) | |
1731 | + return FAIL; | |
1732 | + } | |
1733 | + else | |
1734 | + { | |
1735 | + *paren = NUL; | |
1736 | + if (compile_expr8(arg, cctx, ppconst) == FAIL | |
1737 | + || *skipwhite(*arg) != NUL) | |
1738 | + { | |
1739 | + *paren = '('; | |
1740 | + semsg(_(e_invalid_expression_str), pstart); | |
1741 | + return FAIL; | |
1742 | + } | |
1743 | + *paren = '('; | |
1744 | + } | |
1685 | 1745 | |
1686 | 1746 | // Remember the next instruction index, where the instructions |
1687 | 1747 | // for arguments are being written. |
@@ -1742,27 +1802,7 @@ | ||
1742 | 1802 | if (generate_PCALL(cctx, argcount, p - 2, type, FALSE) == FAIL) |
1743 | 1803 | return FAIL; |
1744 | 1804 | } |
1745 | - else | |
1746 | - { | |
1747 | - // method call: list->method() | |
1748 | - p = *arg; | |
1749 | - if (!eval_isnamec1(*p)) | |
1750 | - { | |
1751 | - semsg(_(e_trailing_characters_str), pstart); | |
1752 | - return FAIL; | |
1753 | - } | |
1754 | - if (ASCII_ISALPHA(*p) && p[1] == ':') | |
1755 | - p += 2; | |
1756 | - for ( ; eval_isnamec(*p); ++p) | |
1757 | - ; | |
1758 | - if (*p != '(') | |
1759 | - { | |
1760 | - semsg(_(e_missing_parenthesis_str), *arg); | |
1761 | - return FAIL; | |
1762 | - } | |
1763 | - if (compile_call(arg, p - *arg, cctx, ppconst, 1) == FAIL) | |
1764 | - return FAIL; | |
1765 | - } | |
1805 | + | |
1766 | 1806 | if (keeping_dict) |
1767 | 1807 | { |
1768 | 1808 | keeping_dict = FALSE; |