diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2023-01-16 21:06:06 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2023-01-16 21:06:06 +0800 |
commit | 5aaecf51b9fccddf52ed3e4749757a03819fae61 (patch) | |
tree | 87ceb62c6eb926cb54d8ba794697f0d3ddd0b1e3 /script | |
parent | a6798e6adb81da6b7f833bc39da0a6368178a090 (diff) | |
download | lua-language-server-5aaecf51b9fccddf52ed3e4749757a03819fae61.zip |
support `---@meta [name]`
once declared `name`, user can only require this file by declared name
meta file can not be required with name `_`
Diffstat (limited to 'script')
-rw-r--r-- | script/core/semantic-tokens.lua | 8 | ||||
-rw-r--r-- | script/parser/guide.lua | 1 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 2 | ||||
-rw-r--r-- | script/vm/doc.lua | 26 | ||||
-rw-r--r-- | script/workspace/require-path.lua | 39 |
5 files changed, 72 insertions, 4 deletions
diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua index b1ec6ac4..60a94281 100644 --- a/script/core/semantic-tokens.lua +++ b/script/core/semantic-tokens.lua @@ -694,6 +694,14 @@ local Care = util.switch() type = define.TokenTypes.operator, } end) + : case 'doc.meta.name' + : call(function (source, options, results) + results[#results+1] = { + start = source.start, + finish = source.finish, + type = define.TokenTypes.namespace, + } + end) ---@param state table ---@param results table diff --git a/script/parser/guide.lua b/script/parser/guide.lua index e3c466c0..7f569d71 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -178,6 +178,7 @@ local childMap = { ['doc.cast'] = {'name', '#casts'}, ['doc.cast.block'] = {'extends'}, ['doc.operator'] = {'op', 'exp', 'extends'}, + ['doc.meta'] = {'name'}, } ---@type table<string, fun(obj: parser.object, list: parser.object[])> diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 1a88d385..545f9d95 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -1116,8 +1116,10 @@ local docSwitch = util.switch() end) : case 'meta' : call(function () + local requireName = parseName('doc.meta.name') return { type = 'doc.meta', + name = requireName, start = getFinish(), finish = getFinish(), } diff --git a/script/vm/doc.lua b/script/vm/doc.lua index f0f7c54c..a6ea248f 100644 --- a/script/vm/doc.lua +++ b/script/vm/doc.lua @@ -44,12 +44,38 @@ function vm.isMetaFile(uri) for _, doc in ipairs(status.ast.docs) do if doc.type == 'doc.meta' then cache.isMeta = true + cache.metaName = doc.name return true end end return false end +---@param uri uri +---@return string? +function vm.getMetaName(uri) + if not vm.isMetaFile(uri) then + return nil + end + local cache = files.getCache(uri) + if not cache then + return nil + end + if not cache.metaName then + return nil + end + return cache.metaName[1] +end + +---@param uri uri +---@return boolean +function vm.isMetaFileRequireable(uri) + if not vm.isMetaFile(uri) then + return false + end + return vm.getMetaName(uri) ~= '_' +end + ---@param doc parser.object ---@return table<string, boolean>? function vm.getValidVersions(doc) diff --git a/script/workspace/require-path.lua b/script/workspace/require-path.lua index f65af868..d7ca8e26 100644 --- a/script/workspace/require-path.lua +++ b/script/workspace/require-path.lua @@ -59,12 +59,24 @@ end ---@param path string ---@return require-manager.visibleResult[] function mt:getRequireResultByPath(path) + local vm = require 'vm' local uri = furi.encode(path) + local result = {} + if vm.isMetaFile(uri) then + local metaName = vm.getMetaName(uri) + if metaName then + if vm.isMetaFileRequireable(uri) then + result[#result+1] = { + name = metaName, + } + end + return result + end + end local searchers = config.get(self.scp.uri, 'Lua.runtime.path') local strict = config.get(self.scp.uri, 'Lua.runtime.pathStrict') local libUri = files.getLibraryUri(self.scp.uri, uri) local libraryPath = libUri and furi.decode(libUri) - local result = {} for _, searcher in ipairs(searchers) do local isAbsolute = searcher:match '^[/\\]' or searcher:match '^%a+%:' @@ -157,14 +169,29 @@ end --- 查找符合指定require name的所有uri ---@param name string ---@return uri[] ----@return table<uri, string> +---@return table<uri, string>? function mt:searchUrisByRequireName(name) + local vm = require 'vm' local searchers = config.get(self.scp.uri, 'Lua.runtime.path') local strict = config.get(self.scp.uri, 'Lua.runtime.pathStrict') local separator = config.get(self.scp.uri, 'Lua.completion.requireSeparator') local path = name:gsub('%' .. separator, '/') local results = {} local searcherMap = {} + local excludes = {} + + for uri in files.eachFile(self.scp.uri) do + if vm.isMetaFileRequireable(uri) then + local metaName = vm.getMetaName(uri) + if metaName == name then + results[#results+1] = uri + return results + end + if metaName then + excludes[uri] = true + end + end + end for _, searcher in ipairs(searchers) do local fspath = searcher:gsub('%?', (path:gsub('%%', '%%%%'))) @@ -172,7 +199,9 @@ function mt:searchUrisByRequireName(name) local tail = '/' .. furi.encode(fspath):gsub('^file:[/]*', '') for uri in files.eachFile(self.scp.uri) do if not searcherMap[uri] - and util.stringEndWith(uri, tail) then + and not excludes[uri] + and util.stringEndWith(uri, tail) + and (not vm.isMetaFile(uri) or vm.isMetaFileRequireable(uri)) then local parentUri = files.getLibraryUri(self.scp.uri, uri) or self.scp.uri if parentUri == nil or parentUri == '' then parentUri = furi.encode '/' @@ -223,7 +252,7 @@ function mt:findUrisByRequireName(suri, name) for _, uri in ipairs(cache.results) do if uri ~= suri then results[#results+1] = uri - searcherMap[uri] = cache.searcherMap[uri] + searcherMap[uri] = cache.searcherMap and cache.searcherMap[uri] end end return results, searcherMap @@ -242,6 +271,8 @@ end ---@param uri uri ---@param name string +---@return uri[] +---@return table<uri, string>? function m.findUrisByRequireName(uri, name) local scp = scope.getScope(uri) ---@type require-manager |