Mercurial > vim
changeset 8635:3a38d465f731 v7.4.1607
commit https://github.com/vim/vim/commit/f0e86a0dbddc18568910e9e4aaae0cd88ca8087a
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Mar 19 19:38:12 2016 +0100
patch 7.4.1607
Problem: Comparing a function that exists on two dicts is not backwards
compatible. (Thinca)
Solution: Only compare the function, not what the partial adds.
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 19 Mar 2016 19:45:05 +0100 |
parents | 416fa8415ada |
children | eb6ce9995994 |
files | src/eval.c src/testdir/test_alot.vim src/testdir/test_expr.vim src/version.c |
diffstat | 4 files changed, 45 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -4555,33 +4555,14 @@ eval4(char_u **arg, typval_T *rettv, int else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL || var2.v_type == VAR_PARTIAL) { - if (rettv->v_type != var2.v_type - || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) - { - if (rettv->v_type != var2.v_type) - EMSG(_("E693: Can only compare Funcref with Funcref")); - else - EMSG(_("E694: Invalid operation for Funcrefs")); + if (type != TYPE_EQUAL && type != TYPE_NEQUAL) + { + EMSG(_("E694: Invalid operation for Funcrefs")); clear_tv(rettv); clear_tv(&var2); return FAIL; } - else if (rettv->v_type == VAR_PARTIAL) - { - /* Partials are only equal when identical. */ - n1 = rettv->vval.v_partial != NULL - && rettv->vval.v_partial == var2.vval.v_partial; - } - else - { - /* Compare two Funcrefs for being equal or unequal. */ - if (rettv->vval.v_string == NULL - || var2.vval.v_string == NULL) - n1 = FALSE; - else - n1 = STRCMP(rettv->vval.v_string, - var2.vval.v_string) == 0; - } + n1 = tv_equal(rettv, &var2, FALSE, FALSE); if (type == TYPE_NEQUAL) n1 = !n1; } @@ -6203,6 +6184,19 @@ tv_equal( static int recursive_cnt = 0; /* catch recursive loops */ int r; + /* For VAR_FUNC and VAR_PARTIAL only compare the function name. */ + if ((tv1->v_type == VAR_FUNC + || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) + && (tv2->v_type == VAR_FUNC + || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) + { + s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string + : tv1->vval.v_partial->pt_name; + s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string + : tv2->vval.v_partial->pt_name; + return (s1 != NULL && s2 != NULL && STRCMP(s1, s2) == 0); + } + if (tv1->v_type != tv2->v_type) return FALSE; @@ -6234,15 +6228,6 @@ tv_equal( --recursive_cnt; return r; - case VAR_FUNC: - return (tv1->vval.v_string != NULL - && tv2->vval.v_string != NULL - && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); - - case VAR_PARTIAL: - return tv1->vval.v_partial != NULL - && tv1->vval.v_partial == tv2->vval.v_partial; - case VAR_NUMBER: return tv1->vval.v_number == tv2->vval.v_number; @@ -6266,6 +6251,8 @@ tv_equal( #ifdef FEAT_JOB_CHANNEL return tv1->vval.v_channel == tv2->vval.v_channel; #endif + case VAR_FUNC: + case VAR_PARTIAL: case VAR_UNKNOWN: break; }
--- a/src/testdir/test_alot.vim +++ b/src/testdir/test_alot.vim @@ -5,6 +5,7 @@ source test_assign.vim source test_cursor_func.vim source test_delete.vim source test_ex_undo.vim +source test_expr.vim source test_expand.vim source test_feedkeys.vim source test_file_perm.vim
new file mode 100644 --- /dev/null +++ b/src/testdir/test_expr.vim @@ -0,0 +1,23 @@ +" Tests for expressions. + +func Test_equal() + let base = {} + func base.method() + return 1 + endfunc + func base.other() dict + return 1 + endfunc + let instance = copy(base) + call assert_true(base.method == instance.method) + call assert_true([base.method] == [instance.method]) + call assert_true(base.other == instance.other) + call assert_true([base.other] == [instance.other]) + + call assert_false(base.method == base.other) + call assert_false([base.method] == [base.other]) + call assert_false(base.method == instance.other) + call assert_false([base.method] == [instance.other]) + + call assert_fails('echo base.method > instance.method') +endfunc