@@ -18,77 +18,106 @@ local function isToBeClosed(source)
1818 return false
1919end
2020
21- --- @async
22- return function (uri , callback )
23- local ast = files .getState (uri )
24- if not ast then
25- return
21+ --- @param source parser.object
22+ local function isValidFunction (source )
23+ if not source then
24+ return false
25+ end
26+ if source .type == ' main' then
27+ return false
28+ end
29+ local parent = source .parent
30+ if not parent then
31+ return false
32+ end
33+ if parent .type ~= ' local'
34+ and parent .type ~= ' setlocal' then
35+ return false
36+ end
37+ if isToBeClosed (parent ) then
38+ return false
2639 end
40+ return true
41+ end
2742
28- local cache = {}
29- --- @async
30- local function checkFunction (source )
31- if not source then
43+ local function collect (ast , white , roots , links )
44+ guide .eachSourceType (ast , ' function' , function (src )
45+ if not isValidFunction (src ) then
3246 return
3347 end
34- if cache [source ] ~= nil then
35- return cache [source ]
36- end
37- cache [source ] = false
38- local parent = source .parent
39- if not parent then
40- return false
41- end
42- if parent .type ~= ' local'
43- and parent .type ~= ' setlocal' then
44- return false
45- end
46- if isToBeClosed (parent ) then
47- return false
48- end
49- await .delay ()
50- if parent .type == ' setlocal' then
51- parent = parent .node
48+ local loc = src .parent
49+ if loc .type == ' setlocal' then
50+ loc = loc .node
5251 end
53- local refs = parent .ref
54- local hasGet
55- if refs then
56- cache [source ] = true
57- for _ , src in ipairs (refs ) do
58- if guide .isGet (src ) then
59- local func = guide .getParentFunction (src )
60- if not checkFunction (func ) then
61- hasGet = true
62- break
63- end
52+ for _ , ref in ipairs (loc .ref or {}) do
53+ if ref .type == ' getlocal' then
54+ local func = guide .getParentFunction (ref )
55+ if not isValidFunction (func ) or roots [func ] then
56+ roots [src ] = true
57+ return
6458 end
59+ if not links [func ] then
60+ links [func ] = {}
61+ end
62+ links [func ][# links [func ]+ 1 ] = src
6563 end
66- cache [source ] = not hasGet
6764 end
68- if not hasGet then
69- if client .isVSCode () then
70- callback {
71- start = source .start ,
72- finish = source .finish ,
73- tags = { define .DiagnosticTag .Unnecessary },
74- message = lang .script .DIAG_UNUSED_FUNCTION ,
75- }
76- else
77- callback {
78- start = source .keyword [1 ],
79- finish = source .keyword [2 ],
80- tags = { define .DiagnosticTag .Unnecessary },
81- message = lang .script .DIAG_UNUSED_FUNCTION ,
82- }
83- end
84- return true
85- end
86- return false
65+ white [src ] = true
66+ end )
67+
68+ return white , roots , links
69+ end
70+
71+ local function turnBlack (source , black , white , links )
72+ if black [source ] then
73+ return
74+ end
75+ black [source ] = true
76+ white [source ] = nil
77+ for _ , link in ipairs (links [source ] or {}) do
78+ turnBlack (link , black , white , links )
8779 end
80+ end
8881
89- -- 只检查局部函数
90- --- @async
91- guide .eachSourceType (ast .ast , ' function' , function (src )
92- checkFunction (src )
93- end )
82+ --- @async
83+ return function (uri , callback )
84+ local state = files .getState (uri )
85+ if not state then
86+ return
87+ end
88+
89+ if vm .isMetaFile (uri ) then
90+ return
91+ end
92+
93+ local black = {}
94+ local white = {}
95+ local roots = {}
96+ local links = {}
97+
98+ -- collect
99+ collect (state .ast , white , roots , links )
100+
101+ -- turn black
102+ for source in pairs (roots ) do
103+ turnBlack (source , black , white , links )
104+ end
105+
106+ for source in pairs (white ) do
107+ if client .isVSCode () then
108+ callback {
109+ start = source .start ,
110+ finish = source .finish ,
111+ tags = { define .DiagnosticTag .Unnecessary },
112+ message = lang .script .DIAG_UNUSED_FUNCTION ,
113+ }
114+ else
115+ callback {
116+ start = source .keyword [1 ],
117+ finish = source .keyword [2 ],
118+ tags = { define .DiagnosticTag .Unnecessary },
119+ message = lang .script .DIAG_UNUSED_FUNCTION ,
120+ }
121+ end
122+ end
94123end
0 commit comments