Skip to content

Commit 6ac3f3d

Browse files
authored
Merge branch 'LuaLS:master' into rcklos
2 parents 760e404 + 3894968 commit 6ac3f3d

File tree

11 files changed

+141
-17
lines changed

11 files changed

+141
-17
lines changed

changelog.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,23 @@
22

33
## Unreleased
44
<!-- Add all new changes here. They will be moved under a version at release -->
5+
6+
## 3.12.0
7+
`2024-10-30`
8+
* `NEW` Support importing `enum` through class name suffix matching in quick fixes, allowing the import of `enum` from `table.table.enum; return table`.
9+
* `NEW` Support limited multiline annotations
10+
```lua
11+
---@type {
12+
--- x: number,
13+
--- y: number,
14+
--- z: number,
15+
---}
16+
local point --> local point: { x: number, y: number, z: number }
17+
```
518
* `FIX` A regression related to type narrow and generic param introduced since `v3.10.1`
19+
* `FIX` Parse storagePath to improve reliability of resolving ${addons} placeholder
20+
* `FIX` Reference should also look in tablefield
21+
* `FIX` Determine that the index of `{...}` is an integer when iterating
622

723
## 3.11.1
824
`2024-10-9`

script/core/code-action.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -695,13 +695,13 @@ local function checkMissingRequire(results, uri, start, finish)
695695
end
696696

697697
local function addRequires(global, endpos)
698-
autoreq.check(state, global, endpos, function(moduleFile, _stemname, _targetSource)
698+
autoreq.check(state, global, endpos, function (moduleFile, _stemname, _targetSource, fullKeyPath)
699699
local visiblePaths = rpath.getVisiblePath(uri, furi.decode(moduleFile))
700700
if not visiblePaths or #visiblePaths == 0 then return end
701701

702702
for _, target in ipairs(findRequireTargets(visiblePaths)) do
703703
results[#results+1] = {
704-
title = lang.script('ACTION_AUTOREQUIRE', target, global),
704+
title = lang.script('ACTION_AUTOREQUIRE', target .. (fullKeyPath or ''), global),
705705
kind = 'refactor.rewrite',
706706
command = {
707707
title = 'autoRequire',
@@ -711,7 +711,8 @@ local function checkMissingRequire(results, uri, start, finish)
711711
uri = guide.getUri(state.ast),
712712
target = moduleFile,
713713
name = global,
714-
requireName = target
714+
requireName = target,
715+
fullKeyPath = fullKeyPath,
715716
},
716717
},
717718
}

script/core/command/autoRequire.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ local function askAutoRequire(uri, visiblePaths)
101101
return nameMap[result]
102102
end
103103

104-
local function applyAutoRequire(uri, row, name, result, fmt)
104+
local function applyAutoRequire(uri, row, name, result, fmt, fullKeyPath)
105105
local quotedResult = ('%q'):format(result)
106106
if fmt.quot == "'" then
107107
quotedResult = ([['%s']]):format(quotedResult:sub(2, -2)
@@ -119,7 +119,7 @@ local function applyAutoRequire(uri, row, name, result, fmt)
119119
if fmt.col and fmt.col > #text then
120120
sp = (' '):rep(fmt.col - #text - 1)
121121
end
122-
text = ('local %s%s= require%s\n'):format(name, sp, quotedResult)
122+
text = ('local %s%s= require%s%s\n'):format(name, sp, quotedResult, fullKeyPath)
123123
client.editText(uri, {
124124
{
125125
start = guide.positionOf(row, 0),
@@ -159,6 +159,6 @@ return function (data)
159159

160160
local offset, fmt = findInsertRow(uri)
161161
if offset and fmt then
162-
applyAutoRequire(uri, offset, name, requireName, fmt)
162+
applyAutoRequire(uri, offset, name, requireName, fmt, data.fullKeyPath or '')
163163
end
164164
end

script/core/completion/auto-require.lua

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ local rpath = require 'workspace.require-path'
88
local vm = require 'vm'
99
local matchKey = require 'core.matchkey'
1010

11+
local ipairs = ipairs
12+
1113
---@class auto-require
1214
local m = {}
1315

@@ -36,6 +38,7 @@ end
3638
function m.check(state, word, position, callback)
3739
local globals = util.arrayToHash(config.get(state.uri, 'Lua.diagnostics.globals'))
3840
local locals = guide.getVisibleLocals(state.ast, position)
41+
local hit = false
3942
for uri in files.eachFile(state.uri) do
4043
if uri == guide.getUri(state.ast) then
4144
goto CONTINUE
@@ -85,12 +88,68 @@ function m.check(state, word, position, callback)
8588
and vm.getDeprecated(targetSource.node) then
8689
goto INNER_CONTINUE
8790
end
91+
hit = true
8892
callback(uri, stemName, targetSource)
8993
end
9094
::INNER_CONTINUE::
9195
end
9296
::CONTINUE::
9397
end
98+
-- 如果没命中, 则检查枚举
99+
if not hit then
100+
local docs = vm.getDocSets(state.uri)
101+
for _, doc in ipairs(docs) do
102+
if doc.type ~= 'doc.enum' or vm.getDeprecated(doc) then
103+
goto CONTINUE
104+
end
105+
-- 检查枚举名是否匹配
106+
if not (doc.enum[1] == word or doc.enum[1]:match(".*%.([^%.]*)$") == word) then
107+
goto CONTINUE
108+
end
109+
local uri = guide.getUri(doc)
110+
local targetState = files.getState(uri)
111+
if not targetState then
112+
goto CONTINUE
113+
end
114+
local targetSource = m.getTargetSource(targetState)
115+
if not targetSource or (targetSource.type ~= 'getlocal' and targetSource.type ~= 'table') or vm.getDeprecated(targetSource.node) then
116+
goto CONTINUE
117+
end
118+
-- 枚举的完整路径
119+
local fullKeyPath = ""
120+
local node = doc.bindSource.parent
121+
while node do
122+
-- 检查是否可见
123+
if not vm.isVisible(state.ast, node) then
124+
goto CONTINUE
125+
end
126+
if node.type == 'setfield' or node.type == 'getfield' then
127+
fullKeyPath = "." .. node.field[1] .. fullKeyPath
128+
end
129+
if node.type == 'getlocal' then
130+
node = node.node
131+
break
132+
end
133+
node = node.node
134+
end
135+
-- 匹配导出的值, 确定最终路径
136+
if targetSource.node == node then
137+
hit = true
138+
elseif targetSource.type == 'table' then
139+
for _, value in ipairs(targetSource) do
140+
if value.value.node == node then
141+
fullKeyPath = "." .. value.value[1] .. fullKeyPath
142+
hit = true
143+
break
144+
end
145+
end
146+
end
147+
if hit then
148+
callback(guide.getUri(doc), nil, nil, fullKeyPath)
149+
end
150+
::CONTINUE::
151+
end
152+
end
94153
end
95154

96155
files.watch(function (ev, uri)

script/files.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -919,10 +919,10 @@ function m.resolvePathPlaceholders(path)
919919
if addonsPath then
920920
return addonsPath
921921
end
922-
local client = require 'client'
923-
local storagePath = client.getOption('storagePath')
922+
local client = require("client")
923+
local storagePath = client.getOption("storagePath")
924924
if storagePath then
925-
addonsPath = storagePath .. "/addonManager/addons"
925+
addonsPath = (fs.path(storagePath) / "addonManager" / "addons"):string()
926926
else
927927
-- Common path across OSes
928928
local dataPath = "User/globalStorage/sumneko.lua/addonManager/addons"

script/parser/luadoc.lua

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,30 @@ local function parseIndexField(parent)
298298
return field
299299
end
300300

301+
local function slideToNextLine()
302+
if peekToken() then
303+
return
304+
end
305+
local nextComment = NextComment(0, true)
306+
if not nextComment then
307+
return
308+
end
309+
local currentComment = NextComment(-1, true)
310+
local currentLine = guide.rowColOf(currentComment.start)
311+
local nextLine = guide.rowColOf(nextComment.start)
312+
if currentLine + 1 ~= nextLine then
313+
return
314+
end
315+
if nextComment.text:sub(1, 1) ~= '-' then
316+
return
317+
end
318+
if nextComment.text:match '^%-%s*%@' then
319+
return
320+
end
321+
NextComment()
322+
parseTokens(nextComment.text:sub(2), nextComment.start + 2)
323+
end
324+
301325
local function parseTable(parent)
302326
if not checkToken('symbol', '{', 1) then
303327
return nil
@@ -311,6 +335,7 @@ local function parseTable(parent)
311335
}
312336

313337
while true do
338+
slideToNextLine()
314339
if checkToken('symbol', '}', 1) then
315340
nextToken()
316341
break
@@ -385,6 +410,7 @@ local function parseTuple(parent)
385410

386411
local index = 1
387412
while true do
413+
slideToNextLine()
388414
if checkToken('symbol', ']', 1) then
389415
nextToken()
390416
break
@@ -500,6 +526,7 @@ local function parseTypeUnitFunction(parent)
500526
return nil
501527
end
502528
while true do
529+
slideToNextLine()
503530
if checkToken('symbol', ')', 1) then
504531
nextToken()
505532
break
@@ -539,14 +566,17 @@ local function parseTypeUnitFunction(parent)
539566
break
540567
end
541568
end
569+
slideToNextLine()
542570
if checkToken('symbol', ':', 1) then
543571
nextToken()
572+
slideToNextLine()
544573
local needCloseParen
545574
if checkToken('symbol', '(', 1) then
546575
nextToken()
547576
needCloseParen = true
548577
end
549578
while true do
579+
slideToNextLine()
550580
local name
551581
try(function ()
552582
local returnName = parseName('doc.return.name', typeUnit)
@@ -2139,10 +2169,10 @@ local function bindDocs(state)
21392169
state.ast.docs.groups[#state.ast.docs.groups+1] = binded
21402170
end
21412171
binded[#binded+1] = doc
2142-
if doc.specialBindGroup then
2143-
bindDocWithSources(sources, doc.specialBindGroup)
2144-
binded = nil
2145-
elseif isTailComment(text, doc) and doc.type ~= "doc.class" and doc.type ~= "doc.field" then
2172+
if doc.specialBindGroup then
2173+
bindDocWithSources(sources, doc.specialBindGroup)
2174+
binded = nil
2175+
elseif isTailComment(text, doc) and doc.type ~= "doc.class" and doc.type ~= "doc.field" then
21462176
bindDocWithSources(sources, binded)
21472177
binded = nil
21482178
else
@@ -2278,7 +2308,7 @@ return {
22782308
doc.special = src
22792309
doc.originalComment = comment
22802310
doc.virtual = true
2281-
doc.specialBindGroup = group
2311+
doc.specialBindGroup = group
22822312
ast.state.pluginDocs = pluginDocs
22832313
return doc
22842314
end

script/vm/ref.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ local function searchWord(source, pushResult, defMap, fileNotify)
109109
end)
110110
end
111111
---@async
112-
guide.eachSourceTypes(state.ast, {'getfield', 'setfield'}, function (src)
112+
guide.eachSourceTypes(state.ast, {'getfield', 'setfield', 'tablefield'}, function (src)
113113
if src.field and src.field[1] == key then
114114
checkDef(src)
115115
await.delay()

script/vm/type.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ function vm.getTableKey(uri, tnode, vnode, reverse)
720720
if field.type == 'tablefield' then
721721
result:merge(vm.declareGlobal('type', 'string'))
722722
end
723-
if field.type == 'tableexp' then
723+
if field.type == 'tableexp' or field.type == 'varargs' then
724724
result:merge(vm.declareGlobal('type', 'integer'))
725725
end
726726
end

test/command/auto-require.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function TEST(text)
2323
files.setText(TESTURI, text)
2424
EditResult = nil
2525
local row, fmt = findInsertRow(TESTURI)
26-
applyAutoRequire(TESTURI, row, name, name, fmt)
26+
applyAutoRequire(TESTURI, row, name, name, fmt, "")
2727
assert(util.equal(EditResult, expect))
2828
files.remove(TESTURI)
2929
end

test/references/all.lua

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,13 @@ function TestB(param)
139139
param:<!TestA!>()
140140
end
141141
]]
142+
143+
TEST [[
144+
---@class A
145+
---@field <~x~> number
146+
147+
---@type A
148+
local t = {
149+
<!x!> = 1
150+
}
151+
]]

0 commit comments

Comments
 (0)