summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruhziel <uhziel@gmail.com>2020-12-15 14:53:59 +0800
committeruhziel <uhziel@gmail.com>2020-12-15 14:53:59 +0800
commit8e55293116809cd46c9f3dce7c972e8ee77af840 (patch)
tree487da1bb0a1b0980870dbab7309fd2f026954b4b
parente7df5a89d015dacd613cc9cdeb7539386884a3eb (diff)
parentf3ec5825e3c6a8090a020097e088f26718c316bb (diff)
downloadlua-language-server-8e55293116809cd46c9f3dce7c972e8ee77af840.zip
Merge branch 'master' into diagnostic-undefined-field
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.md32
-rw-r--r--.vscode/settings.json2
m---------3rd/bee.lua0
-rw-r--r--changelog.md4
-rw-r--r--locale/zh-cn/script.lua2
-rw-r--r--script/config.lua3
-rw-r--r--script/core/completion.lua10
-rw-r--r--script/core/diagnostics/init.lua10
-rw-r--r--script/core/diagnostics/undefined-field.lua20
-rw-r--r--script/core/semantic-tokens.lua7
-rw-r--r--script/files.lua2
-rw-r--r--script/glob/gitignore.lua17
-rw-r--r--script/glob/glob.lua7
-rw-r--r--script/provider/provider.lua6
-rw-r--r--script/service/init.lua1
-rw-r--r--script/service/net.lua293
-rw-r--r--script/service/telemetry.lua36
-rw-r--r--script/vm/eachDef.lua1
-rw-r--r--script/vm/eachField.lua1
-rw-r--r--script/vm/eachRef.lua1
-rw-r--r--script/vm/getClass.lua1
-rw-r--r--script/vm/getDocs.lua1
-rw-r--r--script/vm/getGlobals.lua1
-rw-r--r--script/vm/getInfer.lua1
-rw-r--r--script/vm/getLibrary.lua1
-rw-r--r--script/vm/getLinks.lua1
-rw-r--r--script/vm/getMeta.lua1
-rw-r--r--script/vm/guideInterface.lua1
-rw-r--r--test/diagnostics/init.lua20
29 files changed, 446 insertions, 37 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..33daf9af
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,32 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Environment (please complete the following information):**
+ - OS: [e.g. Windows, macOS, Ubuntu]
+ - Is WSL remote?
+ - Client: [e.g. VSCode, neovim]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 28cfacbe..92e6ec8e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -35,5 +35,5 @@
"Lua.awakened.cat": true,
"Lua.develop.enable": true,
"Lua.develop.debuggerPort": 11413,
- "Lua.intelliSense.searchDepth": 5
+ "Lua.intelliSense.searchDepth": 0
}
diff --git a/3rd/bee.lua b/3rd/bee.lua
-Subproject bb5e94e2dc0822c2f36b24bdcb12f361fda5cdd
+Subproject bb6094a71d3cd41f0af22704cc1905330d4cc1f
diff --git a/changelog.md b/changelog.md
index d7a1755c..7057ca28 100644
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,10 @@
## 1.7.0
* `CHG` diagnostic: `unused-function` ignores function with `<close>`
+* `CHG` semantic: not cover local call
+* `FIX` semantic: tokens may not be updated correctly
+* `FIX` completion: require path broken
+* `FIX` [#291](https://github.com/sumneko/lua-language-server/issues/291)
## 1.6.0
`2020-12-14`
diff --git a/locale/zh-cn/script.lua b/locale/zh-cn/script.lua
index 3dda7699..4e43024f 100644
--- a/locale/zh-cn/script.lua
+++ b/locale/zh-cn/script.lua
@@ -2,7 +2,7 @@ DIAG_LINE_ONLY_SPACE = '只有空格的空行。'
DIAG_LINE_POST_SPACE = '后置空格。'
DIAG_UNUSED_LOCAL = '未使用的局部变量 `{}`。'
DIAG_UNDEF_GLOBAL = '未定义的全局变量 `{}`。'
-DIAG_UNDEF_FIELD = '未定义的 field `{}`。'
+DIAG_UNDEF_FIELD = '未定义的属性/字段 `{}`。'
DIAG_UNDEF_ENV_CHILD = '未定义的变量 `{}`(重载了 `_ENV` )。'
DIAG_UNDEF_FENV_CHILD = '未定义的变量 `{}`(处于模块中)。'
DIAG_GLOBAL_IN_NIL_ENV = '不能使用全局变量(`_ENV`被置为了`nil`)。'
diff --git a/script/config.lua b/script/config.lua
index 298083a4..c9d8e075 100644
--- a/script/config.lua
+++ b/script/config.lua
@@ -150,6 +150,9 @@ local ConfigTemplate = {
intelliSense = {
searchDepth = {0, Integer},
},
+ telemetry = {
+ enable = {true, Boolean},
+ }
}
local OtherTemplate = {
diff --git a/script/core/completion.lua b/script/core/completion.lua
index 436a1689..5db4aa1b 100644
--- a/script/core/completion.lua
+++ b/script/core/completion.lua
@@ -806,8 +806,9 @@ local function checkUri(ast, text, offset, results)
if not collect[info.expect] then
collect[info.expect] = {
textEdit = {
- start = source.start + #source[2],
- finish = source.finish - #source[2],
+ start = source.start + #source[2],
+ finish = source.finish - #source[2],
+ newText = info.expect,
}
}
end
@@ -835,8 +836,9 @@ local function checkUri(ast, text, offset, results)
if not collect[path] then
collect[path] = {
textEdit = {
- start = source.start + #source[2],
- finish = source.finish - #source[2],
+ start = source.start + #source[2],
+ finish = source.finish - #source[2],
+ newText = path,
}
}
end
diff --git a/script/core/diagnostics/init.lua b/script/core/diagnostics/init.lua
index a6b61e12..510b57ea 100644
--- a/script/core/diagnostics/init.lua
+++ b/script/core/diagnostics/init.lua
@@ -22,8 +22,14 @@ local function check(uri, name, results)
end
local level = config.config.diagnostics.severity[name]
or define.DiagnosticDefaultSeverity[name]
- if level == 'Hint' and not files.isOpen(uri) then
- return
+ if not files.isOpen(uri) then
+ if level == 'Hint' then
+ return
+ end
+ -- TODO
+ if name == 'undefined-field' then
+ return
+ end
end
local severity = define.DiagnosticSeverity[level]
local clock = os.clock()
diff --git a/script/core/diagnostics/undefined-field.lua b/script/core/diagnostics/undefined-field.lua
index 1b15203c..499b2ffe 100644
--- a/script/core/diagnostics/undefined-field.lua
+++ b/script/core/diagnostics/undefined-field.lua
@@ -68,7 +68,7 @@ return function (uri, callback)
::CONTINUE::
end
end
-
+
if empty then
return nil
else
@@ -93,11 +93,19 @@ return function (uri, callback)
if not fields[fieldName] then
local message = lang.script('DIAG_UNDEF_FIELD', fieldName)
- callback {
- start = src.start,
- finish = src.finish,
- message = message,
- }
+ if src.type == 'getfield' then
+ callback {
+ start = src.field.start,
+ finish = src.field.finish,
+ message = message,
+ }
+ elseif src.type == 'getmethod' then
+ callback {
+ start = src.method.start,
+ finish = src.method.finish,
+ message = message,
+ }
+ end
end
end
guide.eachSourceType(ast.ast, 'getfield', checkUndefinedField);
diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua
index fdb792da..170bffa8 100644
--- a/script/core/semantic-tokens.lua
+++ b/script/core/semantic-tokens.lua
@@ -83,7 +83,12 @@ Care['getlocal'] = function (source, results)
or source[1] == 'self' then
return
end
- -- 5. 其他
+ -- 5. 函数调用
+ if source.parent.type == 'call'
+ and source.parent.node == source then
+ return
+ end
+ -- 6. 其他
results[#results+1] = {
start = source.start,
finish = source.finish,
diff --git a/script/files.lua b/script/files.lua
index db33dab1..71981a83 100644
--- a/script/files.lua
+++ b/script/files.lua
@@ -367,7 +367,7 @@ end
---@param uri string
---@return boolean
function m.isLua(uri)
- local ext = uri:match '%.([^%.%/%\\]-)$'
+ local ext = uri:match '%.([^%.%/%\\]+)$'
if not ext then
return false
end
diff --git a/script/glob/gitignore.lua b/script/glob/gitignore.lua
index f98a2f31..3f942bfb 100644
--- a/script/glob/gitignore.lua
+++ b/script/glob/gitignore.lua
@@ -19,7 +19,7 @@ end
local parser = m.P {
'Main',
['Sp'] = m.S(' \t')^0,
- ['Slash'] = m.S('/\\')^1,
+ ['Slash'] = m.S('/')^1,
['Main'] = m.Ct(m.V'Sp' * m.P'{' * m.V'Pattern' * (',' * expect(m.V'Pattern', 'Miss exp after ","'))^0 * m.P'}')
+ m.Ct(m.V'Pattern')
+ m.T'Main Failed'
@@ -35,12 +35,20 @@ local parser = m.P {
+ object('?', m.P'?')
+ object('[]', m.V'Range')
,
- ['Char'] = object('char', (1 - m.S',{}[]*?/\\')^1),
+ ['SimpleChar'] = m.P(1) - m.S',{}[]*?/',
+ ['EscChar'] = m.P'\\' / '' * m.P(1),
+ ['Char'] = object('char', m.Cs((m.V'EscChar' + m.V'SimpleChar')^1)),
['FSymbol'] = object('**', m.P'**'),
['Range'] = m.P'[' * m.Ct(m.V'RangeUnit'^0) * m.P']'^-1,
['RangeUnit'] = m.Ct(- m.P']' * m.C(m.P(1)) * (m.P'-' * - m.P']' * m.C(m.P(1)))^-1),
}
+---@class gitignore
+---@field pattern string[]
+---@field options table
+---@field errors table[]
+---@field matcher table
+---@field interface function[]
local mt = {}
mt.__index = mt
mt.__name = 'gitignore'
@@ -170,7 +178,9 @@ function mt:scan(callback)
if type(result) == 'table' then
for _, path in ipairs(result) do
local filename = path:match '([^/\\]+)[/\\]*$'
- if filename then
+ if filename
+ and filename ~= '.'
+ and filename ~= '..' then
list[#list+1] = current .. '/' .. filename
end
end
@@ -185,6 +195,7 @@ function mt:__call(path)
if self.options.ignoreCase then
path = path:lower()
end
+ path = path:gsub('^[/\\]+', '')
return self:finishMatch(path)
end
diff --git a/script/glob/glob.lua b/script/glob/glob.lua
index aa8923f3..59fa83a8 100644
--- a/script/glob/glob.lua
+++ b/script/glob/glob.lua
@@ -19,7 +19,7 @@ end
local parser = m.P {
'Main',
['Sp'] = m.S(' \t')^0,
- ['Slash'] = m.S('/\\')^1,
+ ['Slash'] = m.P('/')^1,
['Main'] = m.Ct(m.V'Sp' * m.P'{' * m.V'Pattern' * (',' * expect(m.V'Pattern', 'Miss exp after ","'))^0 * m.P'}')
+ m.Ct(m.V'Pattern')
+ m.T'Main Failed'
@@ -35,7 +35,9 @@ local parser = m.P {
+ object('?', m.P'?')
+ object('[]', m.V'Range')
,
- ['Char'] = object('char', (1 - m.S',{}[]*?/\\')^1),
+ ['SimpleChar'] = m.P(1) - m.S',{}[]*?/',
+ ['EscChar'] = m.P'\\' / '' * m.P(1),
+ ['Char'] = object('char', m.Cs((m.V'EscChar' + m.V'SimpleChar')^1)),
['FSymbol'] = object('**', m.P'**'),
['RangeWord'] = 1 - m.P']',
['Range'] = m.P'[' * m.Ct(m.V'RangeUnit'^0) * m.P']'^-1,
@@ -83,6 +85,7 @@ function mt:__call(path)
if self.options.ignoreCase then
path = path:lower()
end
+ path = path:gsub('^[/\\]+', '')
for _, refused in ipairs(self.refused) do
if refused(path) then
return false
diff --git a/script/provider/provider.lua b/script/provider/provider.lua
index 6028e6fe..2fb999e7 100644
--- a/script/provider/provider.lua
+++ b/script/provider/provider.lua
@@ -652,9 +652,6 @@ proto.on('textDocument/semanticTokens/full', function (params)
text = files.getText(uri)
end
local results = core(uri, 0, #text)
- if not results or #results == 0 then
- return nil
- end
return {
data = results
}
@@ -674,9 +671,6 @@ proto.on('textDocument/semanticTokens/range', function (params)
local start = define.offset(lines, text, params.range.start)
local finish = define.offset(lines, text, params.range['end'])
local results = core(uri, start, finish)
- if not results or #results == 0 then
- return nil
- end
return {
data = results
}
diff --git a/script/service/init.lua b/script/service/init.lua
index eb0bd057..09204c84 100644
--- a/script/service/init.lua
+++ b/script/service/init.lua
@@ -1,3 +1,4 @@
+require 'service.telemetry'
local service = require 'service.service'
return service
diff --git a/script/service/net.lua b/script/service/net.lua
new file mode 100644
index 00000000..9ccd119a
--- /dev/null
+++ b/script/service/net.lua
@@ -0,0 +1,293 @@
+local socket = require "bee.socket"
+
+local readfds = {}
+local writefds = {}
+local map = {}
+
+local function FD_SET(set, fd)
+ for i = 1, #set do
+ if fd == set[i] then
+ return
+ end
+ end
+ set[#set+1] = fd
+end
+
+local function FD_CLR(set, fd)
+ for i = 1, #set do
+ if fd == set[i] then
+ set[i] = set[#set]
+ set[#set] = nil
+ return
+ end
+ end
+end
+
+local function fd_set_read(fd)
+ FD_SET(readfds, fd)
+end
+
+local function fd_clr_read(fd)
+ FD_CLR(readfds, fd)
+end
+
+local function fd_set_write(fd)
+ FD_SET(writefds, fd)
+end
+
+local function fd_clr_write(fd)
+ FD_CLR(writefds, fd)
+end
+
+local function on_event(self, name, ...)
+ local f = self._event[name]
+ if f then
+ f(self, ...)
+ end
+end
+
+local function close(self)
+ local fd = self._fd
+ on_event(self, "close")
+ fd:close()
+ map[fd] = nil
+end
+
+local stream_mt = {}
+local stream = {}
+stream_mt.__index = stream
+function stream_mt:__newindex(name, func)
+ if name:sub(1, 3) == "on_" then
+ self._event[name:sub(4)] = func
+ end
+end
+function stream:write(data)
+ if self.shutdown_w then
+ return
+ end
+ if data == "" then
+ return
+ end
+ if self._writebuf == "" then
+ fd_set_write(self._fd)
+ end
+ self._writebuf = self._writebuf .. data
+end
+function stream:is_closed()
+ return self.shutdown_w and self.shutdown_r
+end
+function stream:close()
+ if not self.shutdown_r then
+ self.shutdown_r = true
+ fd_clr_read(self._fd)
+ end
+ if self.shutdown_w or self._writebuf == "" then
+ self.shutdown_w = true
+ fd_clr_write(self._fd)
+ close(self)
+ end
+end
+function stream:update(timeout)
+ local fd = self._fd
+ local r = {fd}
+ local w = r
+ if self._writebuf == "" then
+ w = nil
+ end
+ local rd, wr = socket.select(r, w, timeout or 0)
+ if rd then
+ if #rd > 0 then
+ self:select_r()
+ end
+ if #wr > 0 then
+ self:select_w()
+ end
+ end
+end
+local function close_write(self)
+ fd_clr_write(self._fd)
+ if self.shutdown_r then
+ fd_clr_read(self._fd)
+ close(self)
+ end
+end
+function stream:select_r()
+ local data = self._fd:recv()
+ if data == nil then
+ self:close()
+ elseif data == false then
+ else
+ on_event(self, "data", data)
+ end
+end
+function stream:select_w()
+ local n = self._fd:send(self._writebuf)
+ if n == nil then
+ self.shutdown_w = true
+ close_write(self)
+ else
+ self._writebuf = self._writebuf:sub(n + 1)
+ if self._writebuf == "" then
+ close_write(self)
+ end
+ end
+end
+
+local function accept_stream(fd)
+ local self = setmetatable({
+ _fd = fd,
+ _event = {},
+ _writebuf = "",
+ shutdown_r = false,
+ shutdown_w = false,
+ }, stream_mt)
+ map[fd] = self
+ fd_set_read(fd)
+ return self
+end
+local function connect_stream(self)
+ setmetatable(self, stream_mt)
+ fd_set_read(self._fd)
+ if self._writebuf ~= "" then
+ self:select_w()
+ else
+ fd_clr_write(self._fd)
+ end
+end
+
+
+local listen_mt = {}
+local listen = {}
+listen_mt.__index = listen
+function listen_mt:__newindex(name, func)
+ if name:sub(1, 3) == "on_" then
+ self._event[name:sub(4)] = func
+ end
+end
+function listen:is_closed()
+ return self.shutdown_r
+end
+function listen:close()
+ self.shutdown_r = true
+ fd_clr_read(self._fd)
+ close(self)
+end
+function listen:update(timeout)
+ local fd = self._fd
+ local r = {fd}
+ local rd = socket.select(r, nil, timeout or 0)
+ if rd then
+ if #rd > 0 then
+ self:select_r()
+ end
+ end
+end
+function listen:select_r()
+ local newfd = self._fd:accept()
+ if newfd:status() then
+ local news = accept_stream(newfd)
+ on_event(self, "accept", news)
+ end
+end
+local function new_listen(fd)
+ local s = {
+ _fd = fd,
+ _event = {},
+ shutdown_r = false,
+ shutdown_w = true,
+ }
+ map[fd] = s
+ fd_set_read(fd)
+ return setmetatable(s, listen_mt)
+end
+
+local connect_mt = {}
+local connect = {}
+connect_mt.__index = connect
+function connect_mt:__newindex(name, func)
+ if name:sub(1, 3) == "on_" then
+ self._event[name:sub(4)] = func
+ end
+end
+function connect:write(data)
+ if data == "" then
+ return
+ end
+ self._writebuf = self._writebuf .. data
+end
+function connect:is_closed()
+ return self.shutdown_w
+end
+function connect:close()
+ self.shutdown_w = true
+ fd_clr_write(self._fd)
+ close(self)
+end
+function connect:update(timeout)
+ local fd = self._fd
+ local w = {fd}
+ local rd, wr = socket.select(nil, w, timeout or 0)
+ if rd then
+ if #wr > 0 then
+ self:select_w()
+ end
+ end
+end
+function connect:select_w()
+ local ok, err = self._fd:status()
+ if ok then
+ connect_stream(self)
+ on_event(self, "connect")
+ else
+ on_event(self, "error", err)
+ self:close()
+ end
+end
+local function new_connect(fd)
+ local s = {
+ _fd = fd,
+ _event = {},
+ _writebuf = "",
+ shutdown_r = false,
+ shutdown_w = false,
+ }
+ map[fd] = s
+ fd_set_write(fd)
+ return setmetatable(s, connect_mt)
+end
+
+local m = {}
+
+function m.listen(...)
+ local fd, err = socket.bind(...)
+ if not fd then
+ return fd, err
+ end
+ return new_listen(fd)
+end
+
+function m.connect(...)
+ local fd, err = socket.connect(...)
+ if not fd then
+ return fd, err
+ end
+ return new_connect(fd)
+end
+
+function m.update(timeout)
+ local rd, wr = socket.select(readfds, writefds, timeout or 0)
+ if rd then
+ for i = 1, #rd do
+ local fd = rd[i]
+ local s = map[fd]
+ s:select_r()
+ end
+ for i = 1, #wr do
+ local fd = wr[i]
+ local s = map[fd]
+ s:select_w()
+ end
+ end
+end
+
+return m
diff --git a/script/service/telemetry.lua b/script/service/telemetry.lua
new file mode 100644
index 00000000..d04662b9
--- /dev/null
+++ b/script/service/telemetry.lua
@@ -0,0 +1,36 @@
+local net = require 'service.net'
+local timer = require 'timer'
+local config = require 'config'
+local client = require 'provider.client'
+local nonil = require 'without-check-nil'
+local util = require 'utility'
+
+local tokenPath = (ROOT / 'log' / 'token'):string()
+local token = util.loadFile(tokenPath)
+if not token then
+ token = ('%016X'):format(math.random(0, math.maxinteger))
+ util.saveFile(tokenPath, token)
+end
+
+local function pushClient(link)
+ nonil.enable()
+ local clientName = client.info.clientInfo.name
+ local clientVersion = client.info.clientInfo.version
+ nonil.disable()
+ link:write(string.pack('zzz'
+ , 'pulse'
+ , token
+ , table.concat({clientName, clientVersion}, ' ')
+ ))
+end
+
+timer.wait(5, function ()
+ timer.loop(60, function ()
+ if not config.config.telemetry.enable then
+ return
+ end
+ local link = net.connect('tcp', '119.45.194.183', 11577)
+ pushClient(link)
+ net.update()
+ end)()
+end)
diff --git a/script/vm/eachDef.lua b/script/vm/eachDef.lua
index 0fcc2df3..7825d2b1 100644
--- a/script/vm/eachDef.lua
+++ b/script/vm/eachDef.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
local guide = require 'parser.guide'
local files = require 'files'
diff --git a/script/vm/eachField.lua b/script/vm/eachField.lua
index 19ac77e9..292ac39b 100644
--- a/script/vm/eachField.lua
+++ b/script/vm/eachField.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
local guide = require 'parser.guide'
local await = require 'await'
diff --git a/script/vm/eachRef.lua b/script/vm/eachRef.lua
index 9aa6b783..e9229c38 100644
--- a/script/vm/eachRef.lua
+++ b/script/vm/eachRef.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
local guide = require 'parser.guide'
local util = require 'utility'
diff --git a/script/vm/getClass.lua b/script/vm/getClass.lua
index d95bab40..1b77171b 100644
--- a/script/vm/getClass.lua
+++ b/script/vm/getClass.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
local guide = require 'parser.guide'
diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua
index a3f9c714..1c54d593 100644
--- a/script/vm/getDocs.lua
+++ b/script/vm/getDocs.lua
@@ -1,6 +1,7 @@
local files = require 'files'
local util = require 'utility'
local guide = require 'parser.guide'
+---@type vm
local vm = require 'vm.vm'
local config = require 'config'
diff --git a/script/vm/getGlobals.lua b/script/vm/getGlobals.lua
index 26d10a64..37c7f13c 100644
--- a/script/vm/getGlobals.lua
+++ b/script/vm/getGlobals.lua
@@ -1,4 +1,5 @@
local guide = require 'parser.guide'
+---@type vm
local vm = require 'vm.vm'
local files = require 'files'
local util = require 'utility'
diff --git a/script/vm/getInfer.lua b/script/vm/getInfer.lua
index 45da493f..df1a64e1 100644
--- a/script/vm/getInfer.lua
+++ b/script/vm/getInfer.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
local guide = require 'parser.guide'
local util = require 'utility'
diff --git a/script/vm/getLibrary.lua b/script/vm/getLibrary.lua
index c2125212..b52f7240 100644
--- a/script/vm/getLibrary.lua
+++ b/script/vm/getLibrary.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
function vm.getLibraryName(source, deep)
diff --git a/script/vm/getLinks.lua b/script/vm/getLinks.lua
index 0bb1c6ff..c1690762 100644
--- a/script/vm/getLinks.lua
+++ b/script/vm/getLinks.lua
@@ -1,4 +1,5 @@
local guide = require 'parser.guide'
+---@type vm
local vm = require 'vm.vm'
local files = require 'files'
diff --git a/script/vm/getMeta.lua b/script/vm/getMeta.lua
index 67db3d11..b6265dcc 100644
--- a/script/vm/getMeta.lua
+++ b/script/vm/getMeta.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
local function eachMetaOfArg1(source, callback)
diff --git a/script/vm/guideInterface.lua b/script/vm/guideInterface.lua
index e646def8..a73067c5 100644
--- a/script/vm/guideInterface.lua
+++ b/script/vm/guideInterface.lua
@@ -1,3 +1,4 @@
+---@type vm
local vm = require 'vm.vm'
local files = require 'files'
local ws = require 'workspace'
diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua
index 3f3c563c..cfd0f4cb 100644
--- a/test/diagnostics/init.lua
+++ b/test/diagnostics/init.lua
@@ -847,20 +847,20 @@ local mt2 = {}
local v
print(v.field1 + 1)
print(v.field2 + 1)
-print(<!v.field3!> + 1)
+print(v.<!field3!> + 1)
print(v:method1())
print(v.method2())
-print(<!v:method3!>())
+print(v:<!method3!>())
---@type Bar
local v2
print(v2.field1 + 1)
print(v2.field2 + 1)
-print(<!v2.field3!> + 1)
+print(v2.<!field3!> + 1)
print(v2.field4 + 1)
print(v2:method1())
print(v2.method2())
-print(<!v2:method3!>())
+print(v2:<!method3!>())
local v3 = {}
print(v3.abc)
@@ -880,7 +880,7 @@ function Foo:method1() end
---@type Foo
local v
v:method1()
-<!v:method2!>() -- doc.class.name
+v:<!method2!>() -- doc.class.name
]]
-- checkUndefinedField 通过type找到class,涉及到 class 继承版
@@ -895,7 +895,7 @@ function Bar:method3() end
---@type Bar
local v
v:method1()
-<!v:method2!>() -- doc.class.name
+v:<!method2!>() -- doc.class.name
v:method3()
]]
@@ -904,8 +904,8 @@ TEST [[
---@class Foo
local Foo
function Foo:method1() end
-<!Foo:method2!>() -- doc.class
-<!Foo:method2!>() -- doc.class
+Foo:<!method2!>() -- doc.class
+Foo:<!method2!>() -- doc.class
]]
-- checkUndefinedField 没有@class的不检测
@@ -921,9 +921,9 @@ TEST [[
---@class Foo
local mt
function mt:method1()
- <!mt.method2!>() -- doc.class
+ mt.<!method2!>() -- doc.class
self.method1()
- return <!self.method2!>() -- doc.class.name
+ return self.<!method2!>() -- doc.class.name
end
]]