summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-04-25 01:56:00 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-04-25 01:56:00 +0800
commitafc5f4e128f17b70dd6f661394da1acfd924be14 (patch)
tree2823ab03cce20bcf0ed4a9d1c1f583636cdf0313
parent125d943a7faec97b7169d0088a12ba6a44a14c16 (diff)
downloadlua-language-server-afc5f4e128f17b70dd6f661394da1acfd924be14.zip
add completion and semantic for `@cast`
-rw-r--r--script/core/completion/completion.lua36
-rw-r--r--script/core/definition.lua1
-rw-r--r--script/core/semantic-tokens.lua8
-rw-r--r--script/parser/luadoc.lua5
-rw-r--r--script/vm/def.lua7
-rw-r--r--test/completion/common.lua24
-rw-r--r--test/definition/luadoc.lua6
7 files changed, 86 insertions, 1 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index b164d738..0f720684 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -1514,6 +1514,7 @@ local function tryluaDocCate(word, results)
'module',
'async',
'nodiscard',
+ 'cast',
} do
if matchKey(word, docType) then
results[#results+1] = {
@@ -1662,8 +1663,27 @@ local function tryluaDocBySource(state, position, source, results)
}
end
end
+ return true
elseif source.type == 'doc.module' then
collectRequireNames('require', state.uri, source.module or '', source, source.smark, position, results)
+ return true
+ elseif source.type == 'doc.cast.name' then
+ local locals = guide.getVisibleLocals(state.ast, position)
+ for name, loc in util.sortPairs(locals) do
+ if matchKey(source[1], name) then
+ results[#results+1] = {
+ label = name,
+ kind = define.CompletionItemKind.Variable,
+ id = stack(function () ---@async
+ return {
+ detail = buildDetail(loc),
+ description = buildDesc(loc),
+ }
+ end),
+ }
+ end
+ end
+ return true
end
return false
end
@@ -1758,6 +1778,22 @@ local function tryluaDocByErr(state, position, err, docState, results)
end
elseif err.type == 'LUADOC_MISS_MODULE_NAME' then
collectRequireNames('require', state.uri, '', docState, nil, position, results)
+ elseif err.type == 'LUADOC_MISS_LOCAL_NAME' then
+ local locals = guide.getVisibleLocals(state.ast, position)
+ for name, loc in util.sortPairs(locals) do
+ if name ~= '_ENV' then
+ results[#results+1] = {
+ label = name,
+ kind = define.CompletionItemKind.Variable,
+ id = stack(function () ---@async
+ return {
+ detail = buildDetail(loc),
+ description = buildDesc(loc),
+ }
+ end),
+ }
+ end
+ end
end
end
diff --git a/script/core/definition.lua b/script/core/definition.lua
index b89aa751..e2d3b519 100644
--- a/script/core/definition.lua
+++ b/script/core/definition.lua
@@ -53,6 +53,7 @@ local accept = {
['doc.alias.name'] = true,
['doc.see.name'] = true,
['doc.see.field'] = true,
+ ['doc.cast.name'] = true,
}
local function checkRequire(source, offset)
diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua
index 3b23cb95..e1c262ea 100644
--- a/script/core/semantic-tokens.lua
+++ b/script/core/semantic-tokens.lua
@@ -652,6 +652,14 @@ local Care = util.switch()
type = define.TokenTypes.keyword,
}
end)
+ : case 'doc.cast.name'
+ : call(function (source, options, results)
+ results[#results+1] = {
+ start = source.start,
+ finish = source.finish,
+ type = define.TokenTypes.variable,
+ }
+ end)
local function buildTokens(uri, results)
local tokens = {}
diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua
index e10ef356..89a5ee9b 100644
--- a/script/parser/luadoc.lua
+++ b/script/parser/luadoc.lua
@@ -1235,7 +1235,6 @@ local docSwitch = util.switch()
start = getFinish(),
finish = getFinish(),
}
- result.casts[#result.casts+1] = block
if checkToken('symbol', '+', 1) then
block.mode = '+'
nextToken()
@@ -1261,6 +1260,10 @@ local docSwitch = util.switch()
end
end
+ if block.optional or block.extends then
+ result.casts[#result.casts+1] = block
+ end
+
if checkToken('symbol', ',', 1) then
nextToken()
else
diff --git a/script/vm/def.lua b/script/vm/def.lua
index b66e8fda..a0cb501e 100644
--- a/script/vm/def.lua
+++ b/script/vm/def.lua
@@ -79,6 +79,13 @@ simpleSwitch = util.switch()
pushResult(source.node)
end
end)
+ : case 'doc.cast.name'
+ : call(function (source, pushResult)
+ local loc = guide.getLocal(source, source[1], source.start)
+ if loc then
+ pushResult(loc)
+ end
+ end)
local searchFieldSwitch = util.switch()
: case 'table'
diff --git a/test/completion/common.lua b/test/completion/common.lua
index 1fc37bb5..613f9b0c 100644
--- a/test/completion/common.lua
+++ b/test/completion/common.lua
@@ -3324,3 +3324,27 @@ x.y.<??>
kind = define.CompletionItemKind.Field,
}
}
+
+TEST [[
+local xyz
+
+---@cast <??>
+]]
+{
+ {
+ label = 'xyz',
+ kind = define.CompletionItemKind.Variable,
+ },
+}
+
+TEST [[
+local xyz
+
+---@cast x<??>
+]]
+{
+ {
+ label = 'xyz',
+ kind = define.CompletionItemKind.Variable,
+ }
+}
diff --git a/test/definition/luadoc.lua b/test/definition/luadoc.lua
index 19b4421b..47859b15 100644
--- a/test/definition/luadoc.lua
+++ b/test/definition/luadoc.lua
@@ -893,3 +893,9 @@ TEST [[
---@type XXX<<?YYY?>>
]]
+
+TEST [[
+local <!x!>
+
+---@cast <?x?> integer
+]]