diff --git a/autograder-core/pom.xml b/autograder-core/pom.xml
index 94ebca44..a9f5b954 100644
--- a/autograder-core/pom.xml
+++ b/autograder-core/pom.xml
@@ -76,6 +76,13 @@
org.reflections
reflections
+
+
+
+ com.github.javaparser
+ javaparser-core
+ ${javaparser.version}
+
diff --git a/autograder-core/src/main/java/de/firemage/autograder/core/check/comment/CommentedOutCodeCheck.java b/autograder-core/src/main/java/de/firemage/autograder/core/check/comment/CommentedOutCodeCheck.java
index 78ffe69c..fbae8797 100644
--- a/autograder-core/src/main/java/de/firemage/autograder/core/check/comment/CommentedOutCodeCheck.java
+++ b/autograder-core/src/main/java/de/firemage/autograder/core/check/comment/CommentedOutCodeCheck.java
@@ -1,11 +1,12 @@
package de.firemage.autograder.core.check.comment;
+import com.github.javaparser.ParseProblemException;
+import com.github.javaparser.StaticJavaParser;
+import de.firemage.autograder.api.Translatable;
import de.firemage.autograder.core.CodePosition;
import de.firemage.autograder.core.LocalizedMessage;
import de.firemage.autograder.core.ProblemType;
-import de.firemage.autograder.api.Translatable;
import de.firemage.autograder.core.check.ExecutableCheck;
-
import de.firemage.autograder.core.file.SourcePath;
import de.firemage.autograder.core.integrated.IntegratedCheck;
import de.firemage.autograder.core.integrated.StaticAnalysis;
@@ -15,8 +16,11 @@
import spoon.reflect.cu.SourcePosition;
import java.nio.file.Path;
+import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
@@ -44,7 +48,7 @@ public void process(CtComment comment) {
}
String content = comment.getContent().trim();
- if (StringUtils.containsAny(content, ';', '{', '}', '=')) {
+ if (isValidCode(content)) {
var position = comment.getPosition();
files
.computeIfAbsent(position.getFile().toPath(), path -> new TreeSet<>(POSITION_COMPARATOR))
@@ -81,6 +85,59 @@ public void process(CtComment comment) {
});
}
+ private static boolean isValidCode(String content) {
+ return !content.isEmpty() && containsSpecialCharacters(content) && isValidCodeInternal(content);
+ }
+
+ private static boolean containsSpecialCharacters(String content) {
+ return StringUtils.containsAny(content, ';', '{', '}', '=', '(', ')', '-', '<', '>', '?', ':', '+', '.', ',');
+ }
+
+ private static boolean isValidCodeInternal(String content) {
+ return prepareCode(content).stream().anyMatch(formatted -> {
+ try {
+ StaticJavaParser.parseBlock(formatted);
+ return true;
+ } catch (ParseProblemException e) {
+ return false;
+ }
+ });
+ }
+
+ private static List prepareCode(String content) {
+ String stripped = content.strip();
+ return wrapAsBlock(getDifferentVersions(stripped));
+ }
+
+ private static Collection getDifferentVersions(String original) {
+ Set options = new HashSet<>();
+ options.add(original.endsWith(";") ? original : original + ";");
+ options.add(formatBrackets(formatBrackets(formatBrackets(original, '{', '}'), '(', ')'), '[', ']'));
+ return options;
+ }
+
+ private static String formatBrackets(String original, char opening, char closing) {
+ int difference = StringUtils.countMatches(original, closing) - StringUtils.countMatches(original, opening);
+ if (difference == 0) {
+ return original;
+ }
+
+ return difference > 0
+ ? String.valueOf(opening).repeat(difference) + original
+ : original + String.valueOf(closing).repeat(-difference);
+ }
+
+ private static List wrapAsBlock(Collection differentVersions) {
+ return differentVersions.stream()
+ .map(content -> {
+ if (!content.startsWith("{") || !content.endsWith("}")) {
+ return "{" + content + "}";
+ }
+ return content;
+ })
+ .toList();
+ }
+
private final class RunningPosition {
int startLine;
int endLine;
diff --git a/pom.xml b/pom.xml
index 5f563bbc..f5fd09ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,6 +57,7 @@
11.1.1-beta-21
0.70
0.10.2
+ 3.26.1
0.5.13