Skip to content

Commit

Permalink
Another features fix.
Browse files Browse the repository at this point in the history
  • Loading branch information
gchallen committed Oct 21, 2022
1 parent 67310a3 commit fe36121
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 44 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 = "2022.10.3"
version = "2022.10.4"
tasks.withType<Test> {
useJUnitPlatform()
enableAssertions = true
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2022.10.3
version=2022.10.4
74 changes: 34 additions & 40 deletions core/src/main/kotlin/JavaFeatures.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package edu.illinois.cs.cs125.jeed.core

import edu.illinois.cs.cs125.jeed.core.antlr.JavaParser
import edu.illinois.cs.cs125.jeed.core.antlr.JavaParser.CreatorContext
import edu.illinois.cs.cs125.jeed.core.antlr.JavaParserBaseListener
import org.antlr.v4.runtime.tree.ParseTreeWalker

Expand All @@ -17,8 +18,9 @@ class JavaFeatureListener(val source: Source, entry: Map.Entry<String, String>)
private val currentFeatures: FeatureValue
get() = featureStack[0]
var results: MutableMap<String, UnitFeatures> = mutableMapOf()
private var anonymousClassCount = 0

private fun enterClassOrInterface(name: String, start: Location, end: Location) {
private fun enterClassOrInterface(name: String, start: Location, end: Location, anonymous: Boolean = false) {
val locatedClass = if (source is Snippet && name == source.wrappedClassName) {
ClassFeatures("", source.snippetRange)
} else {
Expand All @@ -28,10 +30,15 @@ class JavaFeatureListener(val source: Source, entry: Map.Entry<String, String>)
)
}
if (featureStack.isNotEmpty()) {
assert(!currentFeatures.classes.containsKey(locatedClass.name))
assert(!currentFeatures.classes.containsKey(locatedClass.name)) {
"Duplicate class ${locatedClass.name}"
}
currentFeatures.classes[locatedClass.name] = locatedClass
}
featureStack.add(0, locatedClass)
if (!anonymous) {
anonymousClassCount = 0
}
}

private fun enterMethodOrConstructor(name: String, start: Location, end: Location) {
Expand All @@ -48,7 +55,9 @@ class JavaFeatureListener(val source: Source, entry: Map.Entry<String, String>)
)
}
if (featureStack.isNotEmpty()) {
assert(!currentFeatures.methods.containsKey(locatedMethod.name))
assert(!currentFeatures.methods.containsKey(locatedMethod.name)) {
"Duplicate method ${locatedMethod.name} in ${currentFeatures.name}"
}
currentFeatures.methods[locatedMethod.name] = locatedMethod
}
featureStack.add(0, locatedMethod)
Expand Down Expand Up @@ -467,43 +476,6 @@ class JavaFeatureListener(val source: Source, entry: Map.Entry<String, String>)

@Suppress("LongMethod", "ComplexMethod", "NestedBlockDepth")
override fun enterStatement(ctx: JavaParser.StatementContext) {
/*
if (currentFeatures.features.skeleton.isEmpty()) {
val skeleton = ctx.text
for (i in skeleton.indices) {
if (skeleton[i] == '{') {
currentFeatures.features.skeleton += "{ "
} else if (skeleton[i] == '}') {
currentFeatures.features.skeleton += "} "
}
if (i + 5 < skeleton.length) {
if (skeleton.subSequence(i, i + 5) == "while") {
currentFeatures.features.skeleton += "while "
}
}
if (i + 4 < skeleton.length) {
if (skeleton.subSequence(i, i + 4) == "else") {
currentFeatures.features.skeleton += "else "
}
}
if (i + 3 < skeleton.length) {
if (skeleton.subSequence(i, i + 3) == "for") {
currentFeatures.features.skeleton += "for "
}
}
if (i + 2 < skeleton.length) {
when (skeleton.subSequence(i, i + 2)) {
"if" -> currentFeatures.features.skeleton += "if "
"do" -> currentFeatures.features.skeleton += "do "
}
}
}
while (currentFeatures.features.skeleton.contains("{ } ")) {
currentFeatures.features.skeleton = currentFeatures.features.skeleton.replace("{ } ", "")
}
}
*/
ctx.statementExpression?.also {
@Suppress("ComplexCondition")
if (it.text.startsWith("System.out.println(") ||
Expand Down Expand Up @@ -768,6 +740,28 @@ class JavaFeatureListener(val source: Source, entry: Map.Entry<String, String>)
}
}

override fun enterClassCreatorRest(ctx: JavaParser.ClassCreatorRestContext) {
if (ctx.classBody() != null) {
val creator = ctx.parent as CreatorContext
val name = "${creator.createdName().text}_${anonymousClassCount++}"
enterClassOrInterface(
name,
Location(creator.start.line, creator.start.charPositionInLine),
Location(creator.stop.line, creator.stop.charPositionInLine),
true
)
}
}

override fun exitClassCreatorRest(ctx: JavaParser.ClassCreatorRestContext) {
if (ctx.classBody() != null) {
val creator = ctx.parent as CreatorContext
val name = "${creator.createdName().text}_${anonymousClassCount - 1}"
assert(currentFeatures.name == name)
exitClassOrInterface()
}
}

init {
val parsedSource = source.getParsed(filename)
// println(parsedSource.tree.format(parsedSource.parser))
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2022.10.3
version=2022.10.4
37 changes: 37 additions & 0 deletions core/src/test/kotlin/TestJavaComplexity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -646,4 +646,41 @@ public class Mystery {
).complexity()
}
}
"should not fail on repeated nested anonmyous classes" {
Source.fromJavaSnippet(
"""
public static IWhichHemisphere create(Position p) {
double a = p.getLatitude();
if (a == 0) {
return new IWhichHemisphere() {
public boolean isNorthern() {
return false;
}
public boolean isSouthern() {
return true;
}
};
}
if (a > 0) {
return new IWhichHemisphere() {
public boolean isNorthern() {
return true;
}
public boolean isSouthern() {
return false;
}
};
} else {
return new IWhichHemisphere() {
public boolean isNorthern() {
return false;
}
public boolean isSouthern() {
return true;
}
};
}
}""".trim()
).complexity()
}
})
39 changes: 39 additions & 0 deletions core/src/test/kotlin/TestJavaFeatures.kt
Original file line number Diff line number Diff line change
Expand Up @@ -946,4 +946,43 @@ int[] sorted = array.sorted();
dottedMethodList shouldContainExactly setOf("sort", "sorted", "println")
}
}
"should not fail on repeated nested anonmyous classes" {
Source.fromJavaSnippet(
"""
public static IWhichHemisphere create(Position p) {
double a = p.getLatitude();
if (a == 0) {
return new IWhichHemisphere() {
public boolean isNorthern() {
return false;
}
public boolean isSouthern() {
return true;
}
};
}
if (a > 0) {
return new IWhichHemisphere() {
public boolean isNorthern() {
return true;
}
public boolean isSouthern() {
return false;
}
};
} else {
return new IWhichHemisphere() {
public boolean isNorthern() {
return false;
}
public boolean isSouthern() {
return true;
}
};
}
}""".trim()
).features().check("") {
featureMap[FeatureName.ANONYMOUS_CLASSES] shouldBe 3
}
}
})
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version=2022.10.3
version=2022.10.4

0 comments on commit fe36121

Please sign in to comment.