diff options
-rw-r--r-- | changelog.md | 2 | ||||
-rw-r--r-- | locale/en-us/script.lua | 1 | ||||
-rw-r--r-- | locale/zh-cn/script.lua | 1 | ||||
-rw-r--r-- | script/core/diagnostics/different-requires.lua | 52 | ||||
-rw-r--r-- | script/parser/guide.lua | 3 | ||||
-rw-r--r-- | script/proto/define.lua | 2 | ||||
-rw-r--r-- | test/crossfile/diagnostic.lua | 137 | ||||
-rw-r--r-- | test/crossfile/init.lua | 1 | ||||
-rw-r--r-- | test/diagnostics/init.lua | 1 |
9 files changed, 199 insertions, 1 deletions
diff --git a/changelog.md b/changelog.md index ed39ed42..f5f9eac0 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,8 @@ + `Lua.diagnostics.ignoredFiles` + `Lua.completion.showWord` + `Lua.completion.requireSeparator` +* `NEW` diagnostics: + + `different-requires` * `CHG` hover: improve showing multi defines * `CHG` hover: improve showing multi comments at enums * `CHG` hint: `Lua.hint.paramName` now supports `Disable`, `Literal` and `All` diff --git a/locale/en-us/script.lua b/locale/en-us/script.lua index 35e1df8f..16a66b0a 100644 --- a/locale/en-us/script.lua +++ b/locale/en-us/script.lua @@ -41,6 +41,7 @@ DIAG_COSE_NON_OBJECT = 'Cannot close a value of this type. (Unless set `__clo DIAG_COUNT_DOWN_LOOP = 'Do you mean `{}` ?' DIAG_IMPLICIT_ANY = 'Can not infer type.' DIAG_DEPRECATED = 'Deprecated.' +DIAG_DIFFERENT_REQUIRES = 'The same file is required with different names.' DIAG_CIRCLE_DOC_CLASS = 'Circularly inherited classes.' DIAG_DOC_FIELD_NO_CLASS = 'The field must be defined after the class.' diff --git a/locale/zh-cn/script.lua b/locale/zh-cn/script.lua index 94787304..f1e9d95f 100644 --- a/locale/zh-cn/script.lua +++ b/locale/zh-cn/script.lua @@ -41,6 +41,7 @@ DIAG_COSE_NON_OBJECT = '无法 close 此类型的值。(除非给此类型 DIAG_COUNT_DOWN_LOOP = '你的意思是 `{}` 吗?' DIAG_IMPLICIT_ANY = '无法推测出类型。' DIAG_DEPRECATED = '已废弃。' +DIAG_DIFFERENT_REQUIRES = '使用了不同的名字 require 了同一个文件。' DIAG_CIRCLE_DOC_CLASS = '循环继承的类。' DIAG_DOC_FIELD_NO_CLASS = '字段必须定义在类之后。' diff --git a/script/core/diagnostics/different-requires.lua b/script/core/diagnostics/different-requires.lua new file mode 100644 index 00000000..9e3dfc8f --- /dev/null +++ b/script/core/diagnostics/different-requires.lua @@ -0,0 +1,52 @@ +local files = require 'files' +local guide = require 'parser.guide' +local lang = require 'language' +local config = require 'config' +local vm = require 'vm' +local ws = require 'workspace' + +return function (uri, callback) + local state = files.getState(uri) + if not state then + return + end + local cache = vm.getCache 'different-requires' + guide.eachSpecialOf(state.ast, 'require', function (source) + local call = source.next + if not call or call.type ~= 'call' then + return + end + local arg1 = call.args and call.args[1] + if not arg1 or arg1.type ~= 'string' then + return + end + local literal = arg1[1] + local results = ws.findUrisByRequirePath(literal) + local result = results and results[1] + if not result then + return + end + local other = cache[result] + if not other then + cache[result] = { + source = arg1, + require = literal, + } + return + end + if other.require ~= literal then + callback { + start = arg1.start, + finish = arg1.finish, + related = { + { + start = other.source.start, + finish = other.source.finish, + uri = guide.getUri(other.source), + } + }, + message = lang.script('DIAG_DIFFERENT_REQUIRES'), + } + end + end) +end diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 378d2613..6dcfbf95 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -722,6 +722,9 @@ function m.eachSource(ast, callback) end --- 获取指定的 special +---@param ast parser.guide.object +---@param name string +---@param callback fun(source: parser.guide.object) function m.eachSpecialOf(ast, name, callback) local root = m.getRoot(ast) if not root.specials then diff --git a/script/proto/define.lua b/script/proto/define.lua index a07a3903..9fbbea35 100644 --- a/script/proto/define.lua +++ b/script/proto/define.lua @@ -74,6 +74,7 @@ m.DiagnosticDefaultSeverity = { ['count-down-loop'] = 'Warning', ['no-implicit-any'] = 'Information', ['deprecated'] = 'Warning', + ['different-requires'] = 'Warning', ['duplicate-doc-class'] = 'Warning', ['undefined-doc-class'] = 'Warning', @@ -125,6 +126,7 @@ m.DiagnosticDefaultNeededFileStatus = { ['count-down-loop'] = 'Any', ['no-implicit-any'] = 'None', ['deprecated'] = 'Opened', + ['different-requires'] = 'Any', ['duplicate-doc-class'] = 'Any', ['undefined-doc-class'] = 'Any', diff --git a/test/crossfile/diagnostic.lua b/test/crossfile/diagnostic.lua new file mode 100644 index 00000000..3d4eb552 --- /dev/null +++ b/test/crossfile/diagnostic.lua @@ -0,0 +1,137 @@ +local files = require 'files' +local furi = require 'file-uri' +local core = require 'core.diagnostics' +local config = require 'config' +local platform = require 'bee.platform' + +config.get 'Lua.diagnostics.neededFileStatus'['deprecated'] = 'Any' + +rawset(_G, 'TEST', true) + +local function catch_target(script, sep) + local list = {} + local cur = 1 + local cut = 0 + while true do + local start, finish = script:find(('<%%%s.-%%%s>'):format(sep, sep), 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(('<%%%s(.-)%%%s>'):format(sep, sep), '%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] + and target[3] == result[3] + then + goto NEXT + end + end + do return false end + ::NEXT:: + end + return true +end + +function TEST(datas) + files.removeAll() + + local targetList = {} + local sourceUri + for _, data in ipairs(datas) do + local uri = furi.encode(data.path) + local new, list = catch_target(data.content, '!') + for _, position in ipairs(list) do + targetList[#targetList+1] = { + position[1], + position[2], + uri, + } + end + data.content = new + files.setText(uri, new) + end + + local result = {} + for _, data in ipairs(datas) do + local uri = furi.encode(data.path) + local results = {} + core(uri, function (result) + for _, res in ipairs(result) do + results[#results+1] = res + end + end) + for i, position in ipairs(results) do + result[i] = { + position.start, + position.finish, + uri, + } + end + end + assert(founded(targetList, result)) +end + +TEST { + { + path = 'f/a.lua', + content = '', + }, + { + path = 'b.lua', + content = 'require "a"', + }, + { + path = 'c.lua', + content = 'require <!"f.a"!>', + }, +} + +TEST { + { + path = 'f/a.lua', + content = '', + }, + { + path = 'a.lua', + content = '', + }, + { + path = 'b.lua', + content = 'require "a"', + }, + { + path = 'c.lua', + content = 'require "f.a"', + }, +} + +TEST { + { + path = 'a.lua', + content = '', + }, + { + path = 'f/a.lua', + content = '', + }, + { + path = 'b.lua', + content = 'require "a"', + }, + { + path = 'c.lua', + content = 'require "f.a"', + }, +} diff --git a/test/crossfile/init.lua b/test/crossfile/init.lua index a7402815..1ed2a943 100644 --- a/test/crossfile/init.lua +++ b/test/crossfile/init.lua @@ -3,3 +3,4 @@ require 'crossfile.references' require 'crossfile.allreferences' require 'crossfile.hover' require 'crossfile.completion' +require 'crossfile.diagnostic' diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua index b90b4b26..54ac73ef 100644 --- a/test/diagnostics/init.lua +++ b/test/diagnostics/init.lua @@ -2,7 +2,6 @@ local core = require 'core.diagnostics' local files = require 'files' local config = require 'config' local util = require 'utility' -local define = require 'proto.define' config.get 'Lua.diagnostics.neededFileStatus'['deprecated'] = 'Any' |