summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
Diffstat (limited to 'script')
-rw-r--r--script/core/completion/completion.lua7
-rw-r--r--script/core/diagnostics/cast-type-mismatch.lua45
-rw-r--r--script/core/diagnostics/unknown-cast-variable.lua32
-rw-r--r--script/files.lua4
-rw-r--r--script/fs-utility.lua2
-rw-r--r--script/parser/guide.lua4
-rw-r--r--script/parser/luadoc.lua3
-rw-r--r--script/proto/define.lua4
-rw-r--r--script/provider/markdown.lua2
-rw-r--r--script/vm/function.lua22
-rw-r--r--script/vm/type.lua5
11 files changed, 120 insertions, 10 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index 165dbac5..52ec7a18 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -1103,7 +1103,7 @@ local function tryLabelInString(label, source)
if not state or not state.ast then
return label
end
- if not matchKey(source[1], state.ast[1]) then
+ if not matchKey(source[1], state.ast[1]--[[@as string]]) then
return nil
end
return util.viewString(state.ast[1], source[2])
@@ -1242,6 +1242,9 @@ local function tryIndex(state, position, results)
return
end
local word = parent.next and parent.next.index and parent.next.index[1]
+ if not word then
+ return
+ end
checkField(state, word, position, position, parent, oop, results)
end
@@ -1426,6 +1429,7 @@ local function tryCallArg(state, position, results)
if src.type == 'doc.type.string'
or src.type == 'doc.type.integer'
or src.type == 'doc.type.boolean' then
+ ---@cast src parser.object
enums[#enums+1] = {
label = vm.viewObject(src, state.uri),
description = src.comment,
@@ -1439,6 +1443,7 @@ local function tryCallArg(state, position, results)
}
end
if src.type == 'doc.type.function' then
+ ---@cast src parser.object
local insertText = buildInsertDocFunction(src)
local description
if src.comment then
diff --git a/script/core/diagnostics/cast-type-mismatch.lua b/script/core/diagnostics/cast-type-mismatch.lua
new file mode 100644
index 00000000..ecee6a84
--- /dev/null
+++ b/script/core/diagnostics/cast-type-mismatch.lua
@@ -0,0 +1,45 @@
+local files = require 'files'
+local guide = require 'parser.guide'
+local lang = require 'language'
+local vm = require 'vm'
+local await = require 'await'
+
+---@async
+return function (uri, callback)
+ local state = files.getState(uri)
+ if not state then
+ return
+ end
+
+ if not state.ast.docs then
+ return
+ end
+
+ for _, doc in ipairs(state.ast.docs) do
+ if doc.type == 'doc.cast' then
+ await.delay()
+ local defs = vm.getDefs(doc.loc)
+ local loc = defs[1]
+ if loc then
+ local defNode = vm.compileNode(loc)
+ if defNode:getData 'hasDefined' then
+ for _, cast in ipairs(doc.casts) do
+ if not cast.mode and cast.extends then
+ local refNode = vm.compileNode(cast.extends)
+ if not vm.canCastType(uri, defNode, refNode) then
+ callback {
+ start = cast.extends.start,
+ finish = cast.extends.finish,
+ message = lang.script('DIAG_UNKNOWN_CAST_VARIABLE', {
+ def = vm.getInfer(defNode):view(uri),
+ ref = vm.getInfer(refNode):view(uri),
+ })
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/script/core/diagnostics/unknown-cast-variable.lua b/script/core/diagnostics/unknown-cast-variable.lua
new file mode 100644
index 00000000..cfa25ed8
--- /dev/null
+++ b/script/core/diagnostics/unknown-cast-variable.lua
@@ -0,0 +1,32 @@
+local files = require 'files'
+local guide = require 'parser.guide'
+local lang = require 'language'
+local vm = require 'vm'
+local await = require 'await'
+
+---@async
+return function (uri, callback)
+ local state = files.getState(uri)
+ if not state then
+ return
+ end
+
+ if not state.ast.docs then
+ return
+ end
+
+ for _, doc in ipairs(state.ast.docs) do
+ if doc.type == 'doc.cast' then
+ await.delay()
+ local defs = vm.getDefs(doc.loc)
+ local loc = defs[1]
+ if not loc then
+ callback {
+ start = doc.loc.start,
+ finish = doc.loc.finish,
+ message = lang.script('DIAG_UNKNOWN_CAST_VARIABLE', doc[1])
+ }
+ end
+ end
+ end
+end
diff --git a/script/files.lua b/script/files.lua
index 252a6ee5..d0225f45 100644
--- a/script/files.lua
+++ b/script/files.lua
@@ -14,6 +14,9 @@ local progress = require "progress"
local encoder = require 'encoder'
local scope = require 'workspace.scope'
+---@class file
+---@field content string
+
---@class files
local m = {}
@@ -23,6 +26,7 @@ m.assocVersion = -1
function m.reset()
m.openMap = {}
+ ---@type table<string, file>
m.fileMap = {}
m.dllMap = {}
m.visible = {}
diff --git a/script/fs-utility.lua b/script/fs-utility.lua
index 08aae98a..cca65521 100644
--- a/script/fs-utility.lua
+++ b/script/fs-utility.lua
@@ -40,7 +40,7 @@ function m.loadFile(path, keepBom)
end
--- 写入文件
----@param path string
+---@param path any
---@param content string
function m.saveFile(path, content)
if type(path) ~= 'string' then
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 3f68ccd2..7a9cb875 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -478,7 +478,9 @@ function m.getLocal(source, name, pos)
if not block then
return nil
end
- if block.start <= pos and block.finish >= pos then
+ if block.start <= pos
+ and block.finish >= pos
+ and blockTypes[block.type] then
break
end
block = block.parent
diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua
index 420e78cd..c4f40ac4 100644
--- a/script/parser/luadoc.lua
+++ b/script/parser/luadoc.lua
@@ -1661,6 +1661,9 @@ return function (state)
end
end
+ ast.docs.start = ast.start
+ ast.docs.finish = ast.finish
+
if #ast.docs == 0 then
return
end
diff --git a/script/proto/define.lua b/script/proto/define.lua
index 45fbba9e..30ef621e 100644
--- a/script/proto/define.lua
+++ b/script/proto/define.lua
@@ -62,6 +62,8 @@ m.DiagnosticDefaultSeverity = {
['doc-field-no-class'] = 'Warning',
['duplicate-doc-field'] = 'Warning',
['unknown-diag-code'] = 'Warning',
+ ['unknown-cast-variable'] = 'Warning',
+ ['cast-type-mismatch'] = 'Warning',
['codestyle-check'] = 'Warning',
['spell-check'] = 'Information',
@@ -126,6 +128,8 @@ m.DiagnosticDefaultNeededFileStatus = {
['doc-field-no-class'] = 'Any',
['duplicate-doc-field'] = 'Any',
['unknown-diag-code'] = 'Any',
+ ['unknown-cast-variable'] = 'Any',
+ ['cast-type-mismatch'] = 'Any',
['codestyle-check'] = 'None',
['spell-check'] = 'None',
diff --git a/script/provider/markdown.lua b/script/provider/markdown.lua
index 6b007713..f2f7f777 100644
--- a/script/provider/markdown.lua
+++ b/script/provider/markdown.lua
@@ -10,7 +10,7 @@ function mt:__tostring()
end
---@param language string
----@param text string|markdown
+---@param text? string|markdown
function mt:add(language, text)
if not text then
return self
diff --git a/script/vm/function.lua b/script/vm/function.lua
index 2a169bd6..e8fadb38 100644
--- a/script/vm/function.lua
+++ b/script/vm/function.lua
@@ -75,14 +75,15 @@ function vm.countParamsOfNode(node)
end
---@param func parser.object
+---@param mark? table
---@return integer min
---@return integer max
-function vm.countReturnsOfFunction(func)
+function vm.countReturnsOfFunction(func, mark)
if func.type == 'function' then
local min, max
if func.returns then
for _, ret in ipairs(func.returns) do
- local rmin, rmax = vm.countList(ret)
+ local rmin, rmax = vm.countList(ret, mark)
if not min or rmin < min then
min = rmin
end
@@ -126,14 +127,15 @@ function vm.countReturnsOfFunction(func)
end
---@param func parser.object
+---@param mark? table
---@return integer min
---@return integer max
-function vm.countReturnsOfCall(func, args)
+function vm.countReturnsOfCall(func, args, mark)
local funcs = vm.getMatchedFunctions(func, args)
local min
local max
for _, f in ipairs(funcs) do
- local rmin, rmax = vm.countReturnsOfFunction(f)
+ local rmin, rmax = vm.countReturnsOfFunction(f, mark)
if not min or rmin < min then
min = rmin
end
@@ -145,9 +147,10 @@ function vm.countReturnsOfCall(func, args)
end
---@param list parser.object[]?
+---@param mark? table
---@return integer min
---@return integer max
-function vm.countList(list)
+function vm.countList(list, mark)
if not list then
return 0, 0
end
@@ -160,7 +163,14 @@ function vm.countList(list)
return #list - 1, math.huge
end
if lastArg.type == 'call' then
- local rmin, rmax = vm.countReturnsOfCall(lastArg.node, lastArg.args)
+ if not mark then
+ mark = {}
+ end
+ if mark[lastArg] then
+ return #list - 1, math.huge
+ end
+ mark[lastArg] = true
+ local rmin, rmax = vm.countReturnsOfCall(lastArg.node, lastArg.args, mark)
return #list - 1 + rmin, #list - 1 + rmax
end
return #list, #list
diff --git a/script/vm/type.lua b/script/vm/type.lua
index fa78f735..208f21ed 100644
--- a/script/vm/type.lua
+++ b/script/vm/type.lua
@@ -130,6 +130,11 @@ function vm.isSubType(uri, child, parent, mark)
end
end
end
+ if set.type == 'doc.alias' and set.extends then
+ if vm.isSubType(uri, vm.compileNode(set.extends), parent, mark) then
+ return true
+ end
+ end
end
end
end