diff options
-rw-r--r-- | server/src/matcher/diagnostics.lua | 42 | ||||
-rw-r--r-- | server/src/matcher/vm.lua | 19 | ||||
-rw-r--r-- | server/test/diagnostics/init.lua | 116 | ||||
-rw-r--r-- | server/test/main.lua | 1 |
4 files changed, 151 insertions, 27 deletions
diff --git a/server/src/matcher/diagnostics.lua b/server/src/matcher/diagnostics.lua index 814beaa2..e896e4b5 100644 --- a/server/src/matcher/diagnostics.lua +++ b/server/src/matcher/diagnostics.lua @@ -1,10 +1,7 @@ local findLib = require 'matcher.find_lib' local function searchUnusedLocals(results, callback) - for _, var in ipairs(results.vars) do - if var.type ~= 'local' then - goto NEXT_VAR - end + for _, var in ipairs(results.locals) do if var.key == 'self' or var.key == '_' or var.key == '_ENV' @@ -22,33 +19,27 @@ local function searchUnusedLocals(results, callback) end local function searchUndefinedGlobal(results, callback) - for _, var in ipairs(results.vars) do - if var.type ~= 'field' then - goto NEXT_VAR - end - if var.parent.key ~= '_ENV' - and var.parent.key ~= '_G' - then - goto NEXT_VAR - end - if var.key:lower() == 'log' then - goto NEXT_VAR - end - if not var.key:find '%l' then + local env = results.locals[1] + for index, field in pairs(env.value.child) do + if field.value.lib then goto NEXT_VAR end - local lib = findLib(var) - if lib then - goto NEXT_VAR + if type(index) == 'string' then + if index:lower() == 'log' then + goto NEXT_VAR + end + if not index:find '%l' then + goto NEXT_VAR + end end - for _, info in ipairs(var) do + for _, info in ipairs(field) do if info.type == 'set' then goto NEXT_VAR end end - for _, info in ipairs(var) do + for _, info in ipairs(field) do if info.type == 'get' then - callback(info.source.start, info.source.finish, var.key) + callback(info.source.start, info.source.finish, tostring(index)) end end ::NEXT_VAR:: @@ -92,10 +83,7 @@ local function serachSpaces(lines, callback) end local function searchRedefinition(results, uri, callback) - for _, var in ipairs(results.vars) do - if var.type ~= 'local' then - goto NEXT_VAR - end + for _, var in ipairs(results.locals) do if var.key == '_' or var.key == '_ENV' then diff --git a/server/src/matcher/vm.lua b/server/src/matcher/vm.lua index 3264bd18..2339f769 100644 --- a/server/src/matcher/vm.lua +++ b/server/src/matcher/vm.lua @@ -12,6 +12,20 @@ function mt:createLocal(key, source, value) key = key, source = source or DefaultSource, } + + local shadow = self.scope.locals[key] + if shadow then + local group + if shadow.shadow then + group = shadow.shadow + else + group = { shadow } + shadow.shadow = group + end + group[#group+1] = loc + loc.shadow = group + end + self.scope.locals[key] = loc self.results.locals[#self.results.locals+1] = loc @@ -458,6 +472,10 @@ function mt:getSimple(simple, mode) if i < #simple then value = value[1] or self:createValue('nil') end + self.results.calls[#self.results.calls+1] = { + call = obj, + lastobj = simple[i-1], + } elseif obj.index then local index = self:getIndex(obj) field = self:getField(value, index, obj) @@ -819,6 +837,7 @@ local function compile(ast) fields = {}, labels = {}, funcs = {}, + calls = {}, }, }, mt) diff --git a/server/test/diagnostics/init.lua b/server/test/diagnostics/init.lua new file mode 100644 index 00000000..fb188318 --- /dev/null +++ b/server/test/diagnostics/init.lua @@ -0,0 +1,116 @@ +local matcher = require 'matcher' +local parser = require 'parser' + +rawset(_G, 'TEST', true) + +local function catch_target(script) + local list = {} + local cur = 1 + local cut = 0 + while true do + local start, finish = script:find('<!.-!>', cur) + if not start then + break + end + list[#list+1] = { start - cut, finish - 4 - cut } + cur = finish + 1 + cut = cut + 4 + end + local new_script = script:gsub('<!(.-)!>', '%1') + return new_script, list +end + +local function founded(targets, results) + if #targets ~= #results then + return false + end + for _, target in ipairs(targets) do + for _, result in ipairs(results) do + if target[1] == result[1] and target[2] == result[2] then + goto NEXT + end + end + do return false end + ::NEXT:: + end + return true +end + +function TEST(script) + local new_script, target = catch_target(script) + local ast = parser:ast(new_script) + assert(ast) + local lines = parser:lines(new_script) + local vm = matcher.vm(ast) + assert(vm) + local datas = matcher.diagnostics(vm, lines, 'test') + local results = {} + for i, data in ipairs(datas) do + results[i] = { data.start, data.finish } + end + + if results[1] then + if not founded(target, results) then + error(('%s\n%s'):format(table.dump(target), table.dump(results))) + end + else + assert(#target == 0) + end +end + +TEST [[ +local <!x!> +]] + +TEST [[ +print(<!x!>) +print(log) +print(X) +print(Log) +print(_VERSION) +print(<!y!>) +print(z) +z = 1 +]] + +TEST [[ +::<!LABEL!>:: +]] + +TEST [[ +<! !> +]] + +TEST [[ +x = 1<! !> +]] + +TEST [[ +local <!x!> +print(x) +local <!x!> +print(x) +]] + +TEST [[ +local x +print(x) +local x +print(x) +local x +print(x) +]] + +TEST [[ +local _ +print(_) +local _ +print(_) +local _ENV +print(_ENV) +]] + +TEST [[ +print(_G) +<!('string')!>:sub(1, 1) +]] diff --git a/server/test/main.lua b/server/test/main.lua index 9e619b70..8e340157 100644 --- a/server/test/main.lua +++ b/server/test/main.lua @@ -26,6 +26,7 @@ local function main() test 'vm' --test 'type_inference' test 'definition' + test 'diagnostics' --test 'find_lib' print('测试完成') |