diff options
-rw-r--r-- | server/src/core/completion.old.lua | 578 | ||||
-rw-r--r-- | server/src/core/document_symbol.lua | 195 | ||||
-rw-r--r-- | server/src/core/hover/name.lua | 3 | ||||
-rw-r--r-- | server/src/vm/local.lua | 9 | ||||
-rw-r--r-- | server/src/vm/vm.lua | 4 | ||||
-rw-r--r-- | server/test/document_symbol/init.lua | 119 |
6 files changed, 214 insertions, 694 deletions
diff --git a/server/src/core/completion.old.lua b/server/src/core/completion.old.lua deleted file mode 100644 index 57e006e9..00000000 --- a/server/src/core/completion.old.lua +++ /dev/null @@ -1,578 +0,0 @@ -local findSource = require 'core.find_source' -local hover = require 'core.hover' - -local CompletionItemKind = { - Text = 1, - Method = 2, - Function = 3, - Constructor = 4, - Field = 5, - Variable = 6, - Class = 7, - Interface = 8, - Module = 9, - Property = 10, - Unit = 11, - Value = 12, - Enum = 13, - Keyword = 14, - Snippet = 15, - Color = 16, - File = 17, - Reference = 18, - Folder = 19, - EnumMember = 20, - Constant = 21, - Struct = 22, - Event = 23, - Operator = 24, - TypeParameter = 25, -} - -local function matchKey(me, other) - if me == other then - return true - end - if me == '' then - return true - end - if #me > #other then - return false - end - local lMe = me:lower() - local lOther = other:lower() - if lMe:sub(1, 1) ~= lOther:sub(1, 1) then - return false - end - if lMe == lOther:sub(1, #lMe) then - return true - end - local used = {} - local cur = 1 - local lookup - local researched - for i = 1, #lMe do - local c = lMe:sub(i, i) - -- 1. 看当前字符是否匹配 - if c == lOther:sub(cur, cur) then - used[cur] = true - goto NEXT - end - -- 2. 看前一个字符是否匹配 - if not used[cur-1] then - if c == lOther:sub(cur-1, cur-1) then - used[cur-1] = true - goto NEXT - end - end - -- 3. 向后找这个字 - lookup = lOther:find(c, cur+1, true) - if lookup then - cur = lookup - used[cur] = true - goto NEXT - end - - -- 4. 重新搜索整个字符串,但是只允许1次,否则失败.如果找不到也失败 - if researched then - return false - else - researched = true - for j = 1, cur - 2 do - if c == lOther:sub(j, j) then - used[j] = true - goto NEXT - end - end - return false - end - -- 5. 找到下一个可用的字,如果超出长度且把自己所有字都用尽就算成功 - ::NEXT:: - repeat - cur = cur + 1 - until not used[cur] - if cur > #lOther then - return i == #lMe - end - end - return true -end - -local function searchLocals(vm, pos, name, callback) - for _, loc in ipairs(vm.results.locals) do - if loc.source.start == 0 then - goto CONTINUE - end - if not loc.close then - log.debug('Miss loc close', table.dump(loc)) - end - if loc.source.start <= pos and loc.close >= pos then - if matchKey(name, loc.key) then - callback(loc) - end - end - ::CONTINUE:: - end -end - -local function sortPairs(t) - local keys = {} - for k in pairs(t) do - keys[#keys+1] = k - end - table.sort(keys) - local i = 0 - return function () - i = i + 1 - local k = keys[i] - return k, t[k] - end -end - -local function searchFields(name, parentValue, source, callback) - if not parentValue then - return - end - if type(name) ~= 'string' then - return - end - local map = {} - parentValue:eachField(function (key, field) - if type(key) ~= 'string' then - goto CONTINUE - end - if source.object and field.value:getType() ~= 'function' then - goto CONTINUE - end - if matchKey(name, key) then - map[key] = field - end - ::CONTINUE:: - end) - for _, field in sortPairs(map) do - callback(field) - end -end - -local KEYS = {'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while', 'toclose'} -local function searchKeyWords(name, callback) - for _, key in ipairs(KEYS) do - if matchKey(name, key) then - callback(key) - end - end -end - -local function getKind(var, default) - local value = var.value - if default == CompletionItemKind.Variable then - if value:getType() == 'function' then - return CompletionItemKind.Function - end - end - if default == CompletionItemKind.Field then - local tp = type(value:getValue()) - if tp == 'number' or tp == 'integer' or tp == 'string' then - return CompletionItemKind.Enum - end - if value:getType() == 'function' then - if value.object then - return CompletionItemKind.Method - else - return CompletionItemKind.Function - end - end - end - return default -end - -local function getDetail(var) - local tp = type(var.value:getValue()) - if tp == 'boolean' then - return ('= %q'):format(var.value:getValue()) - elseif tp == 'number' then - if math.type(var.value:getValue()) == 'integer' then - return ('= %q'):format(var.value:getValue()) - else - local str = ('= %.10f'):format(var.value:getValue()) - local dot = str:find('.', 1, true) - local suffix = str:find('[0]+$', dot+2) - if suffix then - return str:sub(1, suffix-1) - else - return str - end - end - elseif tp == 'string' then - return ('= %q'):format(var.value:getValue()) - end - return nil -end - -local function getDocument(var, source) - if not source then - return nil - end - if var.value:getType() == 'function' then - local hvr = hover(var, source) - if not hvr then - return nil - end - local text = ([[ -```lua -%s -``` -%s -```lua -%s -``` -]]):format(hvr.label or '', hvr.description or '', hvr.enum or '') - return { - kind = 'markdown', - value = text, - } - end - return nil -end - -local function searchAsLocal(vm, word, pos, result, source, callback) - searchFields(word, vm.env, source, function (var) - callback(var, CompletionItemKind.Variable) - end) - - -- 支持 local function - if matchKey(word, 'function') then - callback('function', CompletionItemKind.Keyword) - end -end - -local function searchAsArg(vm, word, pos, result, source, callback) - searchFields(word, vm.env, source, function (var) - if var.value.lib then - return - end - callback(var, CompletionItemKind.Variable) - end) -end - -local function searchAsGlobal(vm, word, pos, result, source, callback) - if word == '' or word == nil then - return - end - searchLocals(vm, pos, word, function (var) - callback(var, CompletionItemKind.Variable) - end) - searchFields(word, result.parentValue, source, function (var) - callback(var, CompletionItemKind.Field) - end) - searchKeyWords(word, function (name) - callback(name, CompletionItemKind.Keyword) - end) -end - -local function searchAsSuffix(result, source, word, callback) - searchFields(word, result.parentValue, source, function (var) - callback(var, CompletionItemKind.Field) - end) -end - -local function searchInArg(vm, inCall, inString, callback) - local lib = inCall.func.lib - if not lib then - return - end - - -- require列举出可以引用到的文件 - if lib.special == 'require' then - if not vm.lsp or not vm.lsp.workspace or not inString then - return - end - local results = vm.lsp.workspace:matchPath(vm.uri, inString[1]) - if not results then - return - end - for _, v in ipairs(results) do - if v ~= inString[1] then - callback(v, CompletionItemKind.File, { - textEdit = { - start = inString.start+1, - finish = inString.finish-1, - newText = ('%q'):format(v):sub(2, -2), - } - }) - end - end - end - - -- 其他库函数,根据参数位置找枚举值 - if lib.args and lib.enums then - local arg = lib.args[inCall.select] - local name = arg and arg.name - for _, enum in ipairs(lib.enums) do - if enum.name == name and enum.enum then - if inString then - callback(enum.enum, CompletionItemKind.EnumMember, { - documentation = enum.description - }) - else - callback(('%q'):format(enum.enum), CompletionItemKind.EnumMember, { - documentation = enum.description - }) - end - end - end - end -end - -local function searchAsIndex(vm, word, pos, result, source, callback) - searchLocals(vm, pos, word, function (var) - callback(var, CompletionItemKind.Variable) - end) - for _, source in ipairs(vm.results.sources) do - if source.isIndex then - local index = source.bind - if matchKey(word, index.key) then - callback(index.key, CompletionItemKind.Property) - end - end - end - searchFields(word, result.parentValue, source, function (var) - callback(var, CompletionItemKind.Field) - end) -end - -local function findClosePos(vm, pos) - local curDis = math.maxinteger - local parent = nil - local inputSource = nil - local function found(object, source) - local dis = pos - source.finish - if dis > 1 and dis < curDis then - curDis = dis - parent = object - inputSource = source - end - end - for _, source in ipairs(vm.results.sources) do - found(source.bind, source) - end - if not parent then - return nil - end - if parent.type ~= 'local' and parent.type ~= 'field' then - return nil - end - local sep = inputSource.dot or inputSource.colon - if not sep then - return nil - end - if sep.finish > pos then - return nil - end - -- 造个假的 DirtyName - local source = { - type = 'name', - start = pos, - finish = pos, - object = sep.type == ':' and parent, - isSuffix = true, - [1] = '', - } - local result = { - type = 'field', - parent = parent, - parentValue = parent.value, - key = '', - } - return result, source -end - -local function isContainPos(obj, pos) - if obj.start <= pos and obj.finish + 1 >= pos then - return true - end - return false -end - -local function findString(vm, word, pos) - local finishPos = pos + #word - 1 - for _, source in ipairs(vm.results.strings) do - if isContainPos(source, finishPos) then - return source - end - end - return nil -end - -local function findArgCount(args, pos) - for i, arg in ipairs(args) do - if isContainPos(arg, pos) then - return i - end - end - return #args + 1 -end - --- 找出范围包含pos的call -local function findCall(vm, word, pos) - local finishPos = pos + #word - 1 - local results = {} - for _, call in ipairs(vm.results.calls) do - if isContainPos(call.args, finishPos) then - local n = findArgCount(call.args, finishPos) - local var = call.lastObj.bind - if var then - results[#results+1] = { - func = call.func, - var = var, - source = call.lastObj, - select = n, - args = call.args, - } - end - end - end - if #results == 0 then - return nil - end - -- 可能处于 'func1(func2(' 的嵌套中,因此距离越远的函数层级越低 - table.sort(results, function (a, b) - return a.args.start < b.args.start - end) - return results[#results] -end - -local function makeList(list, source) - local mark = {} - local function callback(var, defualt, data) - local key - if type(var) == 'string' then - key = var - else - key = var.key - end - if mark[key] then - return - end - mark[key] = true - data = data or {} - if var == key then - data.label = var - data.kind = defualt - elseif var.source ~= source then - data.label = var.key - data.kind = getKind(var, defualt) - data.detail = data.detail or getDetail(var) - data.documentation = data.documentation or getDocument(var, source) - else - return - end - list[#list+1] = data - end - return callback -end - -local function searchInResult(result, word, source, vm, pos, callback) - if result.type == 'local' then - if result.link then - result = result.link - end - if source.isArg then - searchAsArg(vm, word, pos, result, source, callback) - elseif source.isLocal then - searchAsLocal(vm, word, pos, result, source, callback) - else - searchAsGlobal(vm, word, pos, result, source, callback) - end - elseif result.type == 'field' then - if source.isIndex then - searchAsIndex(vm, word, pos, result, source, callback) - elseif source.isSuffix then - searchAsSuffix(result, source, word, callback) - else - searchAsGlobal(vm, word, pos, result, source, callback) - end - end -end - -local function searchAllWords(text, vm, callback) - if text == '' then - return - end - if type(text) ~= 'string' then - return - end - for _, source in ipairs(vm.results.sources) do - if source.type == 'name' then - if text ~= source[1] and matchKey(text, source[1]) then - callback(source[1], CompletionItemKind.Text) - end - end - end -end - -local function searchSpecial(vm, pos, callback) - -- 尝试 # - local _, source = findSource(vm, pos, 2) - if source and source.indexName and source[1].op == '#' - then - local label = source.indexName .. '+1' - callback(label, CompletionItemKind.Snippet, { - textEdit = { - start = source.start, - finish = source.finish, - newText = ('[#%s] = '):format(label), - } - }) - end -end - -local function clearList(list, source) - local key = source[1] - -- 清除自己 - for i, v in ipairs(list) do - if v.label == key then - table.remove(list, i) - return - end - end -end - -local function isValidResult(result) - if not result then - return false - end - if result.type == 'local' or result.type == 'field' then - return true - end - return false -end - -return function (vm, pos, word) - local list = {} - local callback = makeList(list) - local inCall = findCall(vm, word, pos) - local inString = findString(vm, word, pos) - if inCall then - searchInArg(vm, inCall, inString, callback) - end - searchSpecial(vm, pos, callback) - if not inString then - local result, source = findSource(vm, pos) - if not isValidResult(result) then - result, source = findClosePos(vm, pos) - end - if isValidResult(result) then - callback = makeList(list, source) - searchInResult(result, word, source, vm, pos, callback) - searchAllWords(result.key, vm, callback) - clearList(list, source) - else - searchAllWords(word, vm, callback) - end - end - if #list == 0 then - return nil - end - return list -end diff --git a/server/src/core/document_symbol.lua b/server/src/core/document_symbol.lua index 8ca39bdd..e4b3c3b8 100644 --- a/server/src/core/document_symbol.lua +++ b/server/src/core/document_symbol.lua @@ -31,95 +31,136 @@ local SymbolKind = { TypeParameter = 26, } -local function buildFunction(vm, var, source) - local func = var.value - if func.source.start == 0 then - return nil - end - local name = hoverName(var, source) - local hvr = hoverFunction(name, func, source.object) +local function buildLocal(source, callback) + local loc = source:bindLocal() + local value = loc:getInitValue() + local hvr = hover(source) if not hvr then - return nil - end - local selectionRange = { source.start, source.finish } - local range = { math.min(source.start, func.source.start), func.source.finish } - local kind = SymbolKind.Function - if source.isSuffix then - kind = SymbolKind.Field - end - - return { - name = name, - -- 前端不支持多行 - detail = hvr.label:gsub('[\r\n]', ''), - kind = kind, - range = range, - selectionRange = selectionRange, - } -end - -local function isLocalTable(var, source) - if not var.value or var.value:getType() ~= 'table' then - return false - end - if var.value.source.start == 0 then - return false + return end - if source ~= var.value:getDeclarat() then - return false + local kind + if value:getType() == 'function' then + kind = SymbolKind.Function + elseif source:get 'table index' then + kind = SymbolKind.Class + else + kind = SymbolKind.Variable end - if var.value.source.finish < source.finish then - return false + local valueSource = value.source + if valueSource.start == 0 then + valueSource = source + end + -- 由于范围不允许交叉,为了支持 local x, y, z = 1, 2, 3 的形式 + -- 范围只能限定在变量上 + -- 而 local function xx() 的形式范围会包含整个 function + if source.start > valueSource.start then + callback { + name = hvr.name, + detail = hvr.label:gsub('[\r\n]', ''), + kind = kind, + range = { valueSource.start, valueSource.finish }, + selectionRange = { source.start, source.finish }, + valueRange = { valueSource.start, valueSource.finish }, + } + else + callback { + name = hvr.name, + detail = hvr.label:gsub('[\r\n]', ''), + kind = kind, + range = { source.start, source.finish }, + selectionRange = { source.start, source.finish }, + valueRange = { valueSource.start, valueSource.finish }, + } end - return true end -local function buildVar(vm, var, source) - if source.start == 0 then - return nil - end - if var.value:getType() == 'function' then - return buildFunction(vm, var, source) - end - if not source.isLocal and not source.isIndex then - return nil - end - if var.hide then - return nil +local function buildSet(source, callback) + if source:bindLocal() then + return end - local key = var.key - if key == '_' then - return nil - end - if type(key) ~= 'string' then - key = ('[%s]'):format(key) - end - local range - if isLocalTable(var, source) then - range = { source.start, var.value.source.finish } - else - range = { source.start, source.finish } - end - local hvr = hover(var, source) + local value = source:bindValue() + local hvr = hover(source) if not hvr then - return nil + return end local kind - if source.isIndex then + if value:getType() == 'function' then + local func = value:getFunction() + if func:getObject() then + kind = SymbolKind.Field + else + kind = SymbolKind.Function + end + elseif source:get 'table index' then kind = SymbolKind.Class else - kind = SymbolKind.Variable + kind = SymbolKind.Object + end + local valueSource = value.source + -- 由于范围不允许交叉,为了支持 x, y, z = 1, 2, 3 的形式 + -- 范围只能限定在变量上 + -- 而 function xx() 的形式范围会包含整个 function + if source.start > valueSource.start then + callback { + name = hvr.name, + -- 前端不支持多行 + detail = hvr.label:gsub('[\r\n]', ''), + kind = kind, + range = { valueSource.start, valueSource.finish }, + selectionRange = { source.start, source.finish }, + valueRange = { valueSource.start, valueSource.finish }, + } + else + callback { + name = hvr.name, + -- 前端不支持多行 + detail = hvr.label:gsub('[\r\n]', ''), + kind = kind, + range = { source.start, source.finish }, + selectionRange = { source.start, source.finish }, + valueRange = { valueSource.start, valueSource.finish }, + } end - return { - name = key, +end + +local function buildReturn(source, callback) + local value = source:bindFunction() + if not value then + return + end + local hvr = hoverFunction('', value:getFunction()) + if not hvr then + return + end + local kind = SymbolKind.Function + callback { + name = '', -- 前端不支持多行 detail = hvr.label:gsub('[\r\n]', ''), kind = kind, - range = range, - selectionRange = { source.start, source.finish }, + range = { source.start, source.finish }, + selectionRange = { source.start, source.start }, + valueRange = { source.start, source.finish }, } end +local function buildSource(source, callback) + if source:action() == 'local' then + buildLocal(source, callback) + return + end + if source:action() == 'set' then + buildSet(source, callback) + return + end + if source.type == 'return' then + for _, src in ipairs(source) do + buildReturn(src, callback) + end + return + end +end + local function packChild(symbols, finish, kind) local t while true do @@ -127,11 +168,11 @@ local function packChild(symbols, finish, kind) if not symbol then break end - if symbol.range[1] > finish then + if symbol.valueRange[1] > finish then break end symbols[#symbols] = nil - symbol.children = packChild(symbols, symbol.range[2], symbol.kind) + symbol.children = packChild(symbols, symbol.valueRange[2], symbol.kind) if symbol.kind == SymbolKind.Class and kind == SymbolKind.Function then else if not t then @@ -146,7 +187,7 @@ end local function packSymbols(symbols) -- 按照start位置反向排序 table.sort(symbols, function (a, b) - return a.range[1] > b.range[1] + return a.valueRange[1] > b.valueRange[1] end) -- 处理嵌套 return packChild(symbols, math.maxinteger, SymbolKind.Function) @@ -155,10 +196,10 @@ end return function (vm) local symbols = {} - for _, source in ipairs(vm.results.sources) do - if source.bind then - symbols[#symbols+1] = buildVar(vm, source.bind, source) - end + for _, source in ipairs(vm.sources) do + buildSource(source, function (data) + symbols[#symbols+1] = data + end) end local packedSymbols = packSymbols(symbols) diff --git a/server/src/core/hover/name.lua b/server/src/core/hover/name.lua index 4faab3f1..78c30b4d 100644 --- a/server/src/core/hover/name.lua +++ b/server/src/core/hover/name.lua @@ -1,5 +1,8 @@ return function (source) local value = source:bindValue() + if not value then + return '' + end local func = value:getFunction() local declarat if func then diff --git a/server/src/vm/local.lua b/server/src/vm/local.lua index fe8b3fe4..fef5a97b 100644 --- a/server/src/vm/local.lua +++ b/server/src/vm/local.lua @@ -23,6 +23,14 @@ function mt:getValue() return self.value end +function mt:setInitValue(value) + self.initValue = value +end + +function mt:getInitValue() + return self.initValue +end + function mt:addInfo(tp, source) self[#self+1] = { type = tp, @@ -87,6 +95,7 @@ return function (name, source, value) name = name, source = source or getDefaultSource(), value = value, + initValue = value, }, mt) return self end diff --git a/server/src/vm/vm.lua b/server/src/vm/vm.lua index 009de868..50deb7e9 100644 --- a/server/src/vm/vm.lua +++ b/server/src/vm/vm.lua @@ -690,6 +690,7 @@ function mt:doReturn(action) if #action == 0 then return end + self:instantSource(action) local values = self:unpackList(action) local func = self:getCurrentFunction() values:eachValue(function (n, value) @@ -928,6 +929,7 @@ function mt:doLocalFunction(action) local func = self:buildFunction(action) func:addInfo('local', name) loc:setValue(func) + loc:setInitValue(func) end end end @@ -987,7 +989,7 @@ function mt:doActions(actions) end function mt:createFunction(source) - local value = createValue('function', source) + local value = self:createValue('function', source) local func = createFunction(source) value:setFunction(func) value:setType('function', 1.0) diff --git a/server/test/document_symbol/init.lua b/server/test/document_symbol/init.lua index ff66cac2..f73cd6ba 100644 --- a/server/test/document_symbol/init.lua +++ b/server/test/document_symbol/init.lua @@ -1,5 +1,6 @@ local parser = require 'parser' local core = require 'core' +local buildVM = require 'vm' local SymbolKind = { File = 1, @@ -63,7 +64,7 @@ end function TEST(script) return function (expect) local ast = parser:ast(script) - local vm = core.vm(ast) + local vm = buildVM(ast) assert(vm) local result = core.documentSymbol(vm) assert(eq(expect, result)) @@ -81,6 +82,7 @@ end kind = SymbolKind.Function, range = {1, 22}, selectionRange = {16, 16}, + valueRange = {1, 22}, } } @@ -95,22 +97,24 @@ end kind = SymbolKind.Function, range = {1, 16}, selectionRange = {10, 10}, + valueRange = {1, 16}, } } ---TEST [[ ---return function () ---end ---]] ---{ --- [1] = { --- name = '', --- detail = 'function ()', --- kind = SymbolKind.Function, --- range = {8, 22}, --- selectionRange = {8, 8}, --- } ---} +TEST [[ +return function () +end +]] +{ + [1] = { + name = '', + detail = 'function ()', + kind = SymbolKind.Function, + range = {8, 22}, + selectionRange = {8, 8}, + valueRange = {8, 22}, + } +} TEST [[ f = function () @@ -121,8 +125,9 @@ end name = 'f', detail = 'function f()', kind = SymbolKind.Function, - range = {1, 19}, + range = {1, 1}, selectionRange = {1, 1}, + valueRange = {5, 19}, } } @@ -135,8 +140,9 @@ end name = 'f', detail = 'function f()', kind = SymbolKind.Function, - range = {7, 25}, + range = {7, 7}, selectionRange = {7, 7}, + valueRange = {11, 25}, } } @@ -151,6 +157,7 @@ end kind = SymbolKind.Field, range = {1, 21}, selectionRange = {13, 15}, + valueRange = {1, 21}, } } @@ -171,6 +178,7 @@ end kind = SymbolKind.Function, range = {1, 68}, selectionRange = {10, 10}, + valueRange = {1, 68}, children = { [1] = { name = 'A1', @@ -178,6 +186,7 @@ end kind = SymbolKind.Function, range = {18, 38}, selectionRange = {27, 28}, + valueRange = {18, 38}, }, [2] = { name = 'A2', @@ -185,6 +194,7 @@ end kind = SymbolKind.Function, range = {44, 64}, selectionRange = {53, 54}, + valueRange = {44, 64}, }, }, }, @@ -194,6 +204,7 @@ end kind = SymbolKind.Function, range = {70, 85}, selectionRange = {79, 79}, + valueRange = {70, 85}, }, } @@ -202,8 +213,10 @@ local x = 1 local function f() local x = 'x' local y = {} + z = 1 end local y = true +local z ]] { [1] = { @@ -212,13 +225,15 @@ local y = true kind = SymbolKind.Variable, range = {7, 7}, selectionRange = {7, 7}, + valueRange = {11, 11}, }, [2] = { name = 'f', detail = 'function f()', kind = SymbolKind.Function, - range = {13, 69}, + range = {13, 79}, selectionRange = {28, 28}, + valueRange = {13, 79}, children = { [1] = { name = 'x', @@ -226,13 +241,23 @@ local y = true kind = SymbolKind.Variable, range = {42, 42}, selectionRange = {42, 42}, + valueRange = {46, 48}, }, [2] = { name = 'y', detail = 'local y: {}', kind = SymbolKind.Variable, - range = {60, 65}, + range = {60, 60}, selectionRange = {60, 60}, + valueRange = {64, 65}, + }, + [3] = { + name = 'z', + detail = 'global z: number = 1', + kind = SymbolKind.Object, + range = {71, 71}, + selectionRange = {71, 71}, + valueRange = {75, 75}, }, }, }, @@ -240,8 +265,17 @@ local y = true name = 'y', detail = 'local y: boolean = true', kind = SymbolKind.Variable, - range = {77, 77}, - selectionRange = {77, 77}, + range = {87, 87}, + selectionRange = {87, 87}, + valueRange = {91, 94}, + }, + [4] = { + name = 'z', + detail = 'local z: any', + kind = SymbolKind.Variable, + range = {102, 102}, + selectionRange = {102, 102}, + valueRange = {102, 102}, }, } @@ -257,8 +291,9 @@ local t = { name = 't', detail = EXISTS, kind = SymbolKind.Variable, - range = {7, 46}, + range = {7, 7}, selectionRange = {7, 7}, + valueRange = {11, 46}, children = { [1] = { name = 'a', @@ -266,6 +301,7 @@ local t = { kind = SymbolKind.Class, range = {17, 17}, selectionRange = {17, 17}, + valueRange = {21, 21}, }, [2] = { name = 'b', @@ -273,6 +309,7 @@ local t = { kind = SymbolKind.Class, range = {28, 28}, selectionRange = {28, 28}, + valueRange = {32, 32}, }, [3] = { name = 'c', @@ -280,6 +317,7 @@ local t = { kind = SymbolKind.Class, range = {39, 39}, selectionRange = {39, 39}, + valueRange = {43, 43}, }, } } @@ -297,15 +335,17 @@ local t = { name = 't', detail = EXISTS, kind = SymbolKind.Variable, - range = {7, 44}, + range = {7, 7}, selectionRange = {7, 7}, + valueRange = {11, 44}, children = { [1] = { name = 'a', detail = EXISTS, kind = SymbolKind.Class, - range = {17, 42}, + range = {17, 17}, selectionRange = {17, 17}, + valueRange = {21, 42}, children = { [1] = { name = 'b', @@ -313,6 +353,7 @@ local t = { kind = SymbolKind.Class, range = {31, 31}, selectionRange = {31, 31}, + valueRange = {35, 35}, } } }, @@ -320,21 +361,21 @@ local t = { } } ---TEST[[ ---local function g() ---end --- ---g = 1 ---]]{ --- [1] = { --- name = 'g', --- detail = 'function g()', --- kind = SymbolKind.Function, --- range = {1, 22}, --- selectionRange = {16, 16}, --- children = EXISTS, --- } ---} +TEST[[ +local function g() +end + +g = 1 +]]{ + [1] = { + name = 'g', + detail = 'function g()', + kind = SymbolKind.Function, + range = {1, 22}, + selectionRange = {16, 16}, + valueRange = {1, 22}, + } +} TEST[[ function f(...) @@ -348,6 +389,7 @@ end kind = SymbolKind.Function, range = {1, 52}, selectionRange = {10, 10}, + valueRange = {1, 52}, children = { [1] = { name = 'x', @@ -355,6 +397,7 @@ end kind = SymbolKind.Variable, range = {27, 27}, selectionRange = {27, 27}, + valueRange = {27, 27}, } } }, |