Skip to content

Commit 26c20bb

Browse files
authored
Refactor nom metric (#675)
Move the macros and functions to check if a determined node is a function or a closure in the checker module, so they can be used by other metrics too
1 parent c0e940d commit 26c20bb

File tree

2 files changed

+110
-210
lines changed

2 files changed

+110
-210
lines changed

src/checker.rs

Lines changed: 98 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,82 @@ use regex::bytes::Regex;
33

44
use 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+
682
pub 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

Comments
 (0)