summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
Diffstat (limited to 'script')
-rw-r--r--script/core/diagnostics/assign-type-mismatch.lua47
-rw-r--r--script/core/diagnostics/init.lua13
-rw-r--r--script/core/diagnostics/type-check-assign.lua20
-rw-r--r--script/proto/define.lua4
-rw-r--r--script/vm/compiler.lua18
-rw-r--r--script/vm/type.lua10
6 files changed, 74 insertions, 38 deletions
diff --git a/script/core/diagnostics/assign-type-mismatch.lua b/script/core/diagnostics/assign-type-mismatch.lua
new file mode 100644
index 00000000..38cfc674
--- /dev/null
+++ b/script/core/diagnostics/assign-type-mismatch.lua
@@ -0,0 +1,47 @@
+local files = require 'files'
+local lang = require 'language'
+local guide = require 'parser.guide'
+local vm = require 'vm'
+local await = require 'await'
+
+local checkTypes = {
+ 'setlocal',
+ 'setglobal',
+ 'setfield',
+ 'setindex',
+ 'setmethod',
+ 'tablefield',
+ 'tableindex'
+}
+
+---@async
+return function (uri, callback)
+ local state = files.getState(uri)
+ if not state then
+ return
+ end
+
+ ---@async
+ guide.eachSourceTypes(state.ast, checkTypes, function (source)
+ local value = source.value
+ if not value then
+ return
+ end
+ await.delay()
+ local varNode = vm.compileNode(source)
+ local valueNode = vm.compileNode(value)
+ if vm.getInfer(varNode):hasUnknown(uri) then
+ return
+ end
+ if not vm.isSubType(uri, valueNode, varNode) then
+ callback {
+ start = source.start,
+ finish = source.finish,
+ message = lang.script('DIAG_ASSIGN_TYPE_MISMATCH', {
+ loc = vm.getInfer(varNode):view(uri),
+ ref = vm.getInfer(valueNode):view(uri),
+ }),
+ }
+ end
+ end)
+end
diff --git a/script/core/diagnostics/init.lua b/script/core/diagnostics/init.lua
index e9af8ea3..746052b0 100644
--- a/script/core/diagnostics/init.lua
+++ b/script/core/diagnostics/init.lua
@@ -7,12 +7,13 @@ local util = require 'utility'
-- 把耗时最长的诊断放到最后面
local diagSort = {
- ['redundant-value'] = 100,
- ['not-yieldable'] = 101,
- ['deprecated'] = 102,
- ['undefined-field'] = 103,
- ['redundant-parameter'] = 104,
- ['cast-local-type'] = 105,
+ ['redundant-value'] = 100,
+ ['not-yieldable'] = 101,
+ ['deprecated'] = 102,
+ ['undefined-field'] = 103,
+ ['redundant-parameter'] = 104,
+ ['cast-local-type'] = 105,
+ ['assign-type-mismatch'] = 106,
}
local diagList = {}
diff --git a/script/core/diagnostics/type-check-assign.lua b/script/core/diagnostics/type-check-assign.lua
deleted file mode 100644
index 6b3c73b3..00000000
--- a/script/core/diagnostics/type-check-assign.lua
+++ /dev/null
@@ -1,20 +0,0 @@
-local files = require 'files'
-local lang = require 'language'
-local guide = require 'parser.guide'
-local vm = require 'vm'
-
-return function (uri, callback)
- local state = files.getState(uri)
- if not state then
- return
- end
-
- guide.eachSourceType(state.ast, 'setlocal', function (source)
- local value = source.value
- if not value then
- return
- end
- local locNode = vm.compileNode(source)
- local valueNode = vm.compileNode(value)
- end)
-end
diff --git a/script/proto/define.lua b/script/proto/define.lua
index 2ea1fd90..8c7c7a0f 100644
--- a/script/proto/define.lua
+++ b/script/proto/define.lua
@@ -50,7 +50,7 @@ m.DiagnosticDefaultSeverity = {
['discard-returns'] = 'Warning',
['need-check-nil'] = 'Warning',
['cast-local-type'] = 'Warning',
- ['type-check-assign'] = 'Warning',
+ ['assign-type-mismatch'] = 'Warning',
['duplicate-doc-alias'] = 'Warning',
['undefined-doc-class'] = 'Warning',
@@ -113,7 +113,7 @@ m.DiagnosticDefaultNeededFileStatus = {
['discard-returns'] = 'Opened',
['need-check-nil'] = 'Opened',
['cast-local-type'] = 'Any',
- ['type-check-assign'] = 'Any',
+ ['assign-type-mismatch'] = 'Any',
['duplicate-doc-alias'] = 'Any',
['undefined-doc-class'] = 'Any',
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index dd41d7b6..bc85407d 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -637,16 +637,14 @@ local function compileByLocalID(source)
end
end
end
- for _, src in ipairs(sources) do
- if src.value then
- if not hasMarkDoc or guide.isLiteral(src.value) then
- if src.value.type ~= 'nil' then
- local valueNode = vm.compileNode(src.value)
- if valueNode:hasType 'unknown' then
- vm.setNode(source, valueNode:copy():remove 'unknown')
- else
- vm.setNode(source, valueNode)
- end
+ if not hasMarkDoc then
+ for _, src in ipairs(sources) do
+ if src.value and src.value.type ~= 'nil' then
+ local valueNode = vm.compileNode(src.value)
+ if valueNode:hasType 'unknown' then
+ vm.setNode(source, valueNode:copy():remove 'unknown')
+ else
+ vm.setNode(source, valueNode)
end
end
end
diff --git a/script/vm/type.lua b/script/vm/type.lua
index 3ad60dae..db378878 100644
--- a/script/vm/type.lua
+++ b/script/vm/type.lua
@@ -50,6 +50,11 @@ function vm.isSubType(uri, child, parent, mark)
return false
end
end
+ if child:isOptional() then
+ if not vm.isSubType(uri, 'nil', parent, mark) then
+ return false
+ end
+ end
return true
end
@@ -64,6 +69,11 @@ function vm.isSubType(uri, child, parent, mark)
return true
end
end
+ if parent:isOptional() then
+ if vm.isSubType(uri, child, 'nil', mark) then
+ return true
+ end
+ end
return false
end