Skip to content

Commit 95b91ea

Browse files
committed
npath: Upgrade npath tool and tests to SDKv1 roles
1 parent 51bed5c commit 95b91ea

File tree

2 files changed

+181
-219
lines changed

2 files changed

+181
-219
lines changed

npath.go

+68-73
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ func NPathComplexity(n *uast.Node) []*NPathData {
3232
var funcs []*uast.Node
3333
var names []string
3434

35-
if containsRole(n, uast.FunctionDeclarationBody) {
35+
if containsRoles(n, []uast.Role{uast.Function, uast.Body}, nil) {
3636
funcs = append(funcs, n)
3737
names = append(names, "NoName")
3838
} else {
39-
funcDecs := deepChildrenOfRole(n, uast.FunctionDeclaration)
39+
funcDecs := deepChildrenOfRoles(n, []uast.Role{uast.Function, uast.Declaration}, []uast.Role{uast.Argument})
4040
for _, funcDec := range funcDecs {
41-
names = append(names, childrenOfRole(funcDec, uast.FunctionDeclarationName)[0].Token)
42-
funcs = append(funcs, childrenOfRole(funcDec, uast.FunctionDeclarationBody)[0])
41+
names = append(names, childrenOfRoles(funcDec, []uast.Role{uast.Function, uast.Name}, nil)[0].Token)
42+
funcs = append(funcs, childrenOfRoles(funcDec, []uast.Role{uast.Function, uast.Body}, nil)[0])
4343
}
4444
}
4545
for i, function := range funcs {
@@ -51,28 +51,26 @@ func NPathComplexity(n *uast.Node) []*NPathData {
5151
}
5252

5353
func visitorSelector(n *uast.Node) int {
54-
// I need to add a error when the node dont have any rol
55-
// when I got 2 or more roles that are inside the switch this doesn't work
56-
for _, role := range n.Roles {
57-
switch role {
58-
case uast.If:
59-
return visitIf(n)
60-
case uast.While:
61-
return visitWhile(n)
62-
case uast.Switch:
63-
return visitSwitch(n)
64-
case uast.DoWhile:
65-
return visitDoWhile(n)
66-
case uast.For:
67-
return visitFor(n)
68-
case uast.ForEach:
69-
return visitForEach(n)
70-
case uast.Return:
71-
return visitReturn(n)
72-
case uast.Try:
73-
return visitTry(n)
74-
default:
75-
}
54+
if containsRoles(n, []uast.Role{uast.Statement, uast.If}, []uast.Role{uast.Then, uast.Else}) {
55+
return visitIf(n)
56+
}
57+
if containsRoles(n, []uast.Role{uast.Statement, uast.While}, nil) {
58+
return visitWhile(n)
59+
}
60+
if containsRoles(n, []uast.Role{uast.Statement, uast.Switch}, nil) {
61+
return visitSwitch(n)
62+
}
63+
if containsRoles(n, []uast.Role{uast.Statement, uast.DoWhile}, nil) {
64+
return visitDoWhile(n)
65+
}
66+
if containsRoles(n, []uast.Role{uast.Statement, uast.For}, nil) {
67+
return visitFor(n)
68+
}
69+
if containsRoles(n, []uast.Role{uast.Statement, uast.Return}, nil) {
70+
return visitReturn(n)
71+
}
72+
if containsRoles(n, []uast.Role{uast.Statement, uast.Try}, nil) {
73+
return visitTry(n)
7674
}
7775
return visitNotCompNode(n)
7876
}
@@ -96,21 +94,16 @@ func visitNotCompNode(n *uast.Node) int {
9694
func visitIf(n *uast.Node) int {
9795
// (npath of if + npath of else (or 1) + bool_comp of if) * npath of next
9896
npath := 0
99-
ifBody := childrenOfRole(n, uast.IfBody)
100-
ifCondition := childrenOfRole(n, uast.IfCondition)
101-
ifElse := childrenOfRole(n, uast.IfElse)
97+
ifThen := childrenOfRoles(n, []uast.Role{uast.If, uast.Then}, nil)
98+
ifCondition := childrenOfRoles(n, []uast.Role{uast.If, uast.Condition}, nil)
99+
ifElse := childrenOfRoles(n, []uast.Role{uast.If, uast.Else}, nil)
102100

103101
if len(ifElse) == 0 {
104102
npath++
105103
} else {
106-
// This if is a short circuit to avoid the two roles in the switch problem
107-
if containsRole(ifElse[0], uast.If) {
108-
npath += visitIf(ifElse[0])
109-
} else {
110-
npath += complexityMultOf(ifElse[0])
111-
}
104+
npath += complexityMultOf(ifElse[0])
112105
}
113-
npath *= complexityMultOf(ifBody[0])
106+
npath *= complexityMultOf(ifThen[0])
114107
npath += expressionComp(ifCondition[0])
115108

116109
return npath
@@ -119,9 +112,9 @@ func visitIf(n *uast.Node) int {
119112
func visitWhile(n *uast.Node) int {
120113
// (npath of while + bool_comp of while + npath of else (or 1)) * npath of next
121114
npath := 0
122-
whileCondition := childrenOfRole(n, uast.WhileCondition)
123-
whileBody := childrenOfRole(n, uast.WhileBody)
124-
whileElse := childrenOfRole(n, uast.IfElse)
115+
whileCondition := childrenOfRoles(n, []uast.Role{uast.While, uast.Condition}, nil)
116+
whileBody := childrenOfRoles(n, []uast.Role{uast.While, uast.Body}, nil)
117+
whileElse := childrenOfRoles(n, []uast.Role{uast.While, uast.Else}, nil)
125118
// Some languages like python can have an else in a while loop
126119
if len(whileElse) == 0 {
127120
npath++
@@ -137,8 +130,8 @@ func visitWhile(n *uast.Node) int {
137130
func visitDoWhile(n *uast.Node) int {
138131
// (npath of do + bool_comp of do + 1) * npath of next
139132
npath := 1
140-
doWhileCondition := childrenOfRole(n, uast.DoWhileCondition)
141-
doWhileBody := childrenOfRole(n, uast.DoWhileBody)
133+
doWhileCondition := childrenOfRoles(n, []uast.Role{uast.DoWhile, uast.Condition}, nil)
134+
doWhileBody := childrenOfRoles(n, []uast.Role{uast.DoWhile, uast.Body}, nil)
142135

143136
npath *= complexityMultOf(doWhileBody[0])
144137
npath += expressionComp(doWhileCondition[0])
@@ -149,7 +142,7 @@ func visitDoWhile(n *uast.Node) int {
149142
func visitFor(n *uast.Node) int {
150143
// (npath of for + bool_comp of for + 1) * npath of next
151144
npath := 1
152-
forBody := childrenOfRole(n, uast.ForBody)
145+
forBody := childrenOfRoles(n, []uast.Role{uast.For, uast.Body}, nil)
153146

154147
npath *= complexityMultOf(forBody[0])
155148

@@ -165,8 +158,8 @@ func visitReturn(n *uast.Node) int {
165158
}
166159

167160
func visitSwitch(n *uast.Node) int {
168-
caseDefault := childrenOfRole(n, uast.SwitchDefault)
169-
switchCases := childrenOfRole(n, uast.SwitchCase)
161+
caseDefault := childrenOfRoles(n, []uast.Role{uast.Switch, uast.Default}, nil)
162+
switchCases := childrenOfRoles(n, []uast.Role{uast.Statement, uast.Switch, uast.Case}, []uast.Role{uast.Body})
170163
npath := 0
171164

172165
if len(caseDefault) != 0 {
@@ -180,25 +173,16 @@ func visitSwitch(n *uast.Node) int {
180173
return npath
181174
}
182175

183-
func visitForEach(n *uast.Node) int {
184-
forBody := childrenOfRole(n, uast.ForBody)
185-
npath := 1
186-
187-
npath *= complexityMultOf(forBody[0])
188-
npath++
189-
return npath
190-
}
191-
192176
func visitTry(n *uast.Node) int {
193177
/*
194178
In pmd they decided the complexity of a try is the summatory of the complexity
195-
of the tryBody,cathBody and finallyBody.I don't think this is the most acurate way
179+
of the try body, catch body and finally body.I don't think this is the most acurate way
196180
of doing this.
197181
*/
198182

199-
tryBody := childrenOfRole(n, uast.TryBody)
200-
tryCatch := childrenOfRole(n, uast.TryCatch)
201-
tryFinaly := childrenOfRole(n, uast.TryFinally)
183+
tryBody := childrenOfRoles(n, []uast.Role{uast.Try, uast.Body}, nil)
184+
tryCatch := childrenOfRoles(n, []uast.Role{uast.Try, uast.Catch}, nil)
185+
tryFinaly := childrenOfRoles(n, []uast.Role{uast.Try, uast.Finally}, nil)
202186

203187
catchComp := 0
204188
if len(tryCatch) != 0 {
@@ -220,59 +204,70 @@ func visitConditionalExpr(n *uast.Node) {
220204
}
221205

222206
func expressionComp(n *uast.Node) int {
223-
orCount := deepCountChildrenOfRole(n, uast.OpBooleanAnd)
224-
andCount := deepCountChildrenOfRole(n, uast.OpBooleanOr)
207+
orCount := deepCountChildrenOfRoles(n, []uast.Role{uast.Operator, uast.Boolean, uast.And}, nil)
208+
andCount := deepCountChildrenOfRoles(n, []uast.Role{uast.Operator, uast.Boolean, uast.Or}, nil)
225209

226210
return orCount + andCount + 1
227211
}
228212

229-
func containsRole(n *uast.Node, role uast.Role) bool {
213+
func containsRoles(n *uast.Node, andRoles []uast.Role, notRoles []uast.Role) bool {
214+
roleMap := make(map[uast.Role]bool)
230215
for _, r := range n.Roles {
231-
if role == r {
232-
return true
216+
roleMap[r] = true
217+
}
218+
for _, r := range andRoles {
219+
if !roleMap[r] {
220+
return false
221+
}
222+
}
223+
if notRoles != nil {
224+
for _, r := range notRoles {
225+
if roleMap[r] {
226+
return false
227+
}
233228
}
234229
}
235-
return false
230+
return true
236231
}
237232

238-
func childrenOfRole(n *uast.Node, role uast.Role) []*uast.Node {
233+
func childrenOfRoles(n *uast.Node, andRoles []uast.Role, notRoles []uast.Role) []*uast.Node {
239234
var children []*uast.Node
240235
for _, child := range n.Children {
241-
if containsRole(child, role) {
236+
if containsRoles(child, andRoles, notRoles) {
242237
children = append(children, child)
243238
}
244239
}
245240
return children
246241
}
247242

248-
func deepChildrenOfRole(n *uast.Node, role uast.Role) []*uast.Node {
243+
func deepChildrenOfRoles(n *uast.Node, andRoles []uast.Role, notRoles []uast.Role) []*uast.Node {
249244
var childList []*uast.Node
250245
for _, child := range n.Children {
251-
if containsRole(child, role) {
246+
if containsRoles(child, andRoles, notRoles) {
252247
childList = append(childList, child)
253248
}
254-
childList = append(childList, deepChildrenOfRole(child, role)...)
249+
childList = append(childList, deepChildrenOfRoles(child, andRoles, notRoles)...)
255250
}
256251
return childList
257252
}
258253

259-
func countChildrenOfRole(n *uast.Node, role uast.Role) int {
254+
func countChildrenOfRoles(n *uast.Node, andRoles []uast.Role, notRoles []uast.Role) int {
260255
count := 0
261256
for _, child := range n.Children {
262-
if containsRole(child, role) {
257+
if containsRoles(child, andRoles, notRoles) {
263258
count++
264259
}
265260
}
266261
return count
267262
}
268263

269-
func deepCountChildrenOfRole(n *uast.Node, role uast.Role) int {
264+
func deepCountChildrenOfRoles(n *uast.Node, andRoles []uast.Role, notRoles []uast.Role) int {
270265
count := 0
271266
for _, child := range n.Children {
272-
if containsRole(child, role) {
267+
if containsRoles(child, andRoles, notRoles) {
273268
count++
274269
}
275-
count += deepCountChildrenOfRole(child, role)
270+
count += deepCountChildrenOfRoles(child, andRoles, notRoles)
276271
}
277272
return count
278273
}

0 commit comments

Comments
 (0)