Skip to content

Commit

Permalink
More complexity fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
gchallen committed Oct 14, 2021
1 parent 349dca3 commit 292c888
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 19 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ allprojects {
}
subprojects {
group = "com.github.cs125-illinois.jeed"
version = "2021.10.1"
version = "2021.10.2"
tasks.withType<Test> {
useJUnitPlatform()
enableAssertions = true
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2021.10.1
version=2021.10.2
2 changes: 1 addition & 1 deletion core/src/main/kotlin/JavaComplexity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class JavaComplexityListener(val source: Source, entry: Map.Entry<String, String
} else if (firstToken.type == JavaLexer.IF) {
/*
* if statements only ever add one unit of complexity. If no else is present then we either enter
* the condition or not or not, adding one path.
* the condition or not, adding one path.
* If else is present then we either take the condition or the else, adding one path.
*/
currentComplexity.complexity++
Expand Down
57 changes: 44 additions & 13 deletions core/src/main/kotlin/KotlinComplexity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -176,35 +176,47 @@ class KotlinComplexityListener(val source: Source, entry: Map.Entry<String, Stri
}

// ||
private var requireDepth = 0
override fun enterDisjunction(ctx: KotlinParser.DisjunctionContext) {
if (!ctx.text.contains("||")) {
return
val conjunction = ctx.conjunction()[0].text
if (conjunction.startsWith("require(") ||
conjunction.startsWith("check(") ||
conjunction.startsWith("assert(")
) {
if (requireDepth == 0) {
currentComplexity.complexity++
}
requireDepth++
}
if (ctx.text.contains("(") || ctx.text.contains(")")) {
if (ctx.DISJ().isEmpty()) {
return
}
require(complexityStack.isNotEmpty())
currentComplexity.complexity++
currentComplexity.complexity += 1
}

override fun exitDisjunction(ctx: KotlinParser.DisjunctionContext) {
val conjunction = ctx.conjunction()[0].text
if (conjunction.startsWith("require(") ||
conjunction.startsWith("check(") ||
conjunction.startsWith("assert(")
) {
requireDepth--
}
}

// &&
override fun enterConjunction(ctx: KotlinParser.ConjunctionContext) {
if (!ctx.text.contains("&&")) {
return
}
if (ctx.text.contains("(") || ctx.text.contains(")")) {
if (ctx.CONJ().isEmpty()) {
return
}
require(complexityStack.isNotEmpty())
currentComplexity.complexity++
currentComplexity.complexity += 1
}

// ?:
override fun enterElvisExpression(ctx: KotlinParser.ElvisExpressionContext) {
if (!ctx.text.contains("?:")) {
return
}
if (ctx.text.contains("(") || ctx.text.contains(")")) {
if (ctx.ELVIS().isEmpty()) {
return
}
require(complexityStack.isNotEmpty())
Expand All @@ -218,19 +230,31 @@ class KotlinComplexityListener(val source: Source, entry: Map.Entry<String, Stri
// currentComplexity.complexity++
}

private var inIfExpression = false

// if & else if
override fun enterIfExpression(ctx: KotlinParser.IfExpressionContext) {
if (!ctx.text.contains("if")) {
return
}
require(complexityStack.isNotEmpty())
currentComplexity.complexity++
inIfExpression = true
}

override fun exitIfExpression(ctx: KotlinParser.IfExpressionContext) {
inIfExpression = false
}

// when, called for each ->, except the default one
override fun enterWhenCondition(ctx: KotlinParser.WhenConditionContext) {
require(complexityStack.isNotEmpty())
currentComplexity.complexity++
inIfExpression = true
}

override fun exitWhenCondition(ctx: KotlinParser.WhenConditionContext) {
inIfExpression = false
}

// catch block
Expand All @@ -245,6 +269,13 @@ class KotlinComplexityListener(val source: Source, entry: Map.Entry<String, Stri
currentComplexity.complexity++
}

override fun enterJumpExpression(ctx: KotlinParser.JumpExpressionContext) {
if (ctx.THROW() != null && requireDepth == 0) {
require(complexityStack.isNotEmpty())
currentComplexity.complexity++
}
}

// ?.
override fun enterMemberAccessOperator(ctx: KotlinParser.MemberAccessOperatorContext) {
if (ctx.text != "?.") {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2021.10.1
version=2021.10.2
47 changes: 46 additions & 1 deletion core/src/test/kotlin/TestKotlinComplexity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,9 @@ class PingPonger constructor(private var state: String) {
""".trim()
)
).complexity().also {
it.lookup("PingPonger", "Test.kt").complexity shouldBe 5
it.lookup("PingPonger", "Test.kt").complexity shouldBe 8
it.lookup("PingPonger.pong():Boolean", "Test.kt").complexity shouldBe 2
it.lookup("PingPonger.ping():Boolean", "Test.kt").complexity shouldBe 2
}
}

Expand Down Expand Up @@ -650,4 +652,47 @@ val addEight = object : Adder {
).complexity()
}
}
"should measure when and if equivalently" {
Source.fromKotlin(
"""
fun first(first: Int, second: Int): Int {
return if (first > second && second > first) {
1
} else if (second < first && first < second) {
-1
} else {
0
}
}
fun second(first: Int, second: Int): Int {
return when {
first > second && second > first -> 1
second < first && first < second -> -1
else -> 0
}
}
""".trim()
).complexity().also {
it.lookup("first(Int,Int):Int", "Main.kt").complexity shouldBe 5
it.lookup("second(Int,Int):Int", "Main.kt").complexity shouldBe 5
}
}
"should measure if correctly" {
Source.fromKotlin(
"""
fun first(first: Int, second: Int): Int {
var it = first > second || second == first
return if (first > second && second > first || second == first && second == second) {
1
} else if (second < first && first < second) {
-1
} else {
0
}
}
""".trim()
).complexity().also {
it.lookup("first(Int,Int):Int", "Main.kt").complexity shouldBe 8
}
}
})
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2021.10.1
version=2021.10.2

0 comments on commit 292c888

Please sign in to comment.