From 137ede024f4ddeac7c602351371447cd6cf36091 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Mon, 4 Nov 2019 17:28:42 +0800 Subject: =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AF=8A=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server-beta/src/core/diagnostics/ambiguity-1.lua | 3 + .../src/core/diagnostics/duplicate-index.lua | 3 + .../src/core/diagnostics/duplicate-method.lua | 3 + server-beta/src/core/diagnostics/emmy-lua.lua | 3 + server-beta/src/core/diagnostics/empty-block.lua | 3 + .../src/core/diagnostics/global-in-nil-env.lua | 3 + server-beta/src/core/diagnostics/init.lua | 29 +++ .../src/core/diagnostics/lowercase-global.lua | 3 + server-beta/src/core/diagnostics/newfield-call.lua | 3 + server-beta/src/core/diagnostics/newline-call.lua | 3 + .../src/core/diagnostics/redefined-local.lua | 3 + .../src/core/diagnostics/redundant-parameter.lua | 3 + .../src/core/diagnostics/redundant-value.lua | 3 + server-beta/src/core/diagnostics/set-const.lua | 3 + .../src/core/diagnostics/trailing-space.lua | 3 + .../src/core/diagnostics/undefined-env-child.lua | 3 + .../src/core/diagnostics/undefined-global.lua | 3 + .../src/core/diagnostics/unused-function.lua | 3 + server-beta/src/core/diagnostics/unused-label.lua | 3 + server-beta/src/core/diagnostics/unused-local.lua | 38 ++++ server-beta/src/core/diagnostics/unused-vararg.lua | 3 + server-beta/src/language.lua | 7 +- server-beta/src/parser/guide.lua | 17 ++ server-beta/src/proto/define.lua | 109 ++++++++++ server-beta/src/proto/interface.lua | 72 ------- server-beta/src/proto/provider.lua | 12 +- server-beta/test.lua | 6 +- server-beta/test/diagnostics/init.lua | 239 ++++++++++----------- 28 files changed, 380 insertions(+), 206 deletions(-) create mode 100644 server-beta/src/core/diagnostics/ambiguity-1.lua create mode 100644 server-beta/src/core/diagnostics/duplicate-index.lua create mode 100644 server-beta/src/core/diagnostics/duplicate-method.lua create mode 100644 server-beta/src/core/diagnostics/emmy-lua.lua create mode 100644 server-beta/src/core/diagnostics/empty-block.lua create mode 100644 server-beta/src/core/diagnostics/global-in-nil-env.lua create mode 100644 server-beta/src/core/diagnostics/init.lua create mode 100644 server-beta/src/core/diagnostics/lowercase-global.lua create mode 100644 server-beta/src/core/diagnostics/newfield-call.lua create mode 100644 server-beta/src/core/diagnostics/newline-call.lua create mode 100644 server-beta/src/core/diagnostics/redefined-local.lua create mode 100644 server-beta/src/core/diagnostics/redundant-parameter.lua create mode 100644 server-beta/src/core/diagnostics/redundant-value.lua create mode 100644 server-beta/src/core/diagnostics/set-const.lua create mode 100644 server-beta/src/core/diagnostics/trailing-space.lua create mode 100644 server-beta/src/core/diagnostics/undefined-env-child.lua create mode 100644 server-beta/src/core/diagnostics/undefined-global.lua create mode 100644 server-beta/src/core/diagnostics/unused-function.lua create mode 100644 server-beta/src/core/diagnostics/unused-label.lua create mode 100644 server-beta/src/core/diagnostics/unused-local.lua create mode 100644 server-beta/src/core/diagnostics/unused-vararg.lua create mode 100644 server-beta/src/proto/define.lua delete mode 100644 server-beta/src/proto/interface.lua (limited to 'server-beta') diff --git a/server-beta/src/core/diagnostics/ambiguity-1.lua b/server-beta/src/core/diagnostics/ambiguity-1.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/ambiguity-1.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/duplicate-index.lua b/server-beta/src/core/diagnostics/duplicate-index.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/duplicate-index.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/duplicate-method.lua b/server-beta/src/core/diagnostics/duplicate-method.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/duplicate-method.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/emmy-lua.lua b/server-beta/src/core/diagnostics/emmy-lua.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/emmy-lua.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/empty-block.lua b/server-beta/src/core/diagnostics/empty-block.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/empty-block.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/global-in-nil-env.lua b/server-beta/src/core/diagnostics/global-in-nil-env.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/global-in-nil-env.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/init.lua b/server-beta/src/core/diagnostics/init.lua new file mode 100644 index 00000000..69815003 --- /dev/null +++ b/server-beta/src/core/diagnostics/init.lua @@ -0,0 +1,29 @@ +local files = require 'files' +local define = require 'proto.define' +local config = require 'config' + +local function check(uri, name, level, results) + if config.config.diagnostics.disable[name] then + return + end + level = config.config.diagnostics.severity[name] or level + require('core.diagnostics.' .. name)(uri, function (result) + result.level = level or result.level + result.code = name + results[#results+1] = result + end) +end + +return function (uri) + local ast = files.getAst(uri) + if not ast then + return nil + end + local results = {} + + for name, level in pairs(define.DiagnosticDefaultSeverity) do + check(uri, name, level, results) + end + + return results +end diff --git a/server-beta/src/core/diagnostics/lowercase-global.lua b/server-beta/src/core/diagnostics/lowercase-global.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/lowercase-global.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/newfield-call.lua b/server-beta/src/core/diagnostics/newfield-call.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/newfield-call.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/newline-call.lua b/server-beta/src/core/diagnostics/newline-call.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/newline-call.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/redefined-local.lua b/server-beta/src/core/diagnostics/redefined-local.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/redefined-local.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/redundant-parameter.lua b/server-beta/src/core/diagnostics/redundant-parameter.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/redundant-parameter.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/redundant-value.lua b/server-beta/src/core/diagnostics/redundant-value.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/redundant-value.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/set-const.lua b/server-beta/src/core/diagnostics/set-const.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/set-const.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/trailing-space.lua b/server-beta/src/core/diagnostics/trailing-space.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/trailing-space.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/undefined-env-child.lua b/server-beta/src/core/diagnostics/undefined-env-child.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/undefined-env-child.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/undefined-global.lua b/server-beta/src/core/diagnostics/undefined-global.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/undefined-global.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/unused-function.lua b/server-beta/src/core/diagnostics/unused-function.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/unused-function.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/unused-label.lua b/server-beta/src/core/diagnostics/unused-label.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/unused-label.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/core/diagnostics/unused-local.lua b/server-beta/src/core/diagnostics/unused-local.lua new file mode 100644 index 00000000..9b97ca88 --- /dev/null +++ b/server-beta/src/core/diagnostics/unused-local.lua @@ -0,0 +1,38 @@ +local files = require 'files' +local guide = require 'parser.guide' +local define = require 'proto.define' +local lang = require 'language' + +local function hasGet(loc) + if not loc.ref then + return false + end + for _, ref in ipairs(loc.ref) do + if ref.type == 'get' then + return true + end + end + return false +end + +return function (uri, callback) + local ast = files.getAst(uri) + if not ast then + return + end + guide.eachSourceType(ast.ast, 'local', function (source) + local name = source[1] + if name == '_' + or name == '_ENV' then + return + end + if not hasGet(source) then + callback { + start = source.start, + finish = source.finish, + tags = { define.DiagnosticTag.Unnecessary }, + message = lang.script('DIAG_UNUSED_LOCAL', name), + } + end + end) +end diff --git a/server-beta/src/core/diagnostics/unused-vararg.lua b/server-beta/src/core/diagnostics/unused-vararg.lua new file mode 100644 index 00000000..b3d19c21 --- /dev/null +++ b/server-beta/src/core/diagnostics/unused-vararg.lua @@ -0,0 +1,3 @@ +return function () + +end diff --git a/server-beta/src/language.lua b/server-beta/src/language.lua index 3294c5b2..d1a4b4cf 100644 --- a/server-beta/src/language.lua +++ b/server-beta/src/language.lua @@ -1,5 +1,6 @@ -local fs = require 'bee.filesystem' -local lni = require 'lni' +local fs = require 'bee.filesystem' +local lni = require 'lni' +local util = require 'utility' local function supportLanguage() local list = {} @@ -33,7 +34,7 @@ end local function loadFileByLanguage(name, language) local path = ROOT / 'locale' / language / (name .. '.lni') - local buf = io.load(path) + local buf = util.loadFile(path:string()) if not buf then return {} end diff --git a/server-beta/src/parser/guide.lua b/server-beta/src/parser/guide.lua index 0ca83489..773fb6d5 100644 --- a/server-beta/src/parser/guide.lua +++ b/server-beta/src/parser/guide.lua @@ -307,6 +307,23 @@ function m.eachSourceContain(ast, offset, callback) end end +--- 遍历所有指定类型的source +function m.eachSourceType(ast, type, callback) + local cache = ast.typeCache + if not cache then + cache = {} + ast.typeCache = cache + m.eachSource(ast, function (source) + if source.type == type then + cache[#cache+1] = source + end + end) + end + for i = 1, #cache do + callback(cache[i]) + end +end + --- 遍历所有的source function m.eachSource(ast, callback) local list = { ast } diff --git a/server-beta/src/proto/define.lua b/server-beta/src/proto/define.lua new file mode 100644 index 00000000..9401e9e5 --- /dev/null +++ b/server-beta/src/proto/define.lua @@ -0,0 +1,109 @@ +local guide = require 'parser.guide' + +local m = {} + +--- 获取 position 对应的光标位置 +---@param lines table +---@param text string +---@param position position +---@return integer +function m.offset(lines, text, position) + local row = position.line + local start = guide.lineRange(lines, row) + local offset = utf8.offset(text, position.character + 1, start) + return offset +end + +--- 将光标位置转化为 position +---@alias position table +---@param lines table +---@param text string +---@param offset integer +---@return position +function m.position(lines, text, offset) + local row, col = guide.positionOf(lines, offset) + local start = guide.lineRange(lines, row) + local ucol = utf8.len(text, start + 1, start + col, true) + return { + line = row, + character = ucol, + } +end + +--- 将2个光标位置转化为 range +---@alias range table +---@param lines table +---@param text string +---@param offset1 integer +---@param offset2 integer +function m.range(lines, text, offset1, offset2) + return { + start = m.position(lines, text, offset1), + ['end'] = m.position(lines, text, offset2), + } +end + +---@alias location table +---@param uri string +---@param range range +---@return location +function m.location(uri, range) + return { + uri = uri, + range = range, + } +end + +---@alias locationLink table +---@param uri string +---@param range range +---@param selection range +---@param origin range +function m.locationLink(uri, range, selection, origin) + return { + targetUri = uri, + targetRange = range, + targetSelectionRange = selection, + originSelectionRange = origin, + } +end + +--- 诊断等级 +m.DiagnosticSeverity = { + Error = 1, + Warning = 2, + Information = 3, + Hint = 4, +} + +--- 诊断类型与默认等级 +m.DiagnosticDefaultSeverity = { + ['unused-local'] = 'Hint', + ['unused-function'] = 'Hint', + ['undefined-global'] = 'Warning', + ['global-in-nil-env'] = 'Warning', + ['unused-label'] = 'Hint', + ['unused-vararg'] = 'Hint', + ['trailing-space'] = 'Hint', + ['redefined-local'] = 'Hint', + ['newline-call'] = 'Information', + ['newfield-call'] = 'Warning', + ['redundant-parameter'] = 'Hint', + ['ambiguity-1'] = 'Warning', + ['lowercase-global'] = 'Information', + ['undefined-env-child'] = 'Information', + ['duplicate-index'] = 'Warning', + ['duplicate-method'] = 'Warning', + ['empty-block'] = 'Hint', + ['redundant-value'] = 'Hint', + ['emmy-lua'] = 'Warning', + ['set-const'] = 'Error', +} + +--- 诊断报告标签 +m.DiagnosticTag = { + Unnecessary = 1, + Deprecated = 2, +} + +return m diff --git a/server-beta/src/proto/interface.lua b/server-beta/src/proto/interface.lua deleted file mode 100644 index 6af0c996..00000000 --- a/server-beta/src/proto/interface.lua +++ /dev/null @@ -1,72 +0,0 @@ -local guide = require 'parser.guide' - -local m = {} - - ---- 获取 position 对应的光标位置 ----@param lines table ----@param text string ----@param position position ----@return integer -function m.offset(lines, text, position) - local row = position.line - local start = guide.lineRange(lines, row) - local offset = utf8.offset(text, position.character + 1, start) - return offset -end - ---- 将光标位置转化为 position ----@alias position table ----@param lines table ----@param text string ----@param offset integer ----@return position -function m.position(lines, text, offset) - local row, col = guide.positionOf(lines, offset) - local start = guide.lineRange(lines, row) - local ucol = utf8.len(text, start + 1, start + col, true) - return { - line = row, - character = ucol, - } -end - ---- 将2个光标位置转化为 range ----@alias range table ----@param lines table ----@param text string ----@param offset1 integer ----@param offset2 integer -function m.range(lines, text, offset1, offset2) - return { - start = m.position(lines, text, offset1), - ['end'] = m.position(lines, text, offset2), - } -end - ----@alias location table ----@param uri string ----@param range range ----@return location -function m.location(uri, range) - return { - uri = uri, - range = range, - } -end - ----@alias locationLink table ----@param uri string ----@param range range ----@param selection range ----@param origin range -function m.locationLink(uri, range, selection, origin) - return { - targetUri = uri, - targetRange = range, - targetSelectionRange = selection, - originSelectionRange = origin, - } -end - -return m diff --git a/server-beta/src/proto/provider.lua b/server-beta/src/proto/provider.lua index 9f3b5697..1f6f6813 100644 --- a/server-beta/src/proto/provider.lua +++ b/server-beta/src/proto/provider.lua @@ -3,7 +3,7 @@ local cap = require 'proto.capability' local task = require 'task' local files = require 'files' local proto = require 'proto.proto' -local interface = require 'proto.interface' +local define = require 'proto.define' local workspace = require 'workspace' local config = require 'config' @@ -154,7 +154,7 @@ proto.on('textDocument/definition', function (params) end local lines = files.getLines(uri) local text = files.getText(uri) - local offset = interface.offset(lines, text, params.position) + local offset = define.offset(lines, text, params.position) local result = core(uri, offset) if not result then return nil @@ -164,10 +164,10 @@ proto.on('textDocument/definition', function (params) local targetUri = info.uri local targetLines = files.getLines(targetUri) local targetText = files.getText(targetUri) - response[i] = interface.locationLink(targetUri - , interface.range(targetLines, targetText, info.target.start - 1, info.target.finish) - , interface.range(targetLines, targetText, info.target.start - 1, info.target.finish) - , interface.range(lines, text, info.source.start - 1, info.source.finish) + response[i] = define.locationLink(targetUri + , define.range(targetLines, targetText, info.target.start - 1, info.target.finish) + , define.range(targetLines, targetText, info.target.start - 1, info.target.finish) + , define.range(lines, text, info.source.start - 1, info.source.finish) ) end return response diff --git a/server-beta/test.lua b/server-beta/test.lua index 32f9dc57..3ebfca70 100644 --- a/server-beta/test.lua +++ b/server-beta/test.lua @@ -37,10 +37,10 @@ local function main() end test 'definition' - --test 'rename' - --test 'highlight' + test 'diagnostics' --test 'references' - --test 'diagnostics' + --test 'highlight' + --test 'rename' --test 'type_inference' --test 'find_lib' --test 'hover' diff --git a/server-beta/test/diagnostics/init.lua b/server-beta/test/diagnostics/init.lua index bd922825..b0438eb2 100644 --- a/server-beta/test/diagnostics/init.lua +++ b/server-beta/test/diagnostics/init.lua @@ -1,8 +1,7 @@ -local core = require 'core' -local buildVM = require 'vm' -local parser = require 'parser' -local service = require 'service' -local config = require 'config' +local core = require 'core.diagnostics' +local files = require 'files' +local config = require 'config' +local util = require 'utility' rawset(_G, 'TEST', true) @@ -48,14 +47,10 @@ local function founded(targets, results) end function TEST(script, ...) + files.removeAll() local new_script, target = catch_target(script, ...) - local lsp = service() - local ast = parser:parse(new_script, 'lua', 'Lua 5.3') - assert(ast) - local lines = parser:lines(new_script) - local vm = buildVM(ast, lsp, 'test') - assert(vm) - local datas = core.diagnostics(vm, lines, 'test') + files.setText('', new_script) + local datas = core('') local results = {} for i, data in ipairs(datas) do results[i] = { data.start, data.finish } @@ -63,7 +58,7 @@ function TEST(script, ...) if results[1] then if not founded(target, results) then - error(('%s\n%s'):format(table.dump(target), table.dump(results))) + error(('%s\n%s'):format(util.dump(target), util.dump(results))) end else assert(#target == 0) @@ -402,108 +397,108 @@ local = {} t[1] = 1 ]] -TEST [[ ----@class ----@class -]] - -TEST [[ ----@class A : -]] - -TEST [[ ----@class ----@class ----@class ----@class -]] - -TEST [[ ----@class A : B ----@class B : C ----@class C : D ----@class D -]] - -TEST [[ ----@type -]] - -TEST [[ ----@class A ----@type A|| -]] - -TEST [[ ----@class AAA ----@alias B AAA - ----@type B -]] - -TEST [[ ----@alias B -]] - -TEST [[ ----@class ----@class B ----@alias -]] - -TEST [[ ----@param x -]] - -TEST [[ ----@class Class ----@param Class -local function f(x) - return x -end -f() -]] - -TEST [[ ----@class Class ----@param Class -function F(x) - return x -end -F() -]] - -TEST [[ ----@class Class ----@param Class ----@param y Class ----@param Class -local function f(x, y) - return x, y -end -f() -]] - -TEST [[ ----@field ----@class Class -]] - -TEST [[ ----@class Class ----@field Class ----@field Class -]] - -TEST [[ ----@class Class : any -]] - -TEST [[ ----@type fun(a: integer) -local f -f() -]] +--TEST [[ +-----@class +-----@class +--]] +-- +--TEST [[ +-----@class A : +--]] +-- +--TEST [[ +-----@class +-----@class +-----@class +-----@class +--]] +-- +--TEST [[ +-----@class A : B +-----@class B : C +-----@class C : D +-----@class D +--]] +-- +--TEST [[ +-----@type +--]] +-- +--TEST [[ +-----@class A +-----@type A|| +--]] +-- +--TEST [[ +-----@class AAA +-----@alias B AAA +-- +-----@type B +--]] +-- +--TEST [[ +-----@alias B +--]] +-- +--TEST [[ +-----@class +-----@class B +-----@alias +--]] +-- +--TEST [[ +-----@param x +--]] +-- +--TEST [[ +-----@class Class +-----@param Class +--local function f(x) +-- return x +--end +--f() +--]] +-- +--TEST [[ +-----@class Class +-----@param Class +--function F(x) +-- return x +--end +--F() +--]] +-- +--TEST [[ +-----@class Class +-----@param Class +-----@param y Class +-----@param Class +--local function f(x, y) +-- return x, y +--end +--f() +--]] +-- +--TEST [[ +-----@field +-----@class Class +--]] +-- +--TEST [[ +-----@class Class +-----@field Class +-----@field Class +--]] +-- +--TEST [[ +-----@class Class : any +--]] +-- +--TEST [[ +-----@type fun(a: integer) +--local f +--f() +--]] TEST [[ local x = 1 @@ -531,13 +526,13 @@ local x x = x or -1 ]] ---TEST [[ ---local t = {} ---function t:() ---end ---function t:() ---end ---]] +TEST [[ +local t = {} +function t:() +end +function t:() +end +]] TEST [[ local t = {} -- cgit v1.2.3