Skip to content

Commit

Permalink
Merge branch 'LuaLS:master' into rcklos
Browse files Browse the repository at this point in the history
  • Loading branch information
Rcklos authored Nov 1, 2024
2 parents 760e404 + 3894968 commit 6ac3f3d
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 17 deletions.
16 changes: 16 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,23 @@

## Unreleased
<!-- Add all new changes here. They will be moved under a version at release -->

## 3.12.0
`2024-10-30`
* `NEW` Support importing `enum` through class name suffix matching in quick fixes, allowing the import of `enum` from `table.table.enum; return table`.
* `NEW` Support limited multiline annotations
```lua
---@type {
--- x: number,
--- y: number,
--- z: number,
---}
local point --> local point: { x: number, y: number, z: number }
```
* `FIX` A regression related to type narrow and generic param introduced since `v3.10.1`
* `FIX` Parse storagePath to improve reliability of resolving ${addons} placeholder
* `FIX` Reference should also look in tablefield
* `FIX` Determine that the index of `{...}` is an integer when iterating

## 3.11.1
`2024-10-9`
Expand Down
7 changes: 4 additions & 3 deletions script/core/code-action.lua
Original file line number Diff line number Diff line change
Expand Up @@ -695,13 +695,13 @@ local function checkMissingRequire(results, uri, start, finish)
end

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

for _, target in ipairs(findRequireTargets(visiblePaths)) do
results[#results+1] = {
title = lang.script('ACTION_AUTOREQUIRE', target, global),
title = lang.script('ACTION_AUTOREQUIRE', target .. (fullKeyPath or ''), global),
kind = 'refactor.rewrite',
command = {
title = 'autoRequire',
Expand All @@ -711,7 +711,8 @@ local function checkMissingRequire(results, uri, start, finish)
uri = guide.getUri(state.ast),
target = moduleFile,
name = global,
requireName = target
requireName = target,
fullKeyPath = fullKeyPath,
},
},
}
Expand Down
6 changes: 3 additions & 3 deletions script/core/command/autoRequire.lua
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ local function askAutoRequire(uri, visiblePaths)
return nameMap[result]
end

local function applyAutoRequire(uri, row, name, result, fmt)
local function applyAutoRequire(uri, row, name, result, fmt, fullKeyPath)
local quotedResult = ('%q'):format(result)
if fmt.quot == "'" then
quotedResult = ([['%s']]):format(quotedResult:sub(2, -2)
Expand All @@ -119,7 +119,7 @@ local function applyAutoRequire(uri, row, name, result, fmt)
if fmt.col and fmt.col > #text then
sp = (' '):rep(fmt.col - #text - 1)
end
text = ('local %s%s= require%s\n'):format(name, sp, quotedResult)
text = ('local %s%s= require%s%s\n'):format(name, sp, quotedResult, fullKeyPath)
client.editText(uri, {
{
start = guide.positionOf(row, 0),
Expand Down Expand Up @@ -159,6 +159,6 @@ return function (data)

local offset, fmt = findInsertRow(uri)
if offset and fmt then
applyAutoRequire(uri, offset, name, requireName, fmt)
applyAutoRequire(uri, offset, name, requireName, fmt, data.fullKeyPath or '')
end
end
59 changes: 59 additions & 0 deletions script/core/completion/auto-require.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ local rpath = require 'workspace.require-path'
local vm = require 'vm'
local matchKey = require 'core.matchkey'

local ipairs = ipairs

---@class auto-require
local m = {}

Expand Down Expand Up @@ -36,6 +38,7 @@ end
function m.check(state, word, position, callback)
local globals = util.arrayToHash(config.get(state.uri, 'Lua.diagnostics.globals'))
local locals = guide.getVisibleLocals(state.ast, position)
local hit = false
for uri in files.eachFile(state.uri) do
if uri == guide.getUri(state.ast) then
goto CONTINUE
Expand Down Expand Up @@ -85,12 +88,68 @@ function m.check(state, word, position, callback)
and vm.getDeprecated(targetSource.node) then
goto INNER_CONTINUE
end
hit = true
callback(uri, stemName, targetSource)
end
::INNER_CONTINUE::
end
::CONTINUE::
end
-- 如果没命中, 则检查枚举
if not hit then
local docs = vm.getDocSets(state.uri)
for _, doc in ipairs(docs) do
if doc.type ~= 'doc.enum' or vm.getDeprecated(doc) then
goto CONTINUE
end
-- 检查枚举名是否匹配
if not (doc.enum[1] == word or doc.enum[1]:match(".*%.([^%.]*)$") == word) then
goto CONTINUE
end
local uri = guide.getUri(doc)
local targetState = files.getState(uri)
if not targetState then
goto CONTINUE
end
local targetSource = m.getTargetSource(targetState)
if not targetSource or (targetSource.type ~= 'getlocal' and targetSource.type ~= 'table') or vm.getDeprecated(targetSource.node) then
goto CONTINUE
end
-- 枚举的完整路径
local fullKeyPath = ""
local node = doc.bindSource.parent
while node do
-- 检查是否可见
if not vm.isVisible(state.ast, node) then
goto CONTINUE
end
if node.type == 'setfield' or node.type == 'getfield' then
fullKeyPath = "." .. node.field[1] .. fullKeyPath
end
if node.type == 'getlocal' then
node = node.node
break
end
node = node.node
end
-- 匹配导出的值, 确定最终路径
if targetSource.node == node then
hit = true
elseif targetSource.type == 'table' then
for _, value in ipairs(targetSource) do
if value.value.node == node then
fullKeyPath = "." .. value.value[1] .. fullKeyPath
hit = true
break
end
end
end
if hit then
callback(guide.getUri(doc), nil, nil, fullKeyPath)
end
::CONTINUE::
end
end
end

files.watch(function (ev, uri)
Expand Down
6 changes: 3 additions & 3 deletions script/files.lua
Original file line number Diff line number Diff line change
Expand Up @@ -919,10 +919,10 @@ function m.resolvePathPlaceholders(path)
if addonsPath then
return addonsPath
end
local client = require 'client'
local storagePath = client.getOption('storagePath')
local client = require("client")
local storagePath = client.getOption("storagePath")
if storagePath then
addonsPath = storagePath .. "/addonManager/addons"
addonsPath = (fs.path(storagePath) / "addonManager" / "addons"):string()
else
-- Common path across OSes
local dataPath = "User/globalStorage/sumneko.lua/addonManager/addons"
Expand Down
40 changes: 35 additions & 5 deletions script/parser/luadoc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,30 @@ local function parseIndexField(parent)
return field
end

local function slideToNextLine()
if peekToken() then
return
end
local nextComment = NextComment(0, true)
if not nextComment then
return
end
local currentComment = NextComment(-1, true)
local currentLine = guide.rowColOf(currentComment.start)
local nextLine = guide.rowColOf(nextComment.start)
if currentLine + 1 ~= nextLine then
return
end
if nextComment.text:sub(1, 1) ~= '-' then
return
end
if nextComment.text:match '^%-%s*%@' then
return
end
NextComment()
parseTokens(nextComment.text:sub(2), nextComment.start + 2)
end

local function parseTable(parent)
if not checkToken('symbol', '{', 1) then
return nil
Expand All @@ -311,6 +335,7 @@ local function parseTable(parent)
}

while true do
slideToNextLine()
if checkToken('symbol', '}', 1) then
nextToken()
break
Expand Down Expand Up @@ -385,6 +410,7 @@ local function parseTuple(parent)

local index = 1
while true do
slideToNextLine()
if checkToken('symbol', ']', 1) then
nextToken()
break
Expand Down Expand Up @@ -500,6 +526,7 @@ local function parseTypeUnitFunction(parent)
return nil
end
while true do
slideToNextLine()
if checkToken('symbol', ')', 1) then
nextToken()
break
Expand Down Expand Up @@ -539,14 +566,17 @@ local function parseTypeUnitFunction(parent)
break
end
end
slideToNextLine()
if checkToken('symbol', ':', 1) then
nextToken()
slideToNextLine()
local needCloseParen
if checkToken('symbol', '(', 1) then
nextToken()
needCloseParen = true
end
while true do
slideToNextLine()
local name
try(function ()
local returnName = parseName('doc.return.name', typeUnit)
Expand Down Expand Up @@ -2139,10 +2169,10 @@ local function bindDocs(state)
state.ast.docs.groups[#state.ast.docs.groups+1] = binded
end
binded[#binded+1] = doc
if doc.specialBindGroup then
bindDocWithSources(sources, doc.specialBindGroup)
binded = nil
elseif isTailComment(text, doc) and doc.type ~= "doc.class" and doc.type ~= "doc.field" then
if doc.specialBindGroup then
bindDocWithSources(sources, doc.specialBindGroup)
binded = nil
elseif isTailComment(text, doc) and doc.type ~= "doc.class" and doc.type ~= "doc.field" then
bindDocWithSources(sources, binded)
binded = nil
else
Expand Down Expand Up @@ -2278,7 +2308,7 @@ return {
doc.special = src
doc.originalComment = comment
doc.virtual = true
doc.specialBindGroup = group
doc.specialBindGroup = group
ast.state.pluginDocs = pluginDocs
return doc
end
Expand Down
2 changes: 1 addition & 1 deletion script/vm/ref.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ local function searchWord(source, pushResult, defMap, fileNotify)
end)
end
---@async
guide.eachSourceTypes(state.ast, {'getfield', 'setfield'}, function (src)
guide.eachSourceTypes(state.ast, {'getfield', 'setfield', 'tablefield'}, function (src)
if src.field and src.field[1] == key then
checkDef(src)
await.delay()
Expand Down
2 changes: 1 addition & 1 deletion script/vm/type.lua
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ function vm.getTableKey(uri, tnode, vnode, reverse)
if field.type == 'tablefield' then
result:merge(vm.declareGlobal('type', 'string'))
end
if field.type == 'tableexp' then
if field.type == 'tableexp' or field.type == 'varargs' then
result:merge(vm.declareGlobal('type', 'integer'))
end
end
Expand Down
2 changes: 1 addition & 1 deletion test/command/auto-require.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function TEST(text)
files.setText(TESTURI, text)
EditResult = nil
local row, fmt = findInsertRow(TESTURI)
applyAutoRequire(TESTURI, row, name, name, fmt)
applyAutoRequire(TESTURI, row, name, name, fmt, "")
assert(util.equal(EditResult, expect))
files.remove(TESTURI)
end
Expand Down
10 changes: 10 additions & 0 deletions test/references/all.lua
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,13 @@ function TestB(param)
param:<!TestA!>()
end
]]

TEST [[
---@class A
---@field <~x~> number
---@type A
local t = {
<!x!> = 1
}
]]
8 changes: 8 additions & 0 deletions test/type_inference/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4591,3 +4591,11 @@ local function f(v) end
local <?r?> = f('')
]]

TEST 'integer' [[
local function F(...)
local t = {...}
for <?k?> in pairs(t) do
end
end
]]

0 comments on commit 6ac3f3d

Please sign in to comment.