diff options
-rw-r--r-- | src/nvim/viml/parser/expressions.c | 4 | ||||
-rw-r--r-- | test/unit/viml/expressions/parser_spec.lua | 73 |
2 files changed, 76 insertions, 1 deletions
diff --git a/src/nvim/viml/parser/expressions.c b/src/nvim/viml/parser/expressions.c index 4babf4312c..fffae8833d 100644 --- a/src/nvim/viml/parser/expressions.c +++ b/src/nvim/viml/parser/expressions.c @@ -1691,8 +1691,10 @@ viml_pexpr_parse_invalid_comma: SELECT_FIGURE_BRACE_TYPE(*eastnode_p, DictLiteral, Dict); break; } else if (eastnode_type == kExprNodeDictLiteral - || eastnode_type == kExprNodeComma) { + || eastnode_type == kExprNodeSubscript) { break; + } else if (eastnode_type == kExprNodeColon) { + goto viml_pexpr_parse_invalid_colon; } else if (eastnode_lvl >= kEOpLvlTernaryValue) { // Do nothing } else if (eastnode_lvl > kEOpLvlComma) { diff --git a/test/unit/viml/expressions/parser_spec.lua b/test/unit/viml/expressions/parser_spec.lua index 8d96c29db7..46e3328184 100644 --- a/test/unit/viml/expressions/parser_spec.lua +++ b/test/unit/viml/expressions/parser_spec.lua @@ -2700,6 +2700,42 @@ describe('Expressions parser', function() hl('Identifier', 'b', 1), hl('Curly', '}'), }) + check_parsing('{a : b : c}', 0, { + -- 01234567890 + -- 0 1 + ast = { + { + 'DictLiteral(-di):0:0:{', + children = { + { + 'Colon:0:2: :', + children = { + 'PlainIdentifier(scope=0,ident=a):0:1:a', + { + 'Colon:0:6: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:4: b', + 'PlainIdentifier(scope=0,ident=c):0:8: c', + }, + }, + }, + }, + }, + }, + }, + err = { + arg = ': c}', + msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', + }, + }, { + hl('Dict', '{'), + hl('Identifier', 'a'), + hl('Colon', ':', 1), + hl('Identifier', 'b', 1), + hl('InvalidColon', ':', 1), + hl('Identifier', 'c', 1), + hl('Dict', '}'), + }) end) itp('works with ternary operator', function() check_parsing('a ? b : c', 0, { @@ -3348,6 +3384,43 @@ describe('Expressions parser', function() hl('TernaryColon', ':'), hl('Identifier', 'h'), }) + check_parsing('a ? b : c : d', 0, { + -- 0123456789012 + -- 0 1 + ast = { + { + 'Colon:0:9: :', + children = { + { + 'Ternary:0:1: ?', + children = { + 'PlainIdentifier(scope=0,ident=a):0:0:a', + { + 'TernaryValue:0:5: :', + children = { + 'PlainIdentifier(scope=0,ident=b):0:3: b', + 'PlainIdentifier(scope=0,ident=c):0:7: c', + }, + }, + }, + }, + 'PlainIdentifier(scope=0,ident=d):0:11: d', + }, + }, + }, + err = { + arg = ': d', + msg = 'E15: Colon outside of dictionary or ternary operator: %.*s', + }, + }, { + hl('Identifier', 'a'), + hl('Ternary', '?', 1), + hl('Identifier', 'b', 1), + hl('TernaryColon', ':', 1), + hl('Identifier', 'c', 1), + hl('InvalidColon', ':', 1), + hl('Identifier', 'd', 1), + }) end) itp('works with comparison operators', function() check_parsing('a == b', 0, { |