@@ -3,6 +3,82 @@ use regex::bytes::Regex;
33
44use crate :: * ;
55
6+ #[ inline( always) ]
7+ fn is_child ( node : & Node , id : u16 ) -> bool {
8+ node. object ( )
9+ . children ( & mut node. object ( ) . walk ( ) )
10+ . any ( |child| child. kind_id ( ) == id)
11+ }
12+
13+ #[ inline( always) ]
14+ fn has_sibling ( node : & Node , id : u16 ) -> bool {
15+ node. object ( ) . parent ( ) . map_or ( false , |parent| {
16+ node. object ( )
17+ . children ( & mut parent. walk ( ) )
18+ . any ( |child| child. kind_id ( ) == id)
19+ } )
20+ }
21+
22+ macro_rules! check_if_func {
23+ ( $node: ident) => {
24+ count_specific_ancestors!(
25+ $node,
26+ VariableDeclarator | AssignmentExpression | LabeledStatement | Pair ,
27+ StatementBlock | ReturnStatement | NewExpression | Arguments
28+ ) > 0
29+ || is_child( $node, Identifier as u16 )
30+ } ;
31+ }
32+
33+ macro_rules! check_if_arrow_func {
34+ ( $node: ident) => {
35+ count_specific_ancestors!(
36+ $node,
37+ VariableDeclarator | AssignmentExpression | LabeledStatement ,
38+ StatementBlock | ReturnStatement | NewExpression | CallExpression
39+ ) > 0
40+ || has_sibling( $node, PropertyIdentifier as u16 )
41+ } ;
42+ }
43+
44+ macro_rules! is_js_func {
45+ ( $node: ident) => {
46+ match $node. object( ) . kind_id( ) . into( ) {
47+ FunctionDeclaration | MethodDefinition => true ,
48+ Function => check_if_func!( $node) ,
49+ ArrowFunction => check_if_arrow_func!( $node) ,
50+ _ => false ,
51+ }
52+ } ;
53+ }
54+
55+ macro_rules! is_js_closure {
56+ ( $node: ident) => {
57+ match $node. object( ) . kind_id( ) . into( ) {
58+ GeneratorFunction | GeneratorFunctionDeclaration => true ,
59+ Function => !check_if_func!( $node) ,
60+ ArrowFunction => !check_if_arrow_func!( $node) ,
61+ _ => false ,
62+ }
63+ } ;
64+ }
65+
66+ macro_rules! is_js_func_and_closure_checker {
67+ ( $grammar: ident) => {
68+ #[ inline( always) ]
69+ fn is_func( node: & Node ) -> bool {
70+ use $grammar:: * ;
71+ is_js_func!( node)
72+ }
73+
74+ #[ inline( always) ]
75+ fn is_closure( node: & Node ) -> bool {
76+ use $grammar:: * ;
77+ is_js_closure!( node)
78+ }
79+ } ;
80+ }
81+
682pub trait Checker {
783 fn is_comment ( node : & Node ) -> bool ;
884
@@ -19,6 +95,7 @@ pub trait Checker {
1995 fn is_string ( node : & Node ) -> bool ;
2096 fn is_call ( node : & Node ) -> bool ;
2197 fn is_func ( node : & Node ) -> bool ;
98+ fn is_closure ( node : & Node ) -> bool ;
2299 fn is_func_space ( node : & Node ) -> bool ;
23100 fn is_non_arg ( node : & Node ) -> bool ;
24101
@@ -32,6 +109,7 @@ impl Checker for PreprocCode {
32109 mk_checker ! ( is_string, StringLiteral , RawStringLiteral ) ;
33110 mk_checker ! ( is_call, ) ;
34111 mk_checker ! ( is_func, ) ;
112+ mk_checker ! ( is_closure, ) ;
35113 mk_checker ! ( is_func_space, ) ;
36114 mk_checker ! ( is_non_arg, ) ;
37115}
@@ -41,6 +119,7 @@ impl Checker for CcommentCode {
41119 mk_checker ! ( is_string, StringLiteral , RawStringLiteral ) ;
42120 mk_checker ! ( is_call, ) ;
43121 mk_checker ! ( is_func, ) ;
122+ mk_checker ! ( is_closure, ) ;
44123 mk_checker ! ( is_func_space, ) ;
45124 mk_checker ! ( is_non_arg, ) ;
46125
@@ -66,8 +145,11 @@ impl Checker for CppCode {
66145 is_func,
67146 FunctionDefinition ,
68147 FunctionDefinition2 ,
69- FunctionDefinition3
148+ FunctionDefinition3 ,
149+ FunctionDefinition4 ,
150+ FunctionDefinitionRepeat1
70151 ) ;
152+ mk_checker ! ( is_closure, LambdaExpression ) ;
71153 mk_checker ! (
72154 is_func_space,
73155 TranslationUnit ,
@@ -106,6 +188,7 @@ impl Checker for PythonCode {
106188 mk_checker ! ( is_string, String , ConcatenatedString ) ;
107189 mk_checker ! ( is_call, Call ) ;
108190 mk_checker ! ( is_func, FunctionDefinition ) ;
191+ mk_checker ! ( is_closure, Lambda ) ;
109192 mk_checker ! ( is_func_space, Module , FunctionDefinition , ClassDefinition ) ;
110193 mk_checker ! ( is_non_arg, LPAREN , COMMA , RPAREN ) ;
111194}
@@ -115,6 +198,7 @@ impl Checker for JavaCode {
115198 mk_checker ! ( is_string, StringLiteral ) ;
116199 mk_checker ! ( is_call, MethodInvocation ) ;
117200 mk_checker ! ( is_func, MethodDeclaration ) ;
201+ mk_checker ! ( is_closure, ) ;
118202 mk_checker ! ( is_func_space, Program , ClassDeclaration ) ;
119203 mk_checker ! ( is_non_arg, ) ;
120204}
@@ -123,15 +207,7 @@ impl Checker for MozjsCode {
123207 mk_checker ! ( is_comment, Comment ) ;
124208 mk_checker ! ( is_string, String , TemplateString ) ;
125209 mk_checker ! ( is_call, CallExpression ) ;
126- mk_checker ! (
127- is_func,
128- Function ,
129- GeneratorFunction ,
130- FunctionDeclaration ,
131- GeneratorFunctionDeclaration ,
132- MethodDefinition ,
133- ArrowFunction
134- ) ;
210+
135211 mk_checker ! (
136212 is_func_space,
137213 Program ,
@@ -145,6 +221,8 @@ impl Checker for MozjsCode {
145221 ArrowFunction
146222 ) ;
147223
224+ is_js_func_and_closure_checker ! ( Mozjs ) ;
225+
148226 #[ inline( always) ]
149227 fn is_else_if ( node : & Node ) -> bool {
150228 if node. object ( ) . kind_id ( ) != <Self as TSLanguage >:: BaseLang :: IfStatement {
@@ -162,15 +240,6 @@ impl Checker for JavascriptCode {
162240 mk_checker ! ( is_comment, Comment ) ;
163241 mk_checker ! ( is_string, String , TemplateString ) ;
164242 mk_checker ! ( is_call, CallExpression ) ;
165- mk_checker ! (
166- is_func,
167- Function ,
168- GeneratorFunction ,
169- FunctionDeclaration ,
170- GeneratorFunctionDeclaration ,
171- MethodDefinition ,
172- ArrowFunction
173- ) ;
174243 mk_checker ! (
175244 is_func_space,
176245 Program ,
@@ -183,6 +252,9 @@ impl Checker for JavascriptCode {
183252 ClassDeclaration ,
184253 ArrowFunction
185254 ) ;
255+
256+ is_js_func_and_closure_checker ! ( Javascript ) ;
257+
186258 mk_else_if ! ( IfStatement ) ;
187259 mk_checker ! ( is_non_arg, LPAREN , COMMA , RPAREN ) ;
188260}
@@ -191,15 +263,6 @@ impl Checker for TypescriptCode {
191263 mk_checker ! ( is_comment, Comment ) ;
192264 mk_checker ! ( is_string, String , TemplateString ) ;
193265 mk_checker ! ( is_call, CallExpression ) ;
194- mk_checker ! (
195- is_func,
196- Function ,
197- GeneratorFunction ,
198- FunctionDeclaration ,
199- GeneratorFunctionDeclaration ,
200- MethodDefinition ,
201- ArrowFunction
202- ) ;
203266 mk_checker ! (
204267 is_func_space,
205268 Program ,
@@ -213,6 +276,8 @@ impl Checker for TypescriptCode {
213276 ArrowFunction
214277 ) ;
215278
279+ is_js_func_and_closure_checker ! ( Typescript ) ;
280+
216281 #[ inline( always) ]
217282 fn is_else_if ( node : & Node ) -> bool {
218283 if node. object ( ) . kind_id ( ) != <Self as TSLanguage >:: BaseLang :: IfStatement {
@@ -230,15 +295,6 @@ impl Checker for TsxCode {
230295 mk_checker ! ( is_comment, Comment ) ;
231296 mk_checker ! ( is_string, String , TemplateString ) ;
232297 mk_checker ! ( is_call, CallExpression ) ;
233- mk_checker ! (
234- is_func,
235- Function ,
236- GeneratorFunction ,
237- FunctionDeclaration ,
238- GeneratorFunctionDeclaration ,
239- MethodDefinition ,
240- ArrowFunction
241- ) ;
242298 mk_checker ! (
243299 is_func_space,
244300 Program ,
@@ -252,6 +308,9 @@ impl Checker for TsxCode {
252308 ClassDeclaration ,
253309 ArrowFunction
254310 ) ;
311+
312+ is_js_func_and_closure_checker ! ( Tsx ) ;
313+
255314 mk_else_if ! ( IfStatement ) ;
256315 mk_checker ! ( is_non_arg, LPAREN , COMMA , RPAREN ) ;
257316}
@@ -282,7 +341,8 @@ impl Checker for RustCode {
282341 }
283342 mk_checker ! ( is_string, StringLiteral , RawStringLiteral ) ;
284343 mk_checker ! ( is_call, CallExpression ) ;
285- mk_checker ! ( is_func, FunctionItem , ClosureExpression ) ;
344+ mk_checker ! ( is_func, FunctionItem ) ;
345+ mk_checker ! ( is_closure, ClosureExpression ) ;
286346 mk_checker ! (
287347 is_func_space,
288348 SourceFile ,
0 commit comments