summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/test.yml2
m---------3rd/bee.lua0
m---------3rd/luamake0
-rw-r--r--locale/en-us/setting.lua6
-rw-r--r--locale/pt-br/setting.lua6
-rw-r--r--locale/zh-cn/setting.lua6
-rw-r--r--locale/zh-tw/setting.lua6
-rw-r--r--make.lua18
-rw-r--r--make/detect_platform.lua10
-rw-r--r--script/cli/doc.lua8
-rw-r--r--script/client.lua4
-rw-r--r--script/config/template.lua1
-rw-r--r--script/core/command/autoRequire.lua5
-rw-r--r--script/core/completion/completion.lua52
-rw-r--r--script/core/diagnostics/undefined-doc-name.lua13
-rw-r--r--script/core/highlight.lua4
-rw-r--r--script/core/hover/description.lua3
-rw-r--r--script/encoder/ansi.lua2
-rw-r--r--script/file-uri.lua4
-rw-r--r--script/files.lua6
-rw-r--r--script/fs-utility.lua7
-rw-r--r--script/gc.lua3
-rw-r--r--script/json-edit.lua13
-rw-r--r--script/parser/compile.lua27
-rw-r--r--script/parser/guide.lua3
-rw-r--r--script/parser/luadoc.lua2
-rw-r--r--script/plugin.lua1
-rw-r--r--script/proto/proto.lua2
-rw-r--r--script/timer.lua13
-rw-r--r--script/vm/compiler.lua62
-rw-r--r--script/vm/visible.lua10
-rw-r--r--script/workspace/require-path.lua2
-rw-r--r--script/workspace/scope.lua6
-rw-r--r--script/workspace/workspace.lua4
-rw-r--r--test/code_action/init.lua1
-rw-r--r--test/crossfile/completion.lua2
-rw-r--r--test/crossfile/definition.lua2
-rw-r--r--test/diagnostics/await-in-sync.lua2
-rw-r--r--test/diagnostics/redundant-parameter.lua2
-rw-r--r--test/document_symbol/init.lua1
-rw-r--r--test/hover/init.lua4
-rw-r--r--test/signature/init.lua14
-rw-r--r--test/tclient/tests/jump-source.lua2
43 files changed, 217 insertions, 124 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 7414d190..e8ff3632 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -7,7 +7,7 @@ jobs:
matrix:
include:
- { os: ubuntu-20.04, platform: linux-x64 }
- - { os: macos-latest, platform: darwin-x64 }
+ - { os: macos-14, platform: darwin-arm64 }
- { os: windows-latest, platform: win32-x64 }
runs-on: ${{ matrix.os }}
steps:
diff --git a/3rd/bee.lua b/3rd/bee.lua
-Subproject dfed9f99d272fedb70c8161d9250918c17d285b
+Subproject 5567822ac88b3f0a027518d6cf1e450999bc7e2
diff --git a/3rd/luamake b/3rd/luamake
-Subproject 13bf00fb858a24c709ddbdc372ec01cc645609b
+Subproject 50ea48f667764b25bc10d14eb21c0800f34c59f
diff --git a/locale/en-us/setting.lua b/locale/en-us/setting.lua
index 80926d12..9ef46b86 100644
--- a/locale/en-us/setting.lua
+++ b/locale/en-us/setting.lua
@@ -293,6 +293,12 @@ When checking the type of union type, ignore the `nil` in it.
When this setting is `false`, the `number|nil` type cannot be assigned to the `number` type. It can be with `true`.
]]
+config.type.inferParamType =
+[[
+When a parameter type is not annotated, it is inferred from the function's call sites.
+
+When this setting is `false`, the type of the parameter is `any` when it is not annotated.
+]]
config.doc.privateName =
'Treat specific field names as private, e.g. `m_*` means `XXX.m_id` and `XXX.m_type` are private, witch can only be accessed in the class where the definition is located.'
config.doc.protectedName =
diff --git a/locale/pt-br/setting.lua b/locale/pt-br/setting.lua
index 4e23e0ff..6ececcd3 100644
--- a/locale/pt-br/setting.lua
+++ b/locale/pt-br/setting.lua
@@ -293,6 +293,12 @@ When checking the type of union type, ignore the `nil` in it.
When this setting is `false`, the `number|nil` type cannot be assigned to the `number` type. It can be with `true`.
]]
+config.type.inferParamType = -- TODO: need translate!
+[[
+When the parameter type is not annotated, the parameter type is inferred from the function's incoming parameters.
+
+When this setting is `false`, the type of the parameter is `any` when it is not annotated.
+]]
config.doc.privateName = -- TODO: need translate!
'Treat specific field names as private, e.g. `m_*` means `XXX.m_id` and `XXX.m_type` are private, witch can only be accessed in the class where the definition is located.'
config.doc.protectedName = -- TODO: need translate!
diff --git a/locale/zh-cn/setting.lua b/locale/zh-cn/setting.lua
index c4ec1b55..78e7fb68 100644
--- a/locale/zh-cn/setting.lua
+++ b/locale/zh-cn/setting.lua
@@ -292,6 +292,12 @@ config.type.weakNilCheck =
此设置为 `false` 时,`numer|nil` 类型无法赋给 `number` 类型;为 `true` 是则可以。
]]
+config.type.inferParamType =
+[[
+未注释参数类型时,参数类型由函数传入参数推断。
+
+如果设置为 "false",则在未注释时,参数类型为 "any"。
+]]
config.doc.privateName =
'将特定名称的字段视为私有,例如 `m_*` 意味着 `XXX.m_id` 与 `XXX.m_type` 是私有字段,只能在定义所在的类中访问。'
config.doc.protectedName =
diff --git a/locale/zh-tw/setting.lua b/locale/zh-tw/setting.lua
index c8e0dbfc..2b43e954 100644
--- a/locale/zh-tw/setting.lua
+++ b/locale/zh-tw/setting.lua
@@ -292,6 +292,12 @@ When checking the type of union type, ignore the `nil` in it.
When this setting is `false`, the `number|nil` type cannot be assigned to the `number` type. It can be with `true`.
]]
+config.type.inferParamType = -- TODO: need translate!
+[[
+未注释参数类型时,参数类型由函数传入参数推断。
+
+如果设置为 "false",则在未注释时,参数类型为 "any"。
+]]
config.doc.privateName = -- TODO: need translate!
'Treat specific field names as private, e.g. `m_*` means `XXX.m_id` and `XXX.m_type` are private, witch can only be accessed in the class where the definition is located.'
config.doc.protectedName = -- TODO: need translate!
diff --git a/make.lua b/make.lua
index 25234c75..e532bbf1 100644
--- a/make.lua
+++ b/make.lua
@@ -55,21 +55,21 @@ lm:executable "lua-language-server" {
}
local platform = require 'bee.platform'
-local exe = platform.OS == 'Windows' and ".exe" or ""
+local exe = platform.os == 'windows' and ".exe" or ""
lm:copy "copy_lua-language-server" {
- input = lm.bindir .. "/lua-language-server" .. exe,
- output = "bin/lua-language-server" .. exe,
+ inputs = "$bin/lua-language-server" .. exe,
+ outputs = "bin/lua-language-server" .. exe,
}
lm:copy "copy_bootstrap" {
- input = "make/bootstrap.lua",
- output = "bin/main.lua",
+ inputs = "make/bootstrap.lua",
+ outputs = "bin/main.lua",
}
lm:msvc_copydll 'copy_vcrt' {
type = "vcrt",
- output = "bin",
+ outputs = "bin",
}
lm:phony "all" {
@@ -93,7 +93,7 @@ if lm.notest then
end
lm:rule "run-bee-test" {
- lm.bindir .. "/lua-language-server" .. exe, "$in",
+ "$bin/lua-language-server" .. exe, "$in",
description = "Run test: $in.",
pool = "console",
}
@@ -107,13 +107,13 @@ lm:rule "run-unit-test" {
lm:build "bee-test" {
rule = "run-bee-test",
deps = { "lua-language-server", "copy_script" },
- input = "3rd/bee.lua/test/test.lua",
+ inputs = "3rd/bee.lua/test/test.lua",
}
lm:build 'unit-test' {
rule = "run-unit-test",
deps = { "bee-test", "all" },
- input = "test.lua",
+ inputs = "test.lua",
}
lm:default {
diff --git a/make/detect_platform.lua b/make/detect_platform.lua
index 52207f95..4b62298f 100644
--- a/make/detect_platform.lua
+++ b/make/detect_platform.lua
@@ -2,7 +2,7 @@ local lm = require 'luamake'
local platform = require 'bee.platform'
-if platform.OS == 'macOS' then
+if platform.os == 'macos' then
if lm.platform == nil then
elseif lm.platform == "darwin-arm64" then
lm.target = "arm64-apple-macos11"
@@ -11,7 +11,7 @@ if platform.OS == 'macOS' then
else
error "unknown platform"
end
-elseif platform.OS == 'Windows' then
+elseif platform.os == 'windows' then
if lm.platform == nil then
elseif lm.platform == "win32-ia32" then
lm.arch = "x86"
@@ -20,7 +20,7 @@ elseif platform.OS == 'Windows' then
else
error "unknown platform"
end
-elseif platform.OS == 'Linux' then
+elseif platform.os == 'linux' then
if lm.platform == nil then
elseif lm.platform == "linux-x64" then
elseif lm.platform == "linux-arm64" then
@@ -52,7 +52,7 @@ local ARCH <const> = {
}
local function detectArch()
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
return detectWindowsArch()
end
local posixArch = detectPosixArch()
@@ -67,5 +67,5 @@ local function targetPlatformArch()
end
if not lm.notest then
- lm.notest = (platform.OS ~= 'Windows' and targetPlatformArch() ~= detectArch())
+ lm.notest = (platform.os ~= 'windows' and targetPlatformArch() ~= detectArch())
end
diff --git a/script/cli/doc.lua b/script/cli/doc.lua
index 1f0e977e..7ba3ae68 100644
--- a/script/cli/doc.lua
+++ b/script/cli/doc.lua
@@ -189,6 +189,10 @@ local function collectTypes(global, results)
field.rawdesc = getDesc(source, true)
field.extends = packObject(source.value)
field.visible = vm.getVisibleType(source)
+ local depr = vm.getDeprecated(source)
+ if (depr and not depr.versions) then
+ field.deprecated = true
+ end
return
end
if source.type == 'tableindex' then
@@ -250,6 +254,10 @@ local function collectVars(global, results)
result.rawdesc = result.rawdesc or getDesc(set, true)
result.defines[#result.defines].extends['desc'] = getDesc(set)
result.defines[#result.defines].extends['rawdesc'] = getDesc(set, true)
+ local depr = vm.getDeprecated(set)
+ if (depr and not depr.versions) then
+ result.defines[#result.defines].extends['deprecated'] = true
+ end
end
end
if #result.defines == 0 then
diff --git a/script/client.lua b/script/client.lua
index a8eda9b8..e328dc52 100644
--- a/script/client.lua
+++ b/script/client.lua
@@ -278,7 +278,7 @@ local function searchPatchInfo(cfg, rawKey)
}
end
----@param uri uri
+---@param uri? uri
---@param cfg table
---@param change config.change
---@return json.patch?
@@ -330,7 +330,7 @@ local function makeConfigPatch(uri, cfg, change)
return nil
end
----@param uri uri
+---@param uri? uri
---@param path string
---@param changes config.change[]
---@return string?
diff --git a/script/config/template.lua b/script/config/template.lua
index 2a30d2ea..49907419 100644
--- a/script/config/template.lua
+++ b/script/config/template.lua
@@ -397,6 +397,7 @@ local template = {
['Lua.type.castNumberToInteger'] = Type.Boolean >> true,
['Lua.type.weakUnionCheck'] = Type.Boolean >> false,
['Lua.type.weakNilCheck'] = Type.Boolean >> false,
+ ['Lua.type.inferParamType'] = Type.Boolean >> false,
['Lua.doc.privateName'] = Type.Array(Type.String),
['Lua.doc.protectedName'] = Type.Array(Type.String),
['Lua.doc.packageName'] = Type.Array(Type.String),
diff --git a/script/core/command/autoRequire.lua b/script/core/command/autoRequire.lua
index a96cc918..9f3ff929 100644
--- a/script/core/command/autoRequire.lua
+++ b/script/core/command/autoRequire.lua
@@ -132,6 +132,7 @@ end
---@async
return function (data)
+ ---@type uri
local uri = data.uri
local target = data.target
local name = data.name
@@ -158,5 +159,7 @@ return function (data)
end
local offset, fmt = findInsertRow(uri)
- applyAutoRequire(uri, offset, name, requireName, fmt)
+ if offset and fmt then
+ applyAutoRequire(uri, offset, name, requireName, fmt)
+ end
end
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index acb3adbe..d047dd56 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -147,6 +147,9 @@ end
local function findParent(state, position)
local text = state.lua
+ if not text then
+ return
+ end
local offset = guide.positionToOffset(state, position)
for i = offset, 1, -1 do
local char = text:sub(i, i)
@@ -675,6 +678,7 @@ local function checkGlobal(state, word, startPos, position, parent, oop, results
end
---@async
+---@param parent parser.object
local function checkField(state, word, start, position, parent, oop, results)
if parent.tag == '_ENV' or parent.special == '_G' then
local globals = vm.getGlobalSets(state.uri, 'variable')
@@ -955,8 +959,7 @@ local function checkFunctionArgByDocParam(state, word, startPos, results)
end
end
-local function isAfterLocal(state, startPos)
- local text = state.lua
+local function isAfterLocal(state, text, startPos)
local offset = guide.positionToOffset(state, startPos)
local pos = lookBackward.skipSpace(text, offset)
local word = lookBackward.findWord(text, pos)
@@ -965,6 +968,8 @@ end
local function collectRequireNames(mode, myUri, literal, source, smark, position, results)
local collect = {}
+ local source_start = source and smark and (source.start + #smark) or position
+ local source_finish = source and smark and (source.finish - #smark) or position
if mode == 'require' then
for uri in files.eachFile(myUri) do
if myUri == uri then
@@ -978,8 +983,8 @@ local function collectRequireNames(mode, myUri, literal, source, smark, position
if not collect[info.name] then
collect[info.name] = {
textEdit = {
- start = smark and (source.start + #smark) or position,
- finish = smark and (source.finish - #smark) or position,
+ start = source_start,
+ finish = source_finish,
newText = smark and info.name or util.viewString(info.name),
},
path = relative,
@@ -1006,8 +1011,8 @@ local function collectRequireNames(mode, myUri, literal, source, smark, position
if not collect[open] then
collect[open] = {
textEdit = {
- start = smark and (source.start + #smark) or position,
- finish = smark and (source.finish - #smark) or position,
+ start = source_start,
+ finish = source_finish,
newText = smark and open or util.viewString(open),
},
path = path,
@@ -1034,8 +1039,8 @@ local function collectRequireNames(mode, myUri, literal, source, smark, position
if not collect[path] then
collect[path] = {
textEdit = {
- start = smark and (source.start + #smark) or position,
- finish = smark and (source.finish - #smark) or position,
+ start = source_start,
+ finish = source_finish,
newText = smark and path or util.viewString(path),
}
}
@@ -1097,6 +1102,9 @@ end
local function checkLenPlusOne(state, position, results)
local text = state.lua
+ if not text then
+ return
+ end
guide.eachSourceContain(state.ast, position, function (source)
if source.type == 'getindex'
or source.type == 'setindex' then
@@ -1392,6 +1400,9 @@ end
local function checkEqualEnum(state, position, results)
local text = state.lua
+ if not text then
+ return
+ end
local start = lookBackward.findTargetSymbol(text, guide.positionToOffset(state, position), '=')
if not start then
return
@@ -1493,6 +1504,9 @@ local function tryWord(state, position, triggerCharacter, results)
return
end
local text = state.lua
+ if not text then
+ return
+ end
local offset = guide.positionToOffset(state, position)
local finish = lookBackward.skipSpace(text, offset)
local word, start = lookBackward.findWord(text, offset)
@@ -1518,7 +1532,7 @@ local function tryWord(state, position, triggerCharacter, results)
checkProvideLocal(state, word, startPos, results)
checkFunctionArgByDocParam(state, word, startPos, results)
else
- local afterLocal = isAfterLocal(state, startPos)
+ local afterLocal = isAfterLocal(state, text, startPos)
local stop = checkKeyWord(state, startPos, position, word, hasSpace, afterLocal, results)
if stop then
return
@@ -1530,8 +1544,10 @@ local function tryWord(state, position, triggerCharacter, results)
checkLocal(state, word, startPos, results)
checkTableField(state, word, startPos, results)
local env = guide.getENV(state.ast, startPos)
- checkGlobal(state, word, startPos, position, env, false, results)
- checkModule(state, word, startPos, results)
+ if env then
+ checkGlobal(state, word, startPos, position, env, false, results)
+ checkModule(state, word, startPos, results)
+ end
end
end
end
@@ -1592,6 +1608,9 @@ end
local function checkTableLiteralField(state, position, tbl, fields, results)
local text = state.lua
+ if not text then
+ return
+ end
local mark = {}
for _, field in ipairs(tbl) do
if field.type == 'tablefield'
@@ -1610,9 +1629,11 @@ local function checkTableLiteralField(state, position, tbl, fields, results)
local left = lookBackward.findWord(text, guide.positionToOffset(state, position))
if not left then
local pos = lookBackward.findAnyOffset(text, guide.positionToOffset(state, position))
- local char = text:sub(pos, pos)
- if char == '{' or char == ',' or char == ';' then
- left = ''
+ if pos then
+ local char = text:sub(pos, pos)
+ if char == '{' or char == ',' or char == ';' then
+ left = ''
+ end
end
end
if left then
@@ -1801,6 +1822,7 @@ local function getluaDocByContain(state, position)
return result
end
+---@return parser.state.err?, parser.object?
local function getluaDocByErr(state, start, position)
local targetError
for _, err in ipairs(state.errs) do
@@ -2008,7 +2030,7 @@ local function tryluaDocByErr(state, position, err, docState, results)
for _, doc in ipairs(vm.getDocSets(state.uri)) do
if doc.type == 'doc.class'
and not used[doc.class[1]]
- and doc.class[1] ~= docState.class[1] then
+ and docState and doc.class[1] ~= docState.class[1] then
used[doc.class[1]] = true
results[#results+1] = {
label = doc.class[1],
diff --git a/script/core/diagnostics/undefined-doc-name.lua b/script/core/diagnostics/undefined-doc-name.lua
index 3c8ed469..1c55f3bf 100644
--- a/script/core/diagnostics/undefined-doc-name.lua
+++ b/script/core/diagnostics/undefined-doc-name.lua
@@ -13,16 +13,6 @@ return function (uri, callback)
return
end
- local function hasNameOfGeneric(name, source)
- if not source.typeGeneric then
- return false
- end
- if not source.typeGeneric[name] then
- return false
- end
- return true
- end
-
guide.eachSource(state.ast.docs, function (source)
if source.type ~= 'doc.extends.name'
and source.type ~= 'doc.type.name' then
@@ -35,8 +25,7 @@ return function (uri, callback)
if name == '...' or name == '_' or name == 'self' then
return
end
- if #vm.getDocSets(uri, name) > 0
- or hasNameOfGeneric(name, source) then
+ if #vm.getDocSets(uri, name) > 0 then
return
end
callback {
diff --git a/script/core/highlight.lua b/script/core/highlight.lua
index 80088680..72214672 100644
--- a/script/core/highlight.lua
+++ b/script/core/highlight.lua
@@ -63,7 +63,7 @@ local function checkInIf(state, source, text, position)
local endA = endB - #'end' + 1
if position >= source.finish - #'end'
and position <= source.finish
- and text:sub(endA, endB) == 'end' then
+ and text and text:sub(endA, endB) == 'end' then
return true
end
-- 检查每个子模块
@@ -83,7 +83,7 @@ local function makeIf(state, source, text, callback)
-- end
local endB = guide.positionToOffset(state, source.finish)
local endA = endB - #'end' + 1
- if text:sub(endA, endB) == 'end' then
+ if text and text:sub(endA, endB) == 'end' then
callback(source.finish - #'end', source.finish)
end
-- 每个子模块
diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua
index 75189b06..0cbcc835 100644
--- a/script/core/hover/description.lua
+++ b/script/core/hover/description.lua
@@ -449,7 +449,8 @@ local function tyrDocParamComment(source)
or source.type == 'getlocal' then
source = source.node
end
- if source.type ~= 'local' then
+ if source.type ~= 'local'
+ and source.type ~= '...' then
return
end
if source.parent.type ~= 'funcargs' then
diff --git a/script/encoder/ansi.lua b/script/encoder/ansi.lua
index 7cb64ec3..f89ddbc1 100644
--- a/script/encoder/ansi.lua
+++ b/script/encoder/ansi.lua
@@ -1,7 +1,7 @@
local platform = require 'bee.platform'
local windows
-if platform.OS == 'Windows' then
+if platform.os == 'windows' then
windows = require 'bee.windows'
end
diff --git a/script/file-uri.lua b/script/file-uri.lua
index 8a075f7e..192f3ab5 100644
--- a/script/file-uri.lua
+++ b/script/file-uri.lua
@@ -25,7 +25,7 @@ local m = {}
---@return uri uri
function m.encode(path)
local authority = ''
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
path = path:gsub('\\', '/')
end
@@ -82,7 +82,7 @@ function m.decode(uri)
else
value = path
end
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
value = value:gsub('/', '\\')
end
return value
diff --git a/script/files.lua b/script/files.lua
index 8cc7a5ab..b9df5695 100644
--- a/script/files.lua
+++ b/script/files.lua
@@ -78,7 +78,7 @@ end
---@param uri uri
---@return uri
function m.getRealUri(uri)
- if platform.OS ~= 'Windows' then
+ if platform.os ~= 'windows' then
return furi.normalize(uri)
end
if not furi.isValid(uri) then
@@ -833,7 +833,7 @@ function m.isDll(uri)
if not ext then
return false
end
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
if ext == 'dll' then
return true
end
@@ -932,7 +932,7 @@ function m.normalize(path)
break
end
end
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
path = path:gsub('[/\\]+', '\\')
:gsub('[/\\]+$', '')
:gsub('^(%a:)$', '%1\\')
diff --git a/script/fs-utility.lua b/script/fs-utility.lua
index 9a45b1cc..35b336fe 100644
--- a/script/fs-utility.lua
+++ b/script/fs-utility.lua
@@ -128,6 +128,7 @@ function dfs:__div(filename)
return new
end
+---@package
function dfs:_open(index)
local paths = split(self.path, '[/\\]')
local current = self.files
@@ -147,6 +148,7 @@ function dfs:_open(index)
return current
end
+---@package
function dfs:_filename()
return self.path:match '[^/\\]+$'
end
@@ -291,6 +293,7 @@ local function fsIsDirectory(path, option)
if path.type == 'dummy' then
return path:isDirectory()
end
+ ---@cast path -dummyfs
local status = fs.symlink_status(path):type()
return status == 'directory'
end
@@ -347,6 +350,7 @@ local function fsSave(path, text, option)
return false
end
if path.type == 'dummy' then
+ ---@cast path -fs.path
local dir = path:_open(-2)
if not dir then
option.err[#option.err+1] = '无法打开:' .. path:string()
@@ -385,6 +389,7 @@ local function fsLoad(path, option)
return nil
end
else
+ ---@cast path -dummyfs
local text, err = m.loadFile(path)
if text then
return text
@@ -407,6 +412,7 @@ local function fsCopy(source, target, option)
end
return fsSave(target, sourceText, option)
else
+ ---@cast source -dummyfs
if target.type == 'dummy' then
local sourceText, err = m.loadFile(source)
if not sourceText then
@@ -564,7 +570,6 @@ end
--- 文件列表
function m.fileList(option)
option = option or buildOption(option)
- local os = platform.OS
local keyMap = {}
local fileList = {}
local function computeKey(path)
diff --git a/script/gc.lua b/script/gc.lua
index ff22195e..92739585 100644
--- a/script/gc.lua
+++ b/script/gc.lua
@@ -1,12 +1,13 @@
local util = require 'utility'
---@class gc
----@field _list table
+---@field package _list table
local mt = {}
mt.__index = mt
mt.type = 'gc'
mt._removed = false
+---@package
mt._max = 10
local function destroyGCObject(obj)
diff --git a/script/json-edit.lua b/script/json-edit.lua
index 30a55250..efa1216f 100644
--- a/script/json-edit.lua
+++ b/script/json-edit.lua
@@ -384,6 +384,7 @@ end
local JsonEmpty = function () end
+---@return {s: integer, d:integer, f:integer, v: any}
local function decode_ast(str)
if type(str) ~= "string" then
error("expected argument of type string, got " .. type(str))
@@ -607,7 +608,11 @@ function OP.add(str, option, path, value)
end
local ast = decode_ast(str)
if ast.v == JsonEmpty then
- local pathlst = split_path(path)
+ local pathlst, err = split_path(path)
+ if not pathlst then
+ error(err)
+ return
+ end
value = add_prefix(value, pathlst)
return json.beautify(value, option)
end
@@ -674,7 +679,11 @@ function OP.replace(str, option, path, value)
end
local ast = decode_ast(str)
if ast.v == JsonEmpty then
- local pathlst = split_path(path)
+ local pathlst, err = split_path(path)
+ if not pathlst then
+ error(err)
+ return
+ end
value = add_prefix(value, pathlst)
return json.beautify(value, option)
end
diff --git a/script/parser/compile.lua b/script/parser/compile.lua
index 5321d9b8..8dd772db 100644
--- a/script/parser/compile.lua
+++ b/script/parser/compile.lua
@@ -239,6 +239,16 @@ local LocalLimit = 200
local parseExp, parseAction
+---@class parser.state.err
+---@field type string
+---@field start? parser.position
+---@field finish? parser.position
+---@field info? table
+---@field fix? table
+---@field version? string[]|string
+---@field level? string | 'Error' | 'Warning'
+
+---@type fun(err:parser.state.err):parser.state.err|nil
local pushError
local function addSpecial(name, obj)
@@ -711,6 +721,7 @@ local function parseLocalAttrs()
return attrs
end
+---@param obj table
local function createLocal(obj, attrs)
obj.type = 'local'
obj.effect = obj.finish
@@ -1709,6 +1720,9 @@ local function parseTable()
end
local function addDummySelf(node, call)
+ if not node then
+ return
+ end
if node.type ~= 'getmethod' then
return
end
@@ -1736,6 +1750,9 @@ local function checkAmbiguityCall(call, parenPos)
return
end
local node = call.node
+ if not node then
+ return
+ end
local nodeRow = guide.rowColOf(node.finish)
local callRow = guide.rowColOf(parenPos)
if nodeRow == callRow then
@@ -2470,7 +2487,10 @@ local function parseExpUnit()
local node = parseName()
if node then
- return parseSimple(resolveName(node), false)
+ local nameNode = resolveName(node)
+ if nameNode then
+ return parseSimple(nameNode, false)
+ end
end
return nil
@@ -3421,6 +3441,7 @@ local function parseFor()
forStateVars = 3
LocalCount = LocalCount + forStateVars
if name then
+ ---@cast name parser.object
local loc = createLocal(name)
loc.parent = action
action.finish = name.finish
@@ -3523,7 +3544,9 @@ local function parseFor()
list.range = lastName and lastName.range or inRight
action.keys = list
for i = 1, #list do
- local loc = createLocal(list[i])
+ local obj = list[i]
+ ---@cast obj parser.object
+ local loc = createLocal(obj)
loc.parent = action
loc.effect = action.finish
end
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index fd779da0..ac7a5ce0 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -74,9 +74,12 @@ local type = type
---@field hasBreak? true
---@field hasExit? true
---@field [integer] parser.object|any
+---@field dot { type: string, start: integer, finish: integer }
+---@field colon { type: string, start: integer, finish: integer }
---@field package _root parser.object
---@field package _eachCache? parser.object[]
---@field package _isGlobal? boolean
+---@field package _typeCache? parser.object[][]
---@class guide
---@field debugMode boolean
diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua
index aec8994b..25ff71c1 100644
--- a/script/parser/luadoc.lua
+++ b/script/parser/luadoc.lua
@@ -1620,7 +1620,7 @@ local function trimTailComment(text)
and comment:find '[\'"%]]%s*$' then
local state = compile(comment:gsub('^%s+', ''), 'String')
if state and state.ast then
- comment = state.ast[1]
+ comment = state.ast[1] --[[@as string]]
end
end
return util.trim(comment)
diff --git a/script/plugin.lua b/script/plugin.lua
index b77511ff..35a1da5b 100644
--- a/script/plugin.lua
+++ b/script/plugin.lua
@@ -62,6 +62,7 @@ end
function m.getVmPlugin(uri)
local scp = scope.getScope(uri)
+ ---@type pluginInterfaces
local interfaces = scp:get('pluginInterfaces')
if not interfaces then
return
diff --git a/script/proto/proto.lua b/script/proto/proto.lua
index 2460b4ec..b0d5d1a9 100644
--- a/script/proto/proto.lua
+++ b/script/proto/proto.lua
@@ -232,7 +232,7 @@ end
function m.listen(mode, socketPort)
m.mode = mode
if mode == 'stdio' then
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
local windows = require 'bee.windows'
windows.filemode(io.stdin, 'b')
windows.filemode(io.stdout, 'b')
diff --git a/script/timer.lua b/script/timer.lua
index 09bbce0f..14d33f6a 100644
--- a/script/timer.lua
+++ b/script/timer.lua
@@ -14,6 +14,7 @@ local curIndex = 0
local tarFrame = 0
local fwFrame = 0
local freeQueue = {}
+---@type (timer|false)[][]
local timer = {}
local function allocQueue()
@@ -101,9 +102,10 @@ end
local m = {}
---@class timer
----@field _onTimer? fun(self: timer)
----@field _timeoutFrame integer
----@field _timeout integer
+---@field package _onTimer? fun(self: timer)
+---@field package _timeoutFrame integer
+---@field package _timeout integer
+---@field package _timerCount integer
local mt = {}
mt.__index = mt
mt.type = 'timer'
@@ -119,6 +121,7 @@ function mt:__call()
end
function mt:remove()
+ ---@package
self._removed = true
end
@@ -126,7 +129,9 @@ function mt:pause()
if self._removed or self._pauseRemaining then
return
end
+ ---@package
self._pauseRemaining = getRemaining(self)
+ ---@package
self._running = false
local ti = self._timeoutFrame
local q = timer[ti]
@@ -145,6 +150,7 @@ function mt:resume()
return
end
local timeout = self._pauseRemaining
+ ---@package
self._pauseRemaining = nil
mTimeout(self, timeout)
end
@@ -163,6 +169,7 @@ function mt:restart()
end
end
end
+ ---@package
self._running = false
mTimeout(self, self._timeout)
end
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 2253c83a..fc8f7c52 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -1031,6 +1031,7 @@ local function compileForVars(source, target)
return false
end
+---@param func parser.object
---@param source parser.object
local function compileFunctionParam(func, source)
-- local call ---@type fun(f: fun(x: number));call(function (x) end) --> x -> number
@@ -1050,33 +1051,31 @@ local function compileFunctionParam(func, source)
end
end
end
- if func.parent.type == 'local' then
+
+ local derviationParam = config.get(guide.getUri(func), 'Lua.type.inferParamType')
+ if derviationParam and func.parent.type == 'local' and func.parent.ref then
local refs = func.parent.ref
- local findCall
- if refs then
- for i, ref in ipairs(refs) do
- if ref.parent.type == 'call' then
- findCall = ref.parent
- break
- end
+ local found
+ for _, ref in ipairs(refs) do
+ if ref.parent.type ~= 'call' then
+ goto continue
end
- end
- if findCall and findCall.args then
- local index
- for i, arg in ipairs(source.parent) do
- if arg == source then
- index = i
- break
- end
+ local caller = ref.parent
+ if not caller.args then
+ goto continue
end
- if index then
- local callerArg = findCall.args[index]
- if callerArg then
- vm.setNode(source, vm.compileNode(callerArg))
- return true
+ for index, arg in ipairs(source.parent) do
+ if arg == source then
+ local callerArg = caller.args[index]
+ if callerArg then
+ vm.setNode(source, vm.compileNode(callerArg))
+ finded = true
+ end
end
end
+ ::continue::
end
+ return finded
end
end
@@ -1121,24 +1120,9 @@ local function compileLocal(source)
end
if source.parent.type == 'funcargs' and not hasMarkDoc and not hasMarkParam then
local func = source.parent.parent
- -- local call ---@type fun(f: fun(x: number));call(function (x) end) --> x -> number
- local funcNode = vm.compileNode(func)
- local hasDocArg
- for n in funcNode:eachObject() do
- if n.type == 'doc.type.function' then
- for index, arg in ipairs(n.args) do
- if func.args[index] == source then
- local argNode = vm.compileNode(arg)
- for an in argNode:eachObject() do
- if an.type ~= 'doc.generic.name' then
- vm.setNode(source, an)
- end
- end
- hasDocArg = true
- end
- end
- end
- end
+ local vmPlugin = plugin.getVmPlugin(guide.getUri(source))
+ local hasDocArg = vmPlugin and vmPlugin.OnCompileFunctionParam(compileFunctionParam, func, source)
+ or compileFunctionParam(func, source)
if not hasDocArg then
vm.setNode(source, vm.declareGlobal('type', 'any'))
end
diff --git a/script/vm/visible.lua b/script/vm/visible.lua
index d13ecf1f..0f486d6b 100644
--- a/script/vm/visible.lua
+++ b/script/vm/visible.lua
@@ -31,6 +31,10 @@ local function getVisibleType(source)
source._visibleType = 'protected'
return 'protected'
end
+ if doc.type == 'doc.package' then
+ source._visibleType = 'package'
+ return 'package'
+ end
end
end
@@ -50,6 +54,12 @@ local function getVisibleType(source)
source._visibleType = 'protected'
return 'protected'
end
+
+ local packageNames = config.get(uri, 'Lua.doc.packageName')
+ if #packageNames > 0 and glob.glob(packageNames)(fieldName) then
+ source._visibleType = 'package'
+ return 'package'
+ end
end
source._visibleType = 'public'
diff --git a/script/workspace/require-path.lua b/script/workspace/require-path.lua
index c319cbad..1507183c 100644
--- a/script/workspace/require-path.lua
+++ b/script/workspace/require-path.lua
@@ -123,7 +123,7 @@ function mt:getRequireResultByPath(path)
cutedPath = currentPath:sub(pos)
head = currentPath:sub(1, pos - 1)
pos = currentPath:match('[/\\]+()', pos)
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
searcher = searcher :gsub('[/\\]+', '\\')
else
searcher = searcher :gsub('[/\\]+', '/')
diff --git a/script/workspace/scope.lua b/script/workspace/scope.lua
index 789b5f81..cfdfdc90 100644
--- a/script/workspace/scope.lua
+++ b/script/workspace/scope.lua
@@ -235,11 +235,11 @@ function m.getLinkedScope(uri)
return nil
end
----@param uri uri
+---@param uri? uri
---@return scope
function m.getScope(uri)
- return m.getFolder(uri)
- or m.getLinkedScope(uri)
+ return uri and (m.getFolder(uri)
+ or m.getLinkedScope(uri))
or m.fallback
end
diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua
index 97518e84..fe7c6c15 100644
--- a/script/workspace/workspace.lua
+++ b/script/workspace/workspace.lua
@@ -188,7 +188,7 @@ function m.getNativeMatcher(scp)
local matcher = glob.gitignore(pattern, {
root = scp.uri and furi.decode(scp.uri),
- ignoreCase = platform.OS == 'Windows',
+ ignoreCase = platform.os == 'windows',
}, globInteferFace)
scp:set('nativeMatcher', matcher)
@@ -236,7 +236,7 @@ function m.getLibraryMatchers(scp)
local nPath = fs.absolute(fs.path(path)):string()
local matcher = glob.gitignore(pattern, {
root = path,
- ignoreCase = platform.OS == 'Windows',
+ ignoreCase = platform.os == 'windows',
}, globInteferFace)
matchers[#matchers+1] = {
uri = furi.encode(nPath),
diff --git a/test/code_action/init.lua b/test/code_action/init.lua
index 264cfacf..75c116a4 100644
--- a/test/code_action/init.lua
+++ b/test/code_action/init.lua
@@ -49,6 +49,7 @@ function TEST(script)
end
end
+---@param testfiles [string, {path:string, content:string}]
local function TEST_CROSSFILE(testfiles)
local mainscript = table.remove(testfiles, 1)
return function(expected)
diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua
index 227350cb..79b40cb3 100644
--- a/test/crossfile/completion.lua
+++ b/test/crossfile/completion.lua
@@ -918,7 +918,7 @@ local z: table
}
}
-if platform.OS == 'Windows' then
+if platform.os == 'windows' then
Cared['detail'] = true
Cared['additionalTextEdits'] = true
TEST {
diff --git a/test/crossfile/definition.lua b/test/crossfile/definition.lua
index b13b57f3..49a5d8d3 100644
--- a/test/crossfile/definition.lua
+++ b/test/crossfile/definition.lua
@@ -689,7 +689,7 @@ TEST {
}
-if platform.OS == 'Linux' then
+if platform.os == 'linux' then
TEST {
{
diff --git a/test/diagnostics/await-in-sync.lua b/test/diagnostics/await-in-sync.lua
index 323c1113..7647f2eb 100644
--- a/test/diagnostics/await-in-sync.lua
+++ b/test/diagnostics/await-in-sync.lua
@@ -119,7 +119,7 @@ end
TEST [[
local function f(cb)
- cb()
+ <!cb!>()
end
local function af()
diff --git a/test/diagnostics/redundant-parameter.lua b/test/diagnostics/redundant-parameter.lua
index fabe3340..520a6381 100644
--- a/test/diagnostics/redundant-parameter.lua
+++ b/test/diagnostics/redundant-parameter.lua
@@ -94,7 +94,7 @@ print(1, 2, 3, 4, 5)
TEST [[
local function f(callback)
- callback(1, 2, 3)
+ callback(<!1!>, <!2!>, <!3!>)
end
f(function () end)
]]
diff --git a/test/document_symbol/init.lua b/test/document_symbol/init.lua
index dff43c7d..53e0dab2 100644
--- a/test/document_symbol/init.lua
+++ b/test/document_symbol/init.lua
@@ -50,6 +50,7 @@ function TEST(script)
return function (expect)
files.setText(TESTURI, script)
local result = core(TESTURI)
+ assert(result)
assert(eq(expect, result))
checkArcoss(result)
files.remove(TESTURI)
diff --git a/test/hover/init.lua b/test/hover/init.lua
index 0cfce3a4..bed5828a 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -276,7 +276,7 @@ function string.lower(s: string|number)
-> string
]]
--- 不根据传入值推测参数类型
+-- 根据传入值推测参数类型
TEST [[
local function x(a, ...)
end
@@ -284,7 +284,7 @@ end
<?x?>(1, 2, 3, 4, 5, 6, 7)
]]
[[
-function x(a: any, ...any)
+function x(a: integer, ...any)
]]
TEST [[
diff --git a/test/signature/init.lua b/test/signature/init.lua
index f46ce017..2bf4b824 100644
--- a/test/signature/init.lua
+++ b/test/signature/init.lua
@@ -88,7 +88,7 @@ end
x(1, 2, 3, <??>
]]
-{'function x(a: any, <!...any!>)'}
+{'function x(a: integer, <!...any!>)'}
TEST [[
(''):sub(<??>
@@ -106,7 +106,7 @@ end
f(1, 'string<??>')
]]
-{'function f(a: any, <!b: any!>, c: any)'}
+{'function f(a: integer, <!b: string!>, c: any)'}
TEST [[
pcall(function () <??> end)
@@ -156,7 +156,7 @@ end
f({},<??>)
]]
-{'function f(a: any, <!b: any!>, c: any)'}
+{'function f(a: table, <!b: any!>, c: any)'}
TEST [[
for _ in pairs(<??>) do
@@ -188,7 +188,7 @@ end
x( aaaa <??>, 2)
]]
-{"function x(<!a: any!>, b: any)"}
+{"function x(<!a: any!>, b: integer)"}
TEST [[
local function x(a, b)
@@ -196,7 +196,7 @@ end
x(<??> aaaa , 2)
]]
-{'function x(<!a: any!>, b: any)'}
+{'function x(<!a: any!>, b: integer)'}
TEST [[
local function x(a, b)
@@ -204,7 +204,7 @@ end
x(aaaa ,<??> 2)
]]
-{'function x(a: any, <!b: any!>)'}
+{'function x(a: any, <!b: integer!>)'}
TEST [[
local function x(a, b)
@@ -212,7 +212,7 @@ end
x(aaaa , 2 <??>)
]]
-{'function x(a: any, <!b: any!>)'}
+{'function x(a: any, <!b: integer!>)'}
TEST [[
local fooC
diff --git a/test/tclient/tests/jump-source.lua b/test/tclient/tests/jump-source.lua
index 84a4dcd5..c9e093c0 100644
--- a/test/tclient/tests/jump-source.lua
+++ b/test/tclient/tests/jump-source.lua
@@ -163,7 +163,7 @@ print(D3)
position = { line = 9, character = 7 },
})
- if platform.OS == 'Windows' then
+ if platform.os == 'windows' then
assert(util.equal(locations, {
{
uri = 'file:///d%3A/xxx/2.lua',