Skip to content

Commit

Permalink
Fix bug, improve property errors on Kotlin.
Browse files Browse the repository at this point in the history
  • Loading branch information
gchallen committed Sep 29, 2021
1 parent 3f69970 commit 1341bb0
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 6 deletions.
75 changes: 70 additions & 5 deletions src/main/kotlin/Submission.kt
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,39 @@ class Submission(val solution: Solution, val submission: Class<*>) {
}?.let { executable ->
executable.isAccessible = true
solutionExecutable to executable
} ?: throw SubmissionDesignMissingMethodError(
submission,
solutionExecutable
)
} ?: run {
@Suppress("ComplexCondition")
if (submission.isKotlin() &&
solutionExecutable is Method &&
(
solutionExecutable.name.startsWith("get") ||
solutionExecutable.name.startsWith("set")
)
) {
if (solutionExecutable.name.startsWith("get")) {
val field = solutionExecutable.name.removePrefix("get").let {
it[0].lowercaseChar() + it.substring(1)
}
throw SubmissionDesignKotlinNotAccessibleError(
submission,
field
)
} else {
val field = solutionExecutable.name.removePrefix("set").let {
it[0].lowercaseChar() + it.substring(1)
}
throw SubmissionDesignKotlinNotModifiableError(
submission,
field
)
}
} else {
throw SubmissionDesignMissingMethodError(
submission,
solutionExecutable
)
}
}
}.toMutableMap().also {
if (solution.initializer != null) {
it[solution.initializer] = solution.initializer
Expand All @@ -119,7 +148,8 @@ class Submission(val solution: Solution, val submission: Class<*>) {
return@forEach
}
if (executable is Constructor<*> &&
executable.parameterTypes.last()?.name == "kotlin.jvm.internal.DefaultConstructorMarker"
executable.parameterTypes.lastOrNull()?.name ==
"kotlin.jvm.internal.DefaultConstructorMarker"
) {
return@forEach
}
Expand All @@ -130,6 +160,28 @@ class Submission(val solution: Solution, val submission: Class<*>) {
return@forEach
}
}
@Suppress("ComplexCondition")
if (submission.isKotlin() && executable is Method &&
(executable.name.startsWith("set") || executable.name.startsWith("get"))
) {
if (executable.name.startsWith("set")) {
val field = executable.name.removePrefix("set").let {
it[0].lowercaseChar() + it.substring(1)
}
throw SubmissionDesignKotlinIsModifiableError(
submission,
field
)
} else {
val field = executable.name.removePrefix("get").let {
it[0].lowercaseChar() + it.substring(1)
}
throw SubmissionDesignKotlinIsAccessibleError(
submission,
field
)
}
}
throw SubmissionDesignExtraMethodError(
submission,
executable
Expand Down Expand Up @@ -468,6 +520,19 @@ class SubmissionDesignMissingMethodError(klass: Class<*>, executable: Executable
} ${executable.fullName(klass.isKotlin())}"
)

class SubmissionDesignKotlinNotAccessibleError(klass: Class<*>, field: String) : SubmissionDesignError(
"Property $field on submission class ${klass.name} is not accessible (no getter is available)"
)
class SubmissionDesignKotlinNotModifiableError(klass: Class<*>, field: String) : SubmissionDesignError(
"Property $field on submission class ${klass.name} is not modifiable (no setter is available)"
)
class SubmissionDesignKotlinIsAccessibleError(klass: Class<*>, field: String) : SubmissionDesignError(
"Property $field on submission class ${klass.name} is accessible but should not be (getter is available)"
)
class SubmissionDesignKotlinIsModifiableError(klass: Class<*>, field: String) : SubmissionDesignError(
"Property $field on submission class ${klass.name} is modifiable but should not be (setter is available)"
)

class SubmissionDesignExtraMethodError(klass: Class<*>, executable: Executable) : SubmissionDesignError(
"Submission class ${klass.name} provided extra ${
if (executable.isStatic() && !klass.isKotlin()) {
Expand Down
9 changes: 8 additions & 1 deletion src/test/java/edu/illinois/cs/cs125/jenisol/core/Helpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,14 @@ fun Class<*>.test() = this.testingClasses().apply {
check(isNotEmpty()) { "No incorrect examples.java.examples for $testName" }
}.forEach { incorrect ->
if (incorrect.simpleName.startsWith("Design")) {
shouldThrow<SubmissionDesignError> { submission(incorrect) }
shouldThrow<SubmissionDesignError> {
try {
submission(incorrect)
} catch (e: Exception) {
e.printStackTrace()
throw e
}
}
} else {
check(!primarySolution.isDesignOnly()) {
"Can't test Incorrect* examples when solution is design only"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,15 @@ class TestJavaExamples : StringSpec(
examples.java.noreceiver.setsum.Correct::class.java.also {
"${it.testName()}" { it.test() }
}
examples.java.receiver.kotlindefaultparameter.Correct::class.java.also {
"${it.testName()}" { it.test() }
}
examples.java.receiver.kotlinvalvar.Correct::class.java.also {
"${it.testName()}" { it.test() }
}
examples.java.receiver.kotlinvarval.Correct::class.java.also {
"${it.testName()}" { it.test() }
}
examples.java.receiver.timeouttest.Correct::class.java.also {
"${it.testName()}" {
val runnable = object : Runnable {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package examples.java.receiver.kotlindefaultparameter;

public class Correct {
private String value;

public Correct(String setValue) {
value = setValue;
}

public void setValue(String setValue) {
value = setValue;
}

public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package examples.java.receiver.kotlindefaultparameter;

public class Design0 {
private String value;

public Design0(String setValue) {
value = setValue;
}

public void setValue(String setValue) {
value = setValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package examples.java.receiver.kotlindefaultparameter

class Design1(var value: String = "")
17 changes: 17 additions & 0 deletions src/test/java/examples/java/receiver/kotlinvalvar/Correct.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package examples.java.receiver.kotlinvalvar;

public class Correct {
private String value;

public Correct(String setValue) {
value = setValue;
}

public void setValue(String setValue) {
value = setValue;
}

public String getValue() {
return value;
}
}
3 changes: 3 additions & 0 deletions src/test/java/examples/java/receiver/kotlinvalvar/Design0.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package examples.java.receiver.kotlinvalvar

class Design0(val value: String?)
4 changes: 4 additions & 0 deletions src/test/java/examples/java/receiver/kotlinvalvar/Design1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package examples.java.receiver.kotlinvalvar

@Suppress("UnusedPrivateMember")
class Design1(private val value: String?)
13 changes: 13 additions & 0 deletions src/test/java/examples/java/receiver/kotlinvarval/Correct.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package examples.java.receiver.kotlinvarval;

public class Correct {
private String value;

public Correct(String setValue) {
value = setValue;
}

public String getValue() {
return value;
}
}
3 changes: 3 additions & 0 deletions src/test/java/examples/java/receiver/kotlinvarval/Design0.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package examples.java.receiver.kotlinvarval

class Design0(var value: String?)
5 changes: 5 additions & 0 deletions src/test/java/examples/java/receiver/kotlinvarval/Design1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package examples.java.receiver.kotlinvarval

class Design1(val value: String?) {
var whatever: Int = 0
}

0 comments on commit 1341bb0

Please sign in to comment.