diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2020-10-20 16:58:57 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2020-10-20 16:58:57 +0800 |
commit | 135f38d1b4f4d7b989f738bead5b59bdaf58f7e1 (patch) | |
tree | 0057af75111840f34da65a43cd8df8ce92f63f85 | |
parent | bb319039fdf41326f23ef0c7288123889434b0a8 (diff) | |
download | lua-language-server-135f38d1b4f4d7b989f738bead5b59bdaf58f7e1.zip |
luadoc的第一步
-rw-r--r-- | script-beta/config.lua | 3 | ||||
-rw-r--r-- | script-beta/core/find-source.lua | 5 | ||||
-rw-r--r-- | script-beta/core/reference.lua | 4 | ||||
-rw-r--r-- | script-beta/files.lua | 11 | ||||
-rw-r--r-- | script-beta/parser/guide.lua | 117 | ||||
-rw-r--r-- | script-beta/parser/luadoc.lua | 12 | ||||
-rw-r--r-- | script-beta/provider/provider.lua | 3 | ||||
-rw-r--r-- | script-beta/vm/eachRef.lua | 2 | ||||
-rw-r--r-- | script-beta/vm/getDocs.lua | 58 | ||||
-rw-r--r-- | script-beta/vm/guideInterface.lua | 5 | ||||
-rw-r--r-- | script-beta/vm/init.lua | 1 | ||||
-rw-r--r-- | test-beta/references/init.lua | 23 |
12 files changed, 218 insertions, 26 deletions
diff --git a/script-beta/config.lua b/script-beta/config.lua index bc6bf863..fce52234 100644 --- a/script-beta/config.lua +++ b/script-beta/config.lua @@ -142,6 +142,9 @@ local ConfigTemplate = { color = { mode = {'Semantic', String}, }, + luadoc = { + enable = {true, Boolean}, + }, plugin = { enable = {false, Boolean}, path = {'.vscode/lua-plugin/*.lua', String}, diff --git a/script-beta/core/find-source.lua b/script-beta/core/find-source.lua index 4788d539..32de102c 100644 --- a/script-beta/core/find-source.lua +++ b/script-beta/core/find-source.lua @@ -4,9 +4,10 @@ return function (ast, offset, accept) local len = math.huge local result guide.eachSourceContain(ast.ast, offset, function (source) - if source.finish - source.start < len and accept[source.type] then + local start, finish = guide.getStartFinish(source) + if finish - start < len and accept[source.type] then result = source - len = source.finish - source.start + len = finish - start end end) return result diff --git a/script-beta/core/reference.lua b/script-beta/core/reference.lua index 56580d0b..8bec1836 100644 --- a/script-beta/core/reference.lua +++ b/script-beta/core/reference.lua @@ -48,6 +48,10 @@ local accept = { ['setglobal'] = true, ['getglobal'] = true, ['function'] = true, + + ['doc.type.name'] = true, + ['doc.class.name'] = true, + ['doc.extends.name'] = true, } return function (uri, offset) diff --git a/script-beta/files.lua b/script-beta/files.lua index 9e72ddd8..800d6d4d 100644 --- a/script-beta/files.lua +++ b/script-beta/files.lua @@ -234,6 +234,9 @@ function m.getAst(uri) state.uri = file.uri state.ast.uri = file.uri file.ast = state + if config.config.luadoc.enable then + parser:luadoc(state) + end else log.error(err) file.ast = false @@ -348,6 +351,14 @@ function m.onWatch(ev, ...) end end +function m.flushCache() + for _, file in pairs(m.fileMap) do + file.cacheActiveTime = math.huge + file.ast = nil + file.cache = {} + end +end + local function init() --TODO 可以清空文件缓存,之后看要不要启用吧 --timer.loop(10, function () diff --git a/script-beta/parser/guide.lua b/script-beta/parser/guide.lua index afd763bf..1ae96097 100644 --- a/script-beta/parser/guide.lua +++ b/script-beta/parser/guide.lua @@ -44,7 +44,7 @@ local breakBlockTypes = { } m.childMap = { - ['main'] = {'#'}, + ['main'] = {'#', 'docs'}, ['repeat'] = {'#', 'filter'}, ['while'] = {'filter', '#'}, ['in'] = {'keys', '#'}, @@ -75,7 +75,21 @@ m.childMap = { ['getfield'] = {'node', 'field'}, ['list'] = {'#'}, ['binary'] = {1, 2}, - ['unary'] = {1} + ['unary'] = {1}, + + ['doc'] = {'#'}, + ['doc.class'] = {'class', 'extends'}, + ['doc.type'] = {'#types', '#enums'}, + ['doc.alias'] = {'alias', 'extends'}, + ['doc.param'] = {'param', 'extends'}, + ['doc.return'] = {'#returns'}, + ['doc.field'] = {'field', 'extends'}, + ['doc.generic'] = {'#generics'}, + ['doc.generic.object'] = {'generic', 'extends'}, + ['doc.vararg'] = {'vararg'}, + ['doc.type.table'] = {'key', 'value'}, + ['doc.type.function'] = {'#args', '#returns'}, + ['doc.overload'] = {'overload'}, } m.actionMap = { @@ -327,24 +341,70 @@ function m.getLabel(block, name) error('guide.getLocal overstack') end +function m.getStartFinish(source) + local start = source.start + local finish = source.finish + if not start then + local first = source[1] + if not first then + return nil, nil + end + local last = source[#source] + start = first.start + finish = last.finish + end + return start, finish +end + +function m.getRange(source) + local start = source.vstart or source.start + local finish = source.range or source.finish + if not start then + local first = source[1] + if not first then + return nil, nil + end + local last = source[#source] + start = first.vstart or first.start + finish = last.range or last.finish + end + return start, finish +end + --- 判断source是否包含offset function m.isContain(source, offset) - return source.start <= offset and source.finish >= offset - 1 + local start, finish = m.getStartFinish(source) + if not start then + return false + end + return start <= offset and finish >= offset - 1 end --- 判断offset在source的影响范围内 --- --- 主要针对赋值等语句时,key包含value function m.isInRange(source, offset) - return (source.vstart or source.start) <= offset and (source.range or source.finish) >= offset - 1 + local start, finish = m.getRange(source) + if not start then + return false + end + return start <= offset and finish >= offset - 1 end -function m.isBetween(source, start, finish) - return source.start <= finish and source.finish >= start - 1 +function m.isBetween(source, tStart, tFinish) + local start, finish = m.getStartFinish(source) + if not start then + return false + end + return start <= tFinish and finish >= tStart - 1 end -function m.isBetweenRange(source, start, finish) - return (source.vstart or source.start) <= finish and (source.range or source.finish) >= start - 1 +function m.isBetweenRange(source, tStart, tFinish) + local start, finish = m.getRange(source) + if not start then + return false + end + return start <= tFinish and finish >= tStart - 1 end --- 添加child @@ -357,8 +417,14 @@ function m.addChilds(list, obj, map) for i = 1, #obj do list[#list+1] = obj[i] end - else + elseif obj[key] then list[#list+1] = obj[key] + elseif type(key) == 'string' + and key:sub(1, 1) == '#' then + key = key:sub(2) + for i = 1, #obj[key] do + list[#list+1] = obj[key][i] + end end end end @@ -856,7 +922,27 @@ local function stepRefOfGlobal(obj, mode) return results end -function m.getStepRef(obj, mode) +local function stepRefOfDocType(status, obj, mode) + local results = {} + local name = obj[1] + if not name or not status.interface.docType then + return results + end + local docs = status.interface.docType(name) + for i = 1, #docs do + local doc = docs[i] + if mode == 'def' then + if doc.type == 'doc.class.name' then + results[#results+1] = doc + end + else + results[#results+1] = doc + end + end + return results +end + +function m.getStepRef(status, obj, mode) if obj.type == 'getlocal' or obj.type == 'setlocal' then return stepRefOfLocal(obj.node, mode) @@ -877,6 +963,11 @@ function m.getStepRef(obj, mode) if obj.type == 'library' then return { obj } end + if obj.type == 'doc.class.name' + or obj.type == 'doc.type.name' + or obj.type == 'doc.extends.name' then + return stepRefOfDocType(status, obj, mode) + end return nil end @@ -1076,6 +1167,10 @@ function m.isGlobal(source) return false end +function m.isDoc(source) + return source.type:sub(1, 4) == 'doc.' +end + --- 根据函数的调用参数,获取:调用,参数索引 function m.getCallAndArgIndex(callarg) local callargs = callarg.parent @@ -2024,7 +2119,7 @@ function m.searchRefs(status, obj, mode) end -- 检查单步引用 - local res = m.getStepRef(obj, mode) + local res = m.getStepRef(status, obj, mode) if res then for i = 1, #res do status.results[#status.results+1] = res[i] diff --git a/script-beta/parser/luadoc.lua b/script-beta/parser/luadoc.lua index ebab1ee9..c84cf52b 100644 --- a/script-beta/parser/luadoc.lua +++ b/script-beta/parser/luadoc.lua @@ -671,7 +671,10 @@ return function (_, state) table.sort(comments, function (a, b) return a.start < b.start end) - ast.docs = {} + ast.docs = { + type = 'doc', + parent = ast, + } pushError = state.pushError @@ -679,6 +682,13 @@ return function (_, state) local doc = buildLuaDoc(comment) if doc then ast.docs[#ast.docs+1] = doc + doc.parent = ast.docs + if ast.start > doc.start then + ast.start = doc.start + end + if ast.finish < doc.finish then + ast.finish = doc.finish + end end end end diff --git a/script-beta/provider/provider.lua b/script-beta/provider/provider.lua index c747027c..094ac027 100644 --- a/script-beta/provider/provider.lua +++ b/script-beta/provider/provider.lua @@ -62,6 +62,9 @@ local function updateConfig() then workspace.reload() end + if not util.equal(oldConfig.luadoc, newConfig.luadoc) then + files.flushCache() + end if newConfig.completion.enable then completion.enable() diff --git a/script-beta/vm/eachRef.lua b/script-beta/vm/eachRef.lua index babfa4d8..429cbb73 100644 --- a/script-beta/vm/eachRef.lua +++ b/script-beta/vm/eachRef.lua @@ -5,7 +5,7 @@ local await = require 'await' local function getRefs(source, simple) local results = {} - local lock = vm.lock('eachDef', source) + local lock = vm.lock('eachRef', source) if not lock then return results end diff --git a/script-beta/vm/getDocs.lua b/script-beta/vm/getDocs.lua new file mode 100644 index 00000000..5c8e6304 --- /dev/null +++ b/script-beta/vm/getDocs.lua @@ -0,0 +1,58 @@ +local files = require 'files' +local util = require 'utility' +local guide = require 'parser.guide' +local vm = require 'vm.vm' + +local function getTypesOfFile(uri) + local classes = {} + local ast = files.getAst(uri) + if not ast or not ast.ast.docs then + return classes + end + guide.eachSource(ast.ast.docs, function (src) + if src.type == 'doc.type.name' + or src.type == 'doc.class.name' + or src.type == 'doc.extends.name' then + local name = src[1] + if name then + if not classes[name] then + classes[name] = {} + end + classes[name][#classes[name]+1] = src + end + end + end) + return classes +end + +local function getDocTypes(name) + local results = {} + for uri in files.eachFile() do + local cache = files.getCache(uri) + cache.classes = cache.classes or getTypesOfFile(uri) + if name == '*' then + for _, sources in util.sortPairs(cache.classes) do + for _, source in ipairs(sources) do + results[#results+1] = source + end + end + else + if cache.classes[name] then + for _, source in ipairs(cache.classes[name]) do + results[#results+1] = source + end + end + end + end + return results +end + +function vm.getDocTypes(name) + local cache = vm.getCache('getDocTypes')[name] + if cache ~= nil then + return cache + end + cache = getDocTypes(name) + vm.getCache('getDocTypes')[name] = cache + return cache +end diff --git a/script-beta/vm/guideInterface.lua b/script-beta/vm/guideInterface.lua index a77184f3..4d651882 100644 --- a/script-beta/vm/guideInterface.lua +++ b/script-beta/vm/guideInterface.lua @@ -85,6 +85,11 @@ function vm.interface.global(name) return vm.getGlobals(name) end +function vm.interface.docType(name) + await.delay() + return vm.getDocTypes(name) +end + function vm.interface.link(uri) await.delay() return vm.getLinksTo(uri) diff --git a/script-beta/vm/init.lua b/script-beta/vm/init.lua index 7621859f..b9e8e147 100644 --- a/script-beta/vm/init.lua +++ b/script-beta/vm/init.lua @@ -1,5 +1,6 @@ local vm = require 'vm.vm' require 'vm.getGlobals' +require 'vm.getDocs' require 'vm.getLibrary' require 'vm.getInfer' require 'vm.getClass' diff --git a/test-beta/references/init.lua b/test-beta/references/init.lua index 3573da55..5bca58ab 100644 --- a/test-beta/references/init.lua +++ b/test-beta/references/init.lua @@ -48,6 +48,7 @@ function TEST(script) end assert(founded(target, positions)) else + local results = core('', pos) assert(#target == 0) end end @@ -262,14 +263,14 @@ local <!t!> <!t!>.<!f!> = <?t?> ]] ---TEST [[ ------@class <!Class!> ------@type <?Class?> ------@type <!Class!> ---]] --- ---TEST [[ ------@class <?Class?> ------@type <!Class!> ------@type <!Class!> ---]] +TEST [[ +---@class <!Class!> +---@type <?Class?> +---@type <!Class!> +]] + +TEST [[ +---@class <?Class?> +---@type <!Class!> +---@type <!Class!> +]] |