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 | |
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 `_`
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | meta/template/basic.lua | 2 | ||||
-rw-r--r-- | meta/template/bit.lua | 2 | ||||
-rw-r--r-- | meta/template/bit32.lua | 2 | ||||
-rw-r--r-- | meta/template/builtin.lua | 2 | ||||
-rw-r--r-- | meta/template/coroutine.lua | 2 | ||||
-rw-r--r-- | meta/template/debug.lua | 2 | ||||
-rw-r--r-- | meta/template/ffi.lua | 2 | ||||
-rw-r--r-- | meta/template/io.lua | 2 | ||||
-rw-r--r-- | meta/template/jit.lua | 2 | ||||
-rw-r--r-- | meta/template/math.lua | 2 | ||||
-rw-r--r-- | meta/template/os.lua | 2 | ||||
-rw-r--r-- | meta/template/package.lua | 2 | ||||
-rw-r--r-- | meta/template/string.buffer.lua | 2 | ||||
-rw-r--r-- | meta/template/string.lua | 2 | ||||
-rw-r--r-- | meta/template/table.clear.lua | 4 | ||||
-rw-r--r-- | meta/template/table.lua | 2 | ||||
-rw-r--r-- | meta/template/table.new.lua | 4 | ||||
-rw-r--r-- | meta/template/utf8.lua | 2 | ||||
-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 | ||||
-rw-r--r-- | test/completion/common.lua | 2 | ||||
-rw-r--r-- | test/crossfile/completion.lua | 52 | ||||
-rw-r--r-- | test/crossfile/hover.lua | 49 |
27 files changed, 194 insertions, 26 deletions
diff --git a/changelog.md b/changelog.md index 7fee59c3..9457ea52 100644 --- a/changelog.md +++ b/changelog.md @@ -9,6 +9,7 @@ * `CHG` definition: supports finding definitions for `@class` and `@alias`, since they may be defined multi times * `CHG` rename: supports `@field` * `CHG` improve patch for `.luarc.json` +* `CHG` `---@meta [name]`: once declared `name`, user can only require this file by declared name. meta file can not be required with name `_` * `CHG` remove telemetry * `FIX` [#831] * `FIX` [#1729] diff --git a/meta/template/basic.lua b/meta/template/basic.lua index 9b6210e1..f3ebae94 100644 --- a/meta/template/basic.lua +++ b/meta/template/basic.lua @@ -1,4 +1,4 @@ ----@meta +---@meta _ ---#DES 'arg' ---@type string[] diff --git a/meta/template/bit.lua b/meta/template/bit.lua index 369c5f9d..c9563f42 100644 --- a/meta/template/bit.lua +++ b/meta/template/bit.lua @@ -1,5 +1,5 @@ ---#if not JIT then DISABLE() end ----@meta +---@meta bit ---@version JIT ---@class bitlib diff --git a/meta/template/bit32.lua b/meta/template/bit32.lua index bcb39c66..ddccbab4 100644 --- a/meta/template/bit32.lua +++ b/meta/template/bit32.lua @@ -1,5 +1,5 @@ ---#if VERSION ~= 5.2 then DISABLE() end ----@meta +---@meta bit32 ---@version 5.2 ---#DES 'bit32' diff --git a/meta/template/builtin.lua b/meta/template/builtin.lua index 41858096..466a0966 100644 --- a/meta/template/builtin.lua +++ b/meta/template/builtin.lua @@ -1,4 +1,4 @@ ----@meta +---@meta _ ---@class unknown ---@class any diff --git a/meta/template/coroutine.lua b/meta/template/coroutine.lua index e807f357..b3890bfd 100644 --- a/meta/template/coroutine.lua +++ b/meta/template/coroutine.lua @@ -1,4 +1,4 @@ ----@meta +---@meta coroutine ---#DES 'coroutine' ---@class coroutinelib diff --git a/meta/template/debug.lua b/meta/template/debug.lua index 48ba52d9..e7ac5911 100644 --- a/meta/template/debug.lua +++ b/meta/template/debug.lua @@ -1,4 +1,4 @@ ----@meta +---@meta debug ---#DES 'debug' ---@class debuglib diff --git a/meta/template/ffi.lua b/meta/template/ffi.lua index 2ca83dd5..a9d48657 100644 --- a/meta/template/ffi.lua +++ b/meta/template/ffi.lua @@ -1,5 +1,5 @@ ---#if not JIT then DISABLE() end ----@meta +---@meta ffi ---@class ffi.namespace*: table ---@field [string] function diff --git a/meta/template/io.lua b/meta/template/io.lua index d685128b..a3420479 100644 --- a/meta/template/io.lua +++ b/meta/template/io.lua @@ -1,4 +1,4 @@ ----@meta +---@meta io ---#DES 'io' ---@class iolib diff --git a/meta/template/jit.lua b/meta/template/jit.lua index d1684a04..dae996b5 100644 --- a/meta/template/jit.lua +++ b/meta/template/jit.lua @@ -1,5 +1,5 @@ ---#if not JIT then DISABLE() end ----@meta +---@meta jit ---@version JIT ---@class jitlib diff --git a/meta/template/math.lua b/meta/template/math.lua index 218a15ac..07917a2b 100644 --- a/meta/template/math.lua +++ b/meta/template/math.lua @@ -1,4 +1,4 @@ ----@meta +---@meta math ---#DES 'math' ---@class mathlib diff --git a/meta/template/os.lua b/meta/template/os.lua index fbe37891..fbc56ac1 100644 --- a/meta/template/os.lua +++ b/meta/template/os.lua @@ -1,4 +1,4 @@ ----@meta +---@meta os ---#DES 'os' ---@class oslib diff --git a/meta/template/package.lua b/meta/template/package.lua index 5c08bbef..3845e769 100644 --- a/meta/template/package.lua +++ b/meta/template/package.lua @@ -1,4 +1,4 @@ ----@meta +---@meta package ---#if VERSION >=5.4 then ---#DES 'require>5.4' diff --git a/meta/template/string.buffer.lua b/meta/template/string.buffer.lua index ee57a1ad..7285290a 100644 --- a/meta/template/string.buffer.lua +++ b/meta/template/string.buffer.lua @@ -1,5 +1,5 @@ ---#if not JIT then DISABLE() end ----@meta +---@meta string.buffer ---@version JIT --- The string buffer library allows high-performance manipulation of string-like data. diff --git a/meta/template/string.lua b/meta/template/string.lua index c68e1117..cf83104b 100644 --- a/meta/template/string.lua +++ b/meta/template/string.lua @@ -1,4 +1,4 @@ ----@meta +---@meta string ---#DES 'string' ---@class stringlib diff --git a/meta/template/table.clear.lua b/meta/template/table.clear.lua index dffed5fa..122e3651 100644 --- a/meta/template/table.clear.lua +++ b/meta/template/table.clear.lua @@ -1,9 +1,9 @@ ---#if not JIT then DISABLE() end ----@meta +---@meta table.clear ---@version JIT ---#DES 'table.clear' ---@param tab table local function clear(tab) end -return clear
\ No newline at end of file +return clear diff --git a/meta/template/table.lua b/meta/template/table.lua index 90efde00..40ba0ac1 100644 --- a/meta/template/table.lua +++ b/meta/template/table.lua @@ -1,4 +1,4 @@ ----@meta +---@meta table ---#DES 'table' ---@class tablelib diff --git a/meta/template/table.new.lua b/meta/template/table.new.lua index 398bc9f9..f4b05cdc 100644 --- a/meta/template/table.new.lua +++ b/meta/template/table.new.lua @@ -1,5 +1,5 @@ ---#if not JIT then DISABLE() end ----@meta +---@meta table.new ---@version JIT ---#DES 'table.new' @@ -8,4 +8,4 @@ ---@return table local function new(narray, nhash) end -return new
\ No newline at end of file +return new diff --git a/meta/template/utf8.lua b/meta/template/utf8.lua index cccee99a..5c766838 100644 --- a/meta/template/utf8.lua +++ b/meta/template/utf8.lua @@ -1,5 +1,5 @@ ---#if VERSION <= 5.2 then DISABLE() end ----@meta +---@meta utf8 ---@version >5.3 ---#DES 'utf8' 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 diff --git a/test/completion/common.lua b/test/completion/common.lua index 7e4aac61..e0668ea3 100644 --- a/test/completion/common.lua +++ b/test/completion/common.lua @@ -3538,7 +3538,7 @@ TEST [[ require '<??>' ]] (function (results) - assert(#results == 11, require 'utility'.dump(results)) + assert(#results == 9, require 'utility'.dump(results)) end) TEST [[ diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua index 3ad8c385..d613f621 100644 --- a/test/crossfile/completion.lua +++ b/test/crossfile/completion.lua @@ -10,6 +10,7 @@ local define = require 'proto.define' rawset(_G, 'TEST', true) local CompletionItemKind = define.CompletionItemKind +local NeedRemoveMeta = false local EXISTS = {} @@ -87,7 +88,9 @@ function TEST(data) assert(result ~= nil) result.complete = nil result.enableCommon = nil - removeMetas(result) + if NeedRemoveMeta then + removeMetas(result) + end for _, item in ipairs(result) do if item.id then local r = core.resolve(item.id) @@ -441,6 +444,51 @@ config.set(nil, 'Lua.runtime.path', originRuntimePath) TEST { { + path = 'abc.lua', + content = '---@meta _', + }, + { + path = 'test.lua', + content = 'require "a<??>"', + main = true, + }, + completion = nil +} + +TEST { + { + path = 'abc.lua', + content = '---@meta xxxxx', + }, + { + path = 'test.lua', + content = 'require "a<??>"', + main = true, + }, + completion = nil +} + +TEST { + { + path = 'abc.lua', + content = '---@meta xxxxx', + }, + { + path = 'test.lua', + content = 'require "xx<??>"', + main = true, + }, + completion = { + { + label = 'xxxxx', + kind = CompletionItemKind.File, + textEdit = EXISTS, + } + } +} + +TEST { + { path = 'a.lua', content = [[ return { @@ -561,6 +609,8 @@ TEST { completion = nil, } +NeedRemoveMeta = true + TEST { { path = 'f/a.lua' }, { path = 'f/b.lua' }, diff --git a/test/crossfile/hover.lua b/test/crossfile/hover.lua index d47bb41b..3cd560ff 100644 --- a/test/crossfile/hover.lua +++ b/test/crossfile/hover.lua @@ -176,6 +176,55 @@ end TEST { { path = 'a.lua', + content = '---@meta _', + }, + { + path = 'b.lua', + content = 'require <?"a"?>', + }, + hover = [[ +```lua +1 个字节 +```]], +} + +TEST { + { + path = 'a.lua', + content = '---@meta xxx', + }, + { + path = 'b.lua', + content = 'require <?"a"?>', + }, + hover = [[ +```lua +1 个字节 +```]], +} + +TEST { + { + path = 'a.lua', + content = '---@meta xxx', + }, + { + path = 'b.lua', + content = 'require <?"xxx"?>', + }, + hover = [=[ +```lua +3 个字节 +``` + +--- + +* [[meta]](file:///a.lua)]=], +} + +TEST { + { + path = 'a.lua', content = [[ local function f(a, b) end |