@@ -37,14 +37,29 @@ return function (uri, callback)
3737 return
3838 end
3939
40+ local isExact
4041 local class = vm .getDefinedClass (uri , node )
4142 if class then
42- return
43+ for _ , doc in ipairs (class :getSets (uri )) do
44+ if vm .docHasAttr (doc , ' exact' ) then
45+ isExact = true
46+ break
47+ end
48+ end
49+ if not isExact then
50+ return
51+ end
52+ if src .type == ' setmethod'
53+ and not guide .getSelfNode (node ) then
54+ return
55+ end
4356 end
4457
4558 for _ , def in ipairs (vm .getDefs (src )) do
4659 local dnode = def .node
47- if dnode and vm .getDefinedClass (uri , dnode ) then
60+ if dnode
61+ and not isExact
62+ and vm .getDefinedClass (uri , dnode ) then
4863 return
4964 end
5065 if def .type == ' doc.type.field' then
@@ -55,16 +70,19 @@ return function (uri, callback)
5570 end
5671 end
5772
58- local howToFix = lang .script (' DIAG_INJECT_FIELD_FIX_CLASS' , {
59- node = hname (node ),
60- fix = ' ---@class' ,
61- })
62- for _ , ndef in ipairs (vm .getDefs (node )) do
63- if ndef .type == ' doc.type.table' then
64- howToFix = lang .script (' DIAG_INJECT_FIELD_FIX_TABLE' , {
65- fix = ' [any]: any' ,
66- })
67- break
73+ local howToFix = ' '
74+ if not isExact then
75+ howToFix = lang .script (' DIAG_INJECT_FIELD_FIX_CLASS' , {
76+ node = hname (node ),
77+ fix = ' ---@class' ,
78+ })
79+ for _ , ndef in ipairs (vm .getDefs (node )) do
80+ if ndef .type == ' doc.type.table' then
81+ howToFix = lang .script (' DIAG_INJECT_FIELD_FIX_TABLE' , {
82+ fix = ' [any]: any' ,
83+ })
84+ break
85+ end
6886 end
6987 end
7088
@@ -79,7 +97,7 @@ return function (uri, callback)
7997 finish = src .field .finish ,
8098 message = message ,
8199 }
82- elseif src .type == ' setfield ' and src .method then
100+ elseif src .type == ' setmethod ' and src .method then
83101 callback {
84102 start = src .method .start ,
85103 finish = src .method .finish ,
@@ -89,4 +107,41 @@ return function (uri, callback)
89107 end
90108 guide .eachSourceType (ast .ast , ' setfield' , checkInjectField )
91109 guide .eachSourceType (ast .ast , ' setmethod' , checkInjectField )
110+
111+ --- @async
112+ local function checkExtraTableField (src )
113+ await .delay ()
114+
115+ if not src .bindSource then
116+ return
117+ end
118+ if not vm .docHasAttr (src , ' exact' ) then
119+ return
120+ end
121+ local value = src .bindSource .value
122+ if not value or value .type ~= ' table' then
123+ return
124+ end
125+ for _ , field in ipairs (value ) do
126+ local defs = vm .getDefs (field )
127+ for _ , def in ipairs (defs ) do
128+ if def .type == ' doc.field' then
129+ goto nextField
130+ end
131+ end
132+ local message = lang .script (' DIAG_INJECT_FIELD' , {
133+ class = vm .getInfer (src ):view (uri ),
134+ field = guide .getKeyName (src ),
135+ fix = ' ' ,
136+ })
137+ callback {
138+ start = field .start ,
139+ finish = field .finish ,
140+ message = message ,
141+ }
142+ :: nextField::
143+ end
144+ end
145+
146+ guide .eachSourceType (ast .ast , ' doc.class' , checkExtraTableField )
92147end
0 commit comments