local core = require 'core.document-symbol' local files = require 'files' local define = require 'proto.define' rawset(_G, 'TEST', true) local EXISTS = {} local function eq(a, b) if a == EXISTS and b ~= nil then return true end local tp1, tp2 = type(a), type(b) if tp1 ~= tp2 then return false end if tp1 == 'table' then local mark = {} for k in pairs(a) do if not eq(a[k], b[k]) then return false end mark[k] = true end for k in pairs(b) do if not mark[k] then return false end end return true end return a == b end local function checkArcoss(symbols) local lastFinish = 0 for _, symbol in ipairs(symbols) do assert(symbol.range[1] <= symbol.selectionRange[1]) assert(symbol.range[2] >= symbol.selectionRange[2]) assert(symbol.range[2] > lastFinish) lastFinish = symbol.range[2] if symbol.children then checkArcoss(symbol.children) end end end ---@diagnostic disable: await-in-sync function TEST(script) return function (expect) files.setText('', script) local result = core('') assert(eq(expect, result)) checkArcoss(result) files.remove('') end end TEST [[ A = 1 ]] { [1] = { name = 'A', detail = 'global number = 1', kind = define.SymbolKind.Class, range = {0, 5}, selectionRange = {0, 1}, } } TEST [[ local function f() end ]] { [1] = { name = 'f', detail = 'function ()', kind = define.SymbolKind.Function, range = {6, 10003}, selectionRange = {15, 16}, valueRange = {6, 10003}, } } TEST [[ function f() end ]] { [1] = { name = 'f', detail = 'function ()', kind = define.SymbolKind.Function, range = {0, 10003}, selectionRange = {9, 10}, valueRange = {0, 10003}, } } TEST [[ return function () end ]] { [1] = { name = '', detail = 'return function ()', kind = define.SymbolKind.Function, range = {7, 10003}, selectionRange = {7, 15}, valueRange = {7, 10003}, } } TEST [[ f = function () end ]] { [1] = { name = 'f', detail = 'function ()', kind = define.SymbolKind.Function, range = {0, 10003}, selectionRange = {0, 1}, valueRange = {4, 10003}, } } TEST [[ local f = function () end ]] { [1] = { name = 'f', detail = 'function ()', kind = define.SymbolKind.Function, range = {6, 10003}, selectionRange = {6, 7}, valueRange = {10, 10003}, } } TEST [[ function mt:add() end ]] { [1] = { name = 'mt:add', detail = 'function ()', kind = define.SymbolKind.Method, range = {0, 10003}, selectionRange = {9, 15}, valueRange = {0, 10003}, } } TEST [[ function A() function A1() end function A2() end end function B() end ]] { [1] = { name = 'A', detail = 'function ()', kind = define.SymbolKind.Function, range = {0, 50003}, selectionRange = {9, 10}, valueRange = {0, 50003}, children = { [1] = { name = 'A1', detail = 'function ()', kind = define.SymbolKind.Function, range = {10004, 20007}, selectionRange = {10013, 10015}, valueRange = {10004, 20007}, }, [2] = { name = 'A2', detail = 'function ()', kind = define.SymbolKind.Function, range = {30004, 40007}, selectionRange = {30013, 30015}, valueRange = {30004, 40007}, }, }, }, [2] = { name = 'B', detail = 'function ()', kind = define.SymbolKind.Function, range = {60000, 70003}, selectionRange = {60009, 60010}, valueRange = {60000, 70003}, }, } TEST [[ local x = 1 local function f() local x = 'x' local y = {} --= 1 end local y = true local z ]] { [1] = { name = 'x', detail = 'local number = 1', kind = define.SymbolKind.Variable, range = {6, 11}, selectionRange = {6, 7}, }, [2] = { name = 'f', detail = 'function ()', kind = define.SymbolKind.Function, range = {10006, 50003}, selectionRange = {10015, 10016}, valueRange = {10006, 50003}, children = { [1] = { name = 'x', detail = 'local string = "x"', kind = define.SymbolKind.Variable, range = {20010, 20017}, selectionRange = {20010, 20011}, }, [2] = { name = 'y', detail = 'local {}', kind = define.SymbolKind.Variable, range = {30010, 30016}, selectionRange = {30010, 30011}, valueRange = {30014, 30016}, }, --[3] = { -- name = 'z', -- detail = 'global z: number = 1', -- kind = define.SymbolKind.Object, -- range = {71, 71}, -- selectionRange = {71, 71}, -- valueRange = {75, 75}, --}, }, }, [3] = { name = 'y', detail = 'local boolean = true', kind = define.SymbolKind.Variable, range = {60006, 60014}, selectionRange = {60006, 60007}, }, [4] = { name = 'z', detail = 'local', kind = define.SymbolKind.Variable, range = {70006, 70007}, selectionRange = {70006, 70007}, }, } TEST [[ local t = { a = 1, b = 2, c = 3, } ]] { [1] = { name = 't', detail = 'local {a, b, c}', kind = define.SymbolKind.Variable, range = {6, 40001}, selectionRange = {6, 7}, valueRange = {10, 40001}, children = { [1] = { name = 'a', detail = 'field number = 1', kind = define.SymbolKind.Property, range = {10004, 10009}, selectionRange = {10004, 10005}, }, [2] = { name = 'b', detail = 'field number = 2', kind = define.SymbolKind.Property, range = {20004, 20009}, selectionRange = {20004, 20005}, }, [3] = { name = 'c', detail = 'field number = 3', kind = define.SymbolKind.Property, range = {30004, 30009}, selectionRange = {30004, 30005}, }, } } } TEST [[ local t = { a = { b = 1, } } ]] { [1] = { name = 't', detail = 'local {a}', kind = define.SymbolKind.Variable, range = {6, 40001}, selectionRange = {6, 7}, valueRange = {10, 40001}, children = { [1] = { name = 'a', detail = 'field {b}', kind = define.SymbolKind.Property, range = {10004, 30005}, selectionRange = {10004, 10005}, valueRange = {10008, 30005}, children = { [1] = { name = 'b', detail = EXISTS, kind = define.SymbolKind.Property, range = {20008, 20013}, selectionRange = {20008, 20009}, } } }, } } } TEST[[ local function g() end g = 1 ]]{ [1] = { name = 'g', detail = 'function ()', kind = define.SymbolKind.Function, range = {6, 10003}, selectionRange = {15, 16}, valueRange = {6, 10003}, }, [2] = { name = 'g', detail = 'setlocal number = 1', kind = define.SymbolKind.Variable, range = {30000, 30005}, selectionRange = {30000, 30001}, } } TEST[[ function f(a, b, ...) local x = ... print(x.a) end ]]{ [1] = { name = 'f', detail = 'function (a, b, ...)', kind = define.SymbolKind.Function, range = {0, 30003}, selectionRange = {9, 10}, valueRange = {0, 30003}, children = { [1] = { name = 'a', detail = 'param', kind = define.SymbolKind.Constant, range = {11, 12}, selectionRange = {11, 12}, }, [2] = { name = 'b', detail = 'param', kind = define.SymbolKind.Constant, range = {14, 15}, selectionRange = {14, 15}, }, [3] = { name = 'x', detail = 'local', kind = define.SymbolKind.Variable, range = {10010, 10017}, selectionRange = {10010, 10011}, } } }, } TEST [[ local t = { a = 1, b = 2, } local v = t ]]{ [1] = { name = 't', detail = 'local {a, b}', kind = define.SymbolKind.Variable, range = {6, 30001}, selectionRange = {6, 7}, valueRange = {10, 30001}, children = EXISTS, }, [2] = { name = 'v', detail = 'local', kind = define.SymbolKind.Variable, range = {50006, 50011}, selectionRange = {50006, 50007}, }, } TEST [[ local x local function ]]{ [1] = { name = 'x', detail = 'local', kind = define.SymbolKind.Variable, range = {6, 7}, selectionRange = {6, 7}, }, [2] = { name = "", detail = "function ()", kind = 12, range = {10006, 10014}, selectionRange = {10006, 10014}, valueRange = {10006, 10014}, }, } TEST [[ local a, b = { x1 = 1, y1 = 1, z1 = 1, }, { x2 = 1, y2= 1, z2 = 1, } ]]{ [1] = { name = 'a', detail = 'local {x1, y1, z1}', kind = define.SymbolKind.Variable, range = {6, 40001}, selectionRange = {6, 7}, valueRange = {13, 40001}, children = EXISTS, }, [2] = { name = 'b', detail = 'local {x2, y2, z2}', kind = define.SymbolKind.Variable, range = {9, 80001}, selectionRange = {9, 10}, valueRange = {40003, 80001}, children = EXISTS, } } TEST [[ local function x() end local function f() local c end ]] { [1] = { name = 'x', detail = 'function ()', kind = define.SymbolKind.Function, range = {6, 10003}, selectionRange = {15, 16}, valueRange = {6, 10003}, }, [2] = { name = 'f', detail = 'function ()', kind = define.SymbolKind.Function, range = {30006, 50003}, selectionRange = {30015, 30016}, valueRange = {30006, 50003}, children = { [1] = { name = 'c', detail = 'local', kind = define.SymbolKind.Variable, range = {40010, 40011}, selectionRange = {40010, 40011}, }, }, } } TEST [[ local t = f({ k = 1 }) ]] { [1] = { name = 't', detail = 'local', kind = define.SymbolKind.Variable, range = {6, 20002}, selectionRange = {6, 7}, valueRange = {10, 20002}, children = { [1] = { name = 'k', detail = 'field number = 1', kind = define.SymbolKind.Property, range = {10004, 10009}, selectionRange = {10004, 10005}, } } } } TEST [[ local t = {} local function f(a, b) end ]] { [1] = { name = 't', detail = 'local {}', kind = define.SymbolKind.Variable, range = {6, 12}, selectionRange = {6, 7}, valueRange = {10, 12}, }, [2] = { name = 'f', detail = 'function (a, b)', kind = define.SymbolKind.Function, range = {20006, 30003}, selectionRange = {20015, 20016}, valueRange = {20006, 30003}, children = { [1] = { name = 'a', detail = 'param', kind = define.SymbolKind.Constant, range = {20017, 20018}, selectionRange = {20017, 20018}, }, [2] = { name = 'b', detail = 'param', kind = define.SymbolKind.Constant, range = {20020, 20021}, selectionRange = {20020, 20021}, } } } } TEST [[ local a = f { x = function () end } ]] { [1] = { name = 'a', detail = 'local', kind = define.SymbolKind.Variable, range = {6, 30001}, selectionRange = {6, 7}, valueRange = {10, 30001}, children = { [1] = { name = 'x', detail = 'function ()', kind = define.SymbolKind.Function, range = {10004, 20007}, selectionRange = {10004, 10005}, valueRange = {10008, 20007}, } } } } TEST [[ table.sort(t, function (a, b) return false end) ]] { [1] = { name = '', detail = 'table.sort -> function (a, b)', kind = define.SymbolKind.Function, range = {14, 20003}, selectionRange = {14, 22}, valueRange = {14, 20003}, children = EXISTS, } } TEST [[ local root = { inner_function = function () local function function_inside_function() end end } ]] { [1] = { name = 'root', detail = 'local {inner_function}', kind = define.SymbolKind.Variable, range = {6, 50001}, selectionRange = {6, 10}, valueRange = {13, 50001}, children = { [1] = { name = 'inner_function', detail = 'function ()', kind = define.SymbolKind.Function, range = {10004, 40007}, selectionRange = {10004, 10018}, valueRange = {10021, 40007}, children = { [1] = { name = 'function_inside_function', detail = 'function ()', kind = define.SymbolKind.Function, range = {20014, 30011}, selectionRange = {20023, 20047}, valueRange = {20014, 30011}, }, }, }, }, } }