diff options
-rw-r--r-- | locale/en-us/script.lua | 4 | ||||
-rw-r--r-- | locale/pt-br/script.lua | 4 | ||||
-rw-r--r-- | locale/zh-cn/script.lua | 4 | ||||
-rw-r--r-- | locale/zh-tw/script.lua | 4 | ||||
-rw-r--r-- | script/core/diagnostics/init.lua | 43 | ||||
-rw-r--r-- | script/core/diagnostics/invisible.lua | 55 | ||||
-rw-r--r-- | script/proto/diagnostic.lua | 1 | ||||
-rw-r--r-- | test/diagnostics/common.lua | 61 |
8 files changed, 152 insertions, 24 deletions
diff --git a/locale/en-us/script.lua b/locale/en-us/script.lua index ca17cdf0..5aa93a4c 100644 --- a/locale/en-us/script.lua +++ b/locale/en-us/script.lua @@ -144,6 +144,10 @@ DIAG_UNKNOWN_OPERATOR = 'Unknown operator `{}`.' DIAG_UNREACHABLE_CODE = 'Unreachable code.' +DIAG_INVISIBLE_PRIVATE = +'Field `{field}` is private, it can only be accessed in class `{class}`.' +DIAG_INVISIBLE_PROTECTED = +'Field `{field}` is protected, it can only be accessed in class `{class}` and its subclasses.' MWS_NOT_SUPPORT = '{} does not support multi workspace for now, I may need to restart to support the new workspace ...' diff --git a/locale/pt-br/script.lua b/locale/pt-br/script.lua index e93ff85f..e58dc201 100644 --- a/locale/pt-br/script.lua +++ b/locale/pt-br/script.lua @@ -144,6 +144,10 @@ DIAG_UNKNOWN_OPERATOR = -- TODO: need translate! 'Unknown operator `{}`.' DIAG_UNREACHABLE_CODE = -- TODO: need translate! 'Unreachable code.' +DIAG_INVISIBLE_PRIVATE = -- TODO: need translate! +'Field `{field}` is private, it can only be accessed in class `{class}`.' +DIAG_INVISIBLE_PROTECTED = -- TODO: need translate! +'Field `{field}` is protected, it can only be accessed in class `{class}` and its subclasses.' MWS_NOT_SUPPORT = '{} não é suportado múltiplos espaços de trabalho por enquanto, posso precisar reiniciar para estabelecer um novo espaço de trabalho ...' diff --git a/locale/zh-cn/script.lua b/locale/zh-cn/script.lua index 04d5e115..a0384e8f 100644 --- a/locale/zh-cn/script.lua +++ b/locale/zh-cn/script.lua @@ -144,6 +144,10 @@ DIAG_UNKNOWN_OPERATOR = '未知的运算符 `{}`。' DIAG_UNREACHABLE_CODE = '不可达的代码。' +DIAG_INVISIBLE_PRIVATE = +'字段 `{field}` 是私有的,只能在 `{class}` 类中才能访问。' +DIAG_INVISIBLE_PROTECTED = +'字段 `{field}` 收到保护,只能在 `{class}` 类极其子类中才能访问。' MWS_NOT_SUPPORT = '{} 目前还不支持多工作目录,我可能需要重启才能支持新的工作目录...' diff --git a/locale/zh-tw/script.lua b/locale/zh-tw/script.lua index 8f03d7ca..b76d2fd1 100644 --- a/locale/zh-tw/script.lua +++ b/locale/zh-tw/script.lua @@ -144,6 +144,10 @@ DIAG_UNKNOWN_OPERATOR = -- TODO: need translate! 'Unknown operator `{}`.' DIAG_UNREACHABLE_CODE = -- TODO: need translate! 'Unreachable code.' +DIAG_INVISIBLE_PRIVATE = -- TODO: need translate! +'Field `{field}` is private, it can only be accessed in class `{class}`.' +DIAG_INVISIBLE_PROTECTED = -- TODO: need translate! +'Field `{field}` is protected, it can only be accessed in class `{class}` and its subclasses.' MWS_NOT_SUPPORT = '{} 目前還不支援多工作目錄,我可能需要重新啟動才能支援新的工作目錄...' diff --git a/script/core/diagnostics/init.lua b/script/core/diagnostics/init.lua index c33de6ce..e3f2c416 100644 --- a/script/core/diagnostics/init.lua +++ b/script/core/diagnostics/init.lua @@ -6,29 +6,6 @@ local vm = require "vm.vm" local util = require 'utility' local diagd = require 'proto.diagnostic' --- 把耗时最长的诊断放到最后面 -local diagSort = { - ['redundant-value'] = 100, - ['not-yieldable'] = 100, - ['deprecated'] = 100, - ['undefined-field'] = 110, - ['redundant-parameter'] = 110, - ['cast-local-type'] = 120, - ['assign-type-mismatch'] = 120, - ['param-type-mismatch'] = 120, - ['missing-return'] = 120, - ['missing-return-value'] = 120, - ['redundant-return-value'] = 120, -} - -local diagList = {} -for k in pairs(define.DiagnosticDefaultSeverity) do - diagList[#diagList+1] = k -end -table.sort(diagList, function (a, b) - return (diagSort[a] or 0) < (diagSort[b] or 0) -end) - local sleepRest = 0.0 ---@async @@ -165,6 +142,21 @@ local function check(uri, name, isScopeDiag, response) end end +local diagList +local diagCosts = {} +local function buildDiagList() + if not diagList then + diagList = {} + for name in pairs(define.DiagnosticDefaultSeverity) do + diagList[#diagList+1] = name + end + end + table.sort(diagList, function (a, b) + return (diagCosts[a] or 0) < (diagCosts[b] or 0) + end) + return diagList +end + ---@async ---@param uri uri ---@param isScopeDiag boolean @@ -176,9 +168,12 @@ return function (uri, isScopeDiag, response, checked) return nil end - for _, name in ipairs(diagList) do + for _, name in ipairs(buildDiagList()) do await.delay() + local clock = os.clock() check(uri, name, isScopeDiag, response) + local cost = os.clock() - clock + diagCosts[name] = (diagCosts[name] or 0) + cost if checked then checked(name) end diff --git a/script/core/diagnostics/invisible.lua b/script/core/diagnostics/invisible.lua new file mode 100644 index 00000000..0bd369a4 --- /dev/null +++ b/script/core/diagnostics/invisible.lua @@ -0,0 +1,55 @@ +local files = require 'files' +local guide = require 'parser.guide' +local lang = require 'language' +local vm = require 'vm.vm' +local await = require 'await' + +local checkTypes = {'getfield', 'setfield', 'getmethod', 'setmethod', 'getindex', 'setindex'} + +---@async +return function (uri, callback) + local state = files.getState(uri) + if not state then + return + end + + ---@async + guide.eachSourceTypes(state.ast, checkTypes, function (src) + local child = src.field or src.method or src.index + if not child then + return + end + local key = guide.getKeyName(src) + if not key then + return + end + await.delay() + local defs = vm.getDefs(src) + for _, def in ipairs(defs) do + if not vm.isVisible(src.node, def) then + if vm.getVisibleType(def) == 'private' then + callback { + start = child.start, + finish = child.finish, + uri = uri, + message = lang.script('DIAG_INVISIBLE_PRIVATE', { + field = key, + class = vm.getParentClass(def):getName(), + }), + } + else + callback { + start = child.start, + finish = child.finish, + uri = uri, + message = lang.script('DIAG_INVISIBLE_PROTECTED', { + field = key, + class = vm.getParentClass(def):getName(), + }), + } + end + break + end + end + end) +end diff --git a/script/proto/diagnostic.lua b/script/proto/diagnostic.lua index f6645e89..be30bcec 100644 --- a/script/proto/diagnostic.lua +++ b/script/proto/diagnostic.lua @@ -184,6 +184,7 @@ m.register { 'close-non-object', 'deprecated', 'discard-returns', + 'invisible', } { group = 'strict', severity = 'Warning', diff --git a/test/diagnostics/common.lua b/test/diagnostics/common.lua index f7cbbb0d..0231cc86 100644 --- a/test/diagnostics/common.lua +++ b/test/diagnostics/common.lua @@ -2081,3 +2081,64 @@ end print(1) ]] + +TEST [[ +---@class A +---@field private x number +---@field protected y number +---@field public z number +local t +print(t.x) +]] + +TEST [[ +---@class A +---@field private x number +---@field protected y number +---@field public z number + +---@type A +local t + +print(t.<!x!>) +]] + +TEST [[ +---@class A +---@field private x number +---@field protected y number +---@field public z number + +---@class B: A +local t + +print(t.y) +]] + +TEST [[ +---@class A +---@field private x number +---@field protected y number +---@field public z number + +---@class B: A + +---@type B +local t + +print(t.<!y!>) +]] + +TEST [[ +---@class A +---@field private x number +---@field protected y number +---@field public z number + +---@class B: A + +---@type B +local t + +print(t.z) +]] |