aboutsummaryrefslogtreecommitdiff
path: root/test/functional/api/vim_spec.lua
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-11-05 02:41:44 +0300
committerZyX <kp-pav@yandex.ru>2017-11-06 01:17:39 +0300
commit7bc6de75263f58c6c4f999bc86a6454ae9f28b80 (patch)
tree7d991ea5c093c0e3bf1705fe5a8a40de9402b4f1 /test/functional/api/vim_spec.lua
parent07ec709141886c6db4f944665e07a36ef7302eb4 (diff)
downloadrneovim-7bc6de75263f58c6c4f999bc86a6454ae9f28b80.tar.gz
rneovim-7bc6de75263f58c6c4f999bc86a6454ae9f28b80.tar.bz2
rneovim-7bc6de75263f58c6c4f999bc86a6454ae9f28b80.zip
api/vim,functests: Add tests for nvim_parse_expression, fix found bugs
Diffstat (limited to 'test/functional/api/vim_spec.lua')
-rw-r--r--test/functional/api/vim_spec.lua6868
1 files changed, 6868 insertions, 0 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 6b44698638..bb7785657d 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -1,5 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
+local global_helpers = require('test.helpers')
+
local NIL = helpers.NIL
local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq
local ok, nvim_async, feed = helpers.ok, helpers.nvim_async, helpers.feed
@@ -10,6 +12,9 @@ local request = helpers.request
local meth_pcall = helpers.meth_pcall
local command = helpers.command
+local intchar2lua = global_helpers.intchar2lua
+local format_string = global_helpers.format_string
+
describe('api', function()
before_each(clear)
@@ -711,8 +716,6871 @@ describe('api', function()
end)
describe('nvim_parse_expression', function()
+ local function simplify_east_api_node(line, east_api_node)
+ if east_api_node.children then
+ for k, v in pairs(east_api_node.children) do
+ east_api_node.children[k] = simplify_east_api_node(line, v)
+ end
+ end
+ local typ = east_api_node.type
+ if typ == 'Register' then
+ typ = typ .. ('(name=%s)'):format(
+ tostring(intchar2lua(east_api_node.name)))
+ east_api_node.name = nil
+ elseif typ == 'PlainIdentifier' then
+ typ = typ .. ('(scope=%s,ident=%s)'):format(
+ tostring(intchar2lua(east_api_node.scope)), east_api_node.ident)
+ east_api_node.scope = nil
+ east_api_node.ident = nil
+ elseif typ == 'PlainKey' then
+ typ = typ .. ('(key=%s)'):format(east_api_node.ident)
+ east_api_node.ident = nil
+ elseif typ == 'Comparison' then
+ typ = typ .. ('(type=%s,inv=%u,ccs=%s)'):format(
+ east_api_node.cmp_type, east_api_node.invert and 1 or 0,
+ east_api_node.ccs_strategy)
+ east_api_node.ccs_strategy = nil
+ east_api_node.cmp_type = nil
+ east_api_node.invert = nil
+ elseif typ == 'Integer' then
+ typ = typ .. ('(val=%u)'):format(east_api_node.ivalue)
+ east_api_node.ivalue = nil
+ elseif typ == 'Float' then
+ typ = typ .. ('(val=%e)'):format(east_api_node.fvalue)
+ east_api_node.fvalue = nil
+ elseif typ == 'SingleQuotedString' or typ == 'DoubleQuotedString' then
+ typ = format_string('%s(val=%q)', typ, east_api_node.svalue)
+ east_api_node.svalue = nil
+ elseif typ == 'Option' then
+ typ = ('%s(scope=%s,ident=%s)'):format(
+ typ,
+ tostring(intchar2lua(east_api_node.scope)),
+ east_api_node.ident)
+ east_api_node.ident = nil
+ east_api_node.scope = nil
+ elseif typ == 'Environment' then
+ typ = ('%s(ident=%s)'):format(typ, east_api_node.ident)
+ east_api_node.ident = nil
+ end
+ typ = ('%s:%u:%u:%s'):format(
+ typ, east_api_node.start[1], east_api_node.start[2],
+ line:sub(east_api_node.start[2] + 1,
+ east_api_node.start[2] + 1 + east_api_node.len - 1))
+ assert(east_api_node.start[2] + east_api_node.len - 1 <= #line)
+ for k, _ in pairs(east_api_node.start) do
+ assert(({true, true})[k])
+ end
+ east_api_node.start = nil
+ east_api_node.type = nil
+ east_api_node.len = nil
+ local can_simplify = true
+ for _, _ in pairs(east_api_node) do
+ if can_simplify then can_simplify = false end
+ end
+ if can_simplify then
+ return typ
+ else
+ east_api_node[1] = typ
+ return east_api_node
+ end
+ end
+ local function simplify_east_api(line, east_api)
+ if east_api.error then
+ east_api.err = east_api.error
+ east_api.error = nil
+ east_api.err.msg = east_api.err.message
+ east_api.err.message = nil
+ end
+ if east_api.ast then
+ east_api.ast = {simplify_east_api_node(line, east_api.ast)}
+ end
+ return east_api
+ end
+ local function simplify_east_hl(line, east_hl)
+ for i, v in ipairs(east_hl) do
+ east_hl[i] = ('%s:%u:%u:%s'):format(
+ v[4],
+ v[1],
+ v[2],
+ line:sub(v[2] + 1, v[3]))
+ end
+ return east_hl
+ end
+ local function check_parsing(str, flags, exp_ast, exp_highlighting_fs)
+ if flags == 0 then
+ flags = ""
+ end
+
+ local err, msg = pcall(function()
+ local east_api = meths.parse_expression(str, flags, true)
+ local east_hl = east_api.highlight
+ east_api.highlight = nil
+ local ast = simplify_east_api(str, east_api)
+ local hls = simplify_east_hl(str, east_hl)
+ eq(exp_ast, ast)
+ if exp_highlighting_fs then
+ local exp_highlighting = {}
+ local next_col = 0
+ for i, h in ipairs(exp_highlighting_fs) do
+ exp_highlighting[i], next_col = h(next_col)
+ end
+ eq(exp_highlighting, hls)
+ end
+ end)
+ if not err then
+ msg = format_string('Error while processing test (%r, %s):\n%s',
+ str, flags, msg)
+ error(msg)
+ end
+ end
+ local function hl(group, str, shift)
+ return function(next_col)
+ local col = next_col + (shift or 0)
+ return (('%s:%u:%u:%s'):format(
+ 'NVim' .. group,
+ 0,
+ col,
+ str)), (col + #str)
+ end
+ end
+ it('works with + and @a', function()
+ check_parsing('@a', 0, {
+ ast = {
+ 'Register(name=a):0:0:@a',
+ },
+ }, {
+ hl('Register', '@a'),
+ })
+ check_parsing('+@a', 0, {
+ ast = {
+ {
+ 'UnaryPlus:0:0:+',
+ children = {
+ 'Register(name=a):0:1:@a',
+ },
+ },
+ },
+ }, {
+ hl('UnaryPlus', '+'),
+ hl('Register', '@a'),
+ })
+ check_parsing('@a+@b', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:2:+',
+ children = {
+ 'Register(name=a):0:0:@a',
+ 'Register(name=b):0:3:@b',
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('Register', '@b'),
+ })
+ check_parsing('@a+@b+@c', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:5:+',
+ children = {
+ {
+ 'BinaryPlus:0:2:+',
+ children = {
+ 'Register(name=a):0:0:@a',
+ 'Register(name=b):0:3:@b',
+ },
+ },
+ 'Register(name=c):0:6:@c',
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('Register', '@b'),
+ hl('BinaryPlus', '+'),
+ hl('Register', '@c'),
+ })
+ check_parsing('+@a+@b', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:3:+',
+ children = {
+ {
+ 'UnaryPlus:0:0:+',
+ children = {
+ 'Register(name=a):0:1:@a',
+ },
+ },
+ 'Register(name=b):0:4:@b',
+ },
+ },
+ },
+ }, {
+ hl('UnaryPlus', '+'),
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('Register', '@b'),
+ })
+ check_parsing('+@a++@b', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:3:+',
+ children = {
+ {
+ 'UnaryPlus:0:0:+',
+ children = {
+ 'Register(name=a):0:1:@a',
+ },
+ },
+ {
+ 'UnaryPlus:0:4:+',
+ children = {
+ 'Register(name=b):0:5:@b',
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('UnaryPlus', '+'),
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('UnaryPlus', '+'),
+ hl('Register', '@b'),
+ })
+ check_parsing('@a@b', 0, {
+ ast = {
+ {
+ 'OpMissing:0:2:',
+ children = {
+ 'Register(name=a):0:0:@a',
+ 'Register(name=b):0:2:@b',
+ },
+ },
+ },
+ err = {
+ arg = '@b',
+ msg = 'E15: Missing operator: %.*s',
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('InvalidRegister', '@b'),
+ })
+ check_parsing(' @a \t @b', 0, {
+ ast = {
+ {
+ 'OpMissing:0:3:',
+ children = {
+ 'Register(name=a):0:0: @a',
+ 'Register(name=b):0:3: \t @b',
+ },
+ },
+ },
+ err = {
+ arg = '@b',
+ msg = 'E15: Missing operator: %.*s',
+ },
+ }, {
+ hl('Register', '@a', 1),
+ hl('InvalidSpacing', ' \t '),
+ hl('Register', '@b'),
+ })
+ check_parsing('+', 0, {
+ ast = {
+ 'UnaryPlus:0:0:+',
+ },
+ err = {
+ arg = '',
+ msg = 'E15: Expected value, got EOC: %.*s',
+ },
+ }, {
+ hl('UnaryPlus', '+'),
+ })
+ check_parsing(' +', 0, {
+ ast = {
+ 'UnaryPlus:0:0: +',
+ },
+ err = {
+ arg = '',
+ msg = 'E15: Expected value, got EOC: %.*s',
+ },
+ }, {
+ hl('UnaryPlus', '+', 1),
+ })
+ check_parsing('@a+ ', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:2:+',
+ children = {
+ 'Register(name=a):0:0:@a',
+ },
+ },
+ },
+ err = {
+ arg = '',
+ msg = 'E15: Expected value, got EOC: %.*s',
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ })
+ end)
+ it('works with @a, + and parenthesis', function()
+ check_parsing('(@a)', 0, {
+ ast = {
+ {
+ 'Nested:0:0:(',
+ children = {
+ 'Register(name=a):0:1:@a',
+ },
+ },
+ },
+ }, {
+ hl('NestingParenthesis', '('),
+ hl('Register', '@a'),
+ hl('NestingParenthesis', ')'),
+ })
+ check_parsing('()', 0, {
+ ast = {
+ {
+ 'Nested:0:0:(',
+ children = {
+ 'Missing:0:1:',
+ },
+ },
+ },
+ err = {
+ arg = ')',
+ msg = 'E15: Expected value, got parenthesis: %.*s',
+ },
+ }, {
+ hl('NestingParenthesis', '('),
+ hl('InvalidNestingParenthesis', ')'),
+ })
+ check_parsing(')', 0, {
+ ast = {
+ {
+ 'Nested:0:0:',
+ children = {
+ 'Missing:0:0:',
+ },
+ },
+ },
+ err = {
+ arg = ')',
+ msg = 'E15: Expected value, got parenthesis: %.*s',
+ },
+ }, {
+ hl('InvalidNestingParenthesis', ')'),
+ })
+ check_parsing('+)', 0, {
+ ast = {
+ {
+ 'Nested:0:1:',
+ children = {
+ {
+ 'UnaryPlus:0:0:+',
+ children = {
+ 'Missing:0:1:',
+ },
+ },
+ },
+ },
+ },
+ err = {
+ arg = ')',
+ msg = 'E15: Expected value, got parenthesis: %.*s',
+ },
+ }, {
+ hl('UnaryPlus', '+'),
+ hl('InvalidNestingParenthesis', ')'),
+ })
+ check_parsing('+@a(@b)', 0, {
+ ast = {
+ {
+ 'UnaryPlus:0:0:+',
+ children = {
+ {
+ 'Call:0:3:(',
+ children = {
+ 'Register(name=a):0:1:@a',
+ 'Register(name=b):0:4:@b',
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('UnaryPlus', '+'),
+ hl('Register', '@a'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@b'),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a+@b(@c)', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:2:+',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Call:0:5:(',
+ children = {
+ 'Register(name=b):0:3:@b',
+ 'Register(name=c):0:6:@c',
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('Register', '@b'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@c'),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a()', 0, {
+ ast = {
+ {
+ 'Call:0:2:(',
+ children = {
+ 'Register(name=a):0:0:@a',
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('CallingParenthesis', '('),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a ()', 0, {
+ ast = {
+ {
+ 'OpMissing:0:2:',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Nested:0:2: (',
+ children = {
+ 'Missing:0:4:',
+ },
+ },
+ },
+ },
+ },
+ err = {
+ arg = '()',
+ msg = 'E15: Missing operator: %.*s',
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('InvalidSpacing', ' '),
+ hl('NestingParenthesis', '('),
+ hl('InvalidNestingParenthesis', ')'),
+ })
+ check_parsing(
+ '@a + (@b)', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:2: +',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Nested:0:4: (',
+ children = {
+ 'Register(name=b):0:6:@b',
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+', 1),
+ hl('NestingParenthesis', '(', 1),
+ hl('Register', '@b'),
+ hl('NestingParenthesis', ')'),
+ })
+ check_parsing(
+ '@a + (+@b)', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:2: +',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Nested:0:4: (',
+ children = {
+ {
+ 'UnaryPlus:0:6:+',
+ children = {
+ 'Register(name=b):0:7:@b',
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+', 1),
+ hl('NestingParenthesis', '(', 1),
+ hl('UnaryPlus', '+'),
+ hl('Register', '@b'),
+ hl('NestingParenthesis', ')'),
+ })
+ check_parsing(
+ '@a + (@b + @c)', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:2: +',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Nested:0:4: (',
+ children = {
+ {
+ 'BinaryPlus:0:8: +',
+ children = {
+ 'Register(name=b):0:6:@b',
+ 'Register(name=c):0:10: @c',
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+', 1),
+ hl('NestingParenthesis', '(', 1),
+ hl('Register', '@b'),
+ hl('BinaryPlus', '+', 1),
+ hl('Register', '@c', 1),
+ hl('NestingParenthesis', ')'),
+ })
+ check_parsing('(@a)+@b', 0, {
+ ast = {
+ {
+ 'BinaryPlus:0:4:+',
+ children = {
+ {
+ 'Nested:0:0:(',
+ children = {
+ 'Register(name=a):0:1:@a',
+ },
+ },
+ 'Register(name=b):0:5:@b',
+ },
+ },
+ },
+ }, {
+ hl('NestingParenthesis', '('),
+ hl('Register', '@a'),
+ hl('NestingParenthesis', ')'),
+ hl('BinaryPlus', '+'),
+ hl('Register', '@b'),
+ })
+ check_parsing('@a+(@b)(@c)', 0, {
+ -- 01234567890
+ ast = {
+ {
+ 'BinaryPlus:0:2:+',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Call:0:7:(',
+ children = {
+ {
+ 'Nested:0:3:(',
+ children = { 'Register(name=b):0:4:@b' },
+ },
+ 'Register(name=c):0:8:@c',
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('NestingParenthesis', '('),
+ hl('Register', '@b'),
+ hl('NestingParenthesis', ')'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@c'),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a+((@b))(@c)', 0, {
+ -- 01234567890123456890123456789
+ -- 0 1 2
+ ast = {
+ {
+ 'BinaryPlus:0:2:+',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Call:0:9:(',
+ children = {
+ {
+ 'Nested:0:3:(',
+ children = {
+ {
+ 'Nested:0:4:(',
+ children = { 'Register(name=b):0:5:@b' }
+ },
+ },
+ },
+ 'Register(name=c):0:10:@c',
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('NestingParenthesis', '('),
+ hl('NestingParenthesis', '('),
+ hl('Register', '@b'),
+ hl('NestingParenthesis', ')'),
+ hl('NestingParenthesis', ')'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@c'),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a+((@b))+@c', 0, {
+ -- 01234567890123456890123456789
+ -- 0 1 2
+ ast = {
+ {
+ 'BinaryPlus:0:9:+',
+ children = {
+ {
+ 'BinaryPlus:0:2:+',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Nested:0:3:(',
+ children = {
+ {
+ 'Nested:0:4:(',
+ children = { 'Register(name=b):0:5:@b' }
+ },
+ },
+ },
+ },
+ },
+ 'Register(name=c):0:10:@c',
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+'),
+ hl('NestingParenthesis', '('),
+ hl('NestingParenthesis', '('),
+ hl('Register', '@b'),
+ hl('NestingParenthesis', ')'),
+ hl('NestingParenthesis', ')'),
+ hl('BinaryPlus', '+'),
+ hl('Register', '@c'),
+ })
+ check_parsing(
+ '@a + (@b + @c) + @d(@e) + (+@f) + ((+@g(@h))(@j)(@k))(@l)', 0, {--[[
+ | | | | | | | | || | | || | | ||| || || || ||
+ 000000000011111111112222222222333333333344444444445555555
+ 012345678901234567890123456789012345678901234567890123456
+ ]]
+ ast = {{
+ 'BinaryPlus:0:31: +',
+ children = {
+ {
+ 'BinaryPlus:0:23: +',
+ children = {
+ {
+ 'BinaryPlus:0:14: +',
+ children = {
+ {
+ 'BinaryPlus:0:2: +',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Nested:0:4: (',
+ children = {
+ {
+ 'BinaryPlus:0:8: +',
+ children = {
+ 'Register(name=b):0:6:@b',
+ 'Register(name=c):0:10: @c',
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ 'Call:0:19:(',
+ children = {
+ 'Register(name=d):0:16: @d',
+ 'Register(name=e):0:20:@e',
+ },
+ },
+ },
+ },
+ {
+ 'Nested:0:25: (',
+ children = {
+ {
+ 'UnaryPlus:0:27:+',
+ children = {
+ 'Register(name=f):0:28:@f',
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ 'Call:0:53:(',
+ children = {
+ {
+ 'Nested:0:33: (',
+ children = {
+ {
+ 'Call:0:48:(',
+ children = {
+ {
+ 'Call:0:44:(',
+ children = {
+ {
+ 'Nested:0:35:(',
+ children = {
+ {
+ 'UnaryPlus:0:36:+',
+ children = {
+ {
+ 'Call:0:39:(',
+ children = {
+ 'Register(name=g):0:37:@g',
+ 'Register(name=h):0:40:@h',
+ },
+ },
+ },
+ },
+ },
+ },
+ 'Register(name=j):0:45:@j',
+ },
+ },
+ 'Register(name=k):0:49:@k',
+ },
+ },
+ },
+ },
+ 'Register(name=l):0:54:@l',
+ },
+ },
+ },
+ }},
+ }, {
+ hl('Register', '@a'),
+ hl('BinaryPlus', '+', 1),
+ hl('NestingParenthesis', '(', 1),
+ hl('Register', '@b'),
+ hl('BinaryPlus', '+', 1),
+ hl('Register', '@c', 1),
+ hl('NestingParenthesis', ')'),
+ hl('BinaryPlus', '+', 1),
+ hl('Register', '@d', 1),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@e'),
+ hl('CallingParenthesis', ')'),
+ hl('BinaryPlus', '+', 1),
+ hl('NestingParenthesis', '(', 1),
+ hl('UnaryPlus', '+'),
+ hl('Register', '@f'),
+ hl('NestingParenthesis', ')'),
+ hl('BinaryPlus', '+', 1),
+ hl('NestingParenthesis', '(', 1),
+ hl('NestingParenthesis', '('),
+ hl('UnaryPlus', '+'),
+ hl('Register', '@g'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@h'),
+ hl('CallingParenthesis', ')'),
+ hl('NestingParenthesis', ')'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@j'),
+ hl('CallingParenthesis', ')'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@k'),
+ hl('CallingParenthesis', ')'),
+ hl('NestingParenthesis', ')'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@l'),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a)', 0, {
+ -- 012
+ ast = {
+ {
+ 'Nested:0:2:',
+ children = {
+ 'Register(name=a):0:0:@a',
+ },
+ },
+ },
+ err = {
+ arg = ')',
+ msg = 'E15: Unexpected closing parenthesis: %.*s',
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('InvalidNestingParenthesis', ')'),
+ })
+ check_parsing('(@a', 0, {
+ -- 012
+ ast = {
+ {
+ 'Nested:0:0:(',
+ children = {
+ 'Register(name=a):0:1:@a',
+ },
+ },
+ },
+ err = {
+ arg = '(@a',
+ msg = 'E110: Missing closing parenthesis for nested expression: %.*s',
+ },
+ }, {
+ hl('NestingParenthesis', '('),
+ hl('Register', '@a'),
+ })
+ check_parsing('@a(@b', 0, {
+ -- 01234
+ ast = {
+ {
+ 'Call:0:2:(',
+ children = {
+ 'Register(name=a):0:0:@a',
+ 'Register(name=b):0:3:@b',
+ },
+ },
+ },
+ err = {
+ arg = '(@b',
+ msg = 'E116: Missing closing parenthesis for function call: %.*s',
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@b'),
+ })
+ check_parsing('@a(@b, @c, @d, @e)', 0, {
+ -- 012345678901234567
+ -- 0 1
+ ast = {
+ {
+ 'Call:0:2:(',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Comma:0:5:,',
+ children = {
+ 'Register(name=b):0:3:@b',
+ {
+ 'Comma:0:9:,',
+ children = {
+ 'Register(name=c):0:6: @c',
+ {
+ 'Comma:0:13:,',
+ children = {
+ 'Register(name=d):0:10: @d',
+ 'Register(name=e):0:14: @e',
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@b'),
+ hl('Comma', ','),
+ hl('Register', '@c', 1),
+ hl('Comma', ','),
+ hl('Register', '@d', 1),
+ hl('Comma', ','),
+ hl('Register', '@e', 1),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a(@b(@c))', 0, {
+ -- 01234567890123456789012345678901234567
+ -- 0 1 2 3
+ ast = {
+ {
+ 'Call:0:2:(',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Call:0:5:(',
+ children = {
+ 'Register(name=b):0:3:@b',
+ 'Register(name=c):0:6:@c',
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@b'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@c'),
+ hl('CallingParenthesis', ')'),
+ hl('CallingParenthesis', ')'),
+ })
+ check_parsing('@a(@b(@c(@d(@e), @f(@g(@h), @i(@j)))))', 0, {
+ -- 01234567890123456789012345678901234567
+ -- 0 1 2 3
+ ast = {
+ {
+ 'Call:0:2:(',
+ children = {
+ 'Register(name=a):0:0:@a',
+ {
+ 'Call:0:5:(',
+ children = {
+ 'Register(name=b):0:3:@b',
+ {
+ 'Call:0:8:(',
+ children = {
+ 'Register(name=c):0:6:@c',
+ {
+ 'Comma:0:15:,',
+ children = {
+ {
+ 'Call:0:11:(',
+ children = {
+ 'Register(name=d):0:9:@d',
+ 'Register(name=e):0:12:@e',
+ },
+ },
+ {
+ 'Call:0:19:(',
+ children = {
+ 'Register(name=f):0:16: @f',
+ {
+ 'Comma:0:26:,',
+ children = {
+ {
+ 'Call:0:22:(',
+ children = {
+ 'Register(name=g):0:20:@g',
+ 'Register(name=h):0:23:@h',
+ },
+ },
+ {
+ 'Call:0:30:(',
+ children = {
+ 'Register(name=i):0:27: @i',
+ 'Register(name=j):0:31:@j',
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }, {
+ hl('Register', '@a'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@b'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@c'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@d'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@e'),
+ hl('CallingParenthesis', ')'),
+ hl('Comma', ','),
+ hl('Register', '@f', 1),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@g'),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@h'),
+ hl('CallingParenthesis', ')'),
+ hl('Comma', ','),
+ hl('Register', '@i', 1),
+ hl('CallingParenthesis', '('),
+ hl('Register', '@j'),
+ hl('CallingParenthesis', ')'),
+ hl('CallingParenthesis', ')'),
+ hl('CallingParenthesis', ')'),
+ hl('CallingParenthesis', ')'),
+ hl('CallingParenthesis', ')'),
+ })
+ end)
+ it('works with variable names, including curly braces ones', function()
+ check_parsing('var', 0, {
+ ast = {
+ 'PlainIdentifier(scope=0,ident=var):0:0:var',
+ },
+ }, {
+ hl('IdentifierName', 'var'),
+ })
+ check_parsing('g:var', 0, {
+ ast = {
+ 'PlainIdentifier(scope=g,ident=var):0:0:g:var',
+ },
+ }, {
+ hl('IdentifierScope', 'g'),
+ hl('IdentifierScopeDelimiter', ':'),
+ hl('IdentifierName', 'var'),
+ })
+ check_parsing('g:', 0, {
+ ast = {
+ 'PlainIdentifier(scope=g,ident=):0:0:g:',
+ },
+ }, {
+ hl('IdentifierScope', 'g'),
+ hl('IdentifierScopeDelimiter', ':'),
+ })
+ check_parsing('{a}', 0, {
+ -- 012
+ ast = {
+ {
+ 'CurlyBracesIdentifier:0:0:{',
+ children = {
+ 'PlainIdentifier(scope=0,ident=a):0:1:a',
+ },
+ },
+ },
+ }, {
+ hl('Curly', '{'),
+ hl('IdentifierName', 'a'),
+ hl('Curly', '}'),
+ })
+ check_parsing('{a:b}', 0, {
+ -- 012
+ ast = {
+ {
+ 'CurlyBracesIdentifier:0:0: