From 8c167915b330f52cb31de8005d4e0f66ab706fb2 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 11 Aug 2025 14:05:09 -0600 Subject: [PATCH 01/11] rework commented code check to (almost) identical functionality --- .../checkstyle/readability/CommentedCode.java | 75 +++++++++---------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java index 0d9e24b..df5d36d 100644 --- a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java +++ b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java @@ -4,6 +4,9 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Set; /** @@ -17,9 +20,7 @@ public class CommentedCode extends AbstractCheck { private int min = 5; - private int firstGroupCommentedLine; - - private int numSuccessiveLines; + private final List commentNodes = new ArrayList<>(); /** * Sets the minimum number of successive lines of commented code before reporting @@ -50,60 +51,54 @@ public boolean isCommentNodesRequired() { return true; } - @Override - public void beginTree(DetailAST rootAST) { - resetCounters(); - } - @Override public void finishTree(DetailAST rootAST) { - checkLines(); + checkCommentList(); } @Override public void visitToken(DetailAST ast) { - String[] split = ast.getText().split("\n"); - int lineNum = ast.getLineNo(); - for(int i = 0; i < split.length; i++) { - String line = split[i].trim(); + CommentNode commentNode = new CommentNode(ast, Arrays.stream(ast.getText().trim().split("\r?\n")).map(String::trim).toList()); - if(line.isBlank()) { - continue; - } - - if(CODE_LINE_END_CHARS.contains(line.charAt(line.length() - 1))) { - handleCommentedLine(lineNum + i); - } - else { - checkLines(); - resetCounters(); - } + if(!commentNodes.isEmpty() && ast.getLineNo() > commentNodes.getLast().getLastLineNo() + 1) { + checkCommentList(); } + + commentNodes.add(commentNode); } - private void handleCommentedLine(int lineNum) { - if(firstGroupCommentedLine + numSuccessiveLines < lineNum) { - checkLines(); - resetCounters(); + private void checkCommentList() { + List commentLines = new ArrayList<>(); + commentNodes.forEach(node -> commentLines.addAll(node.lines())); + + if (commentLines.size() < min) { + commentNodes.clear(); + return; } - if(numSuccessiveLines == 0) { - firstGroupCommentedLine = lineNum; - numSuccessiveLines = 1; + int numSuccessiveLines = 0; + for(String comment : commentLines) { + if(comment.isBlank() || CODE_LINE_END_CHARS.contains(comment.charAt(comment.length() - 1))) { + numSuccessiveLines++; + } + else { +// int numSuccessiveLines = commentNodes.getLast().getLastLineNo() + 1 - commentNodes.getFirst().ast().getLineNo(); + if(numSuccessiveLines >= min) { + log(commentNodes.getFirst().ast(), String.format("%d lines of commented out code", numSuccessiveLines)); + } + numSuccessiveLines = 0; + } } - else { - numSuccessiveLines++; + if(numSuccessiveLines >= min) { + log(commentNodes.getFirst().ast(), String.format("%d lines of commented out code", numSuccessiveLines)); } - } - private void resetCounters() { - firstGroupCommentedLine = Integer.MIN_VALUE; - numSuccessiveLines = 0; + commentNodes.clear(); } - private void checkLines() { - if(numSuccessiveLines >= min) { - log(firstGroupCommentedLine, String.format("%d lines of commented out code", numSuccessiveLines)); + private record CommentNode(DetailAST ast, List lines) { + int getLastLineNo() { + return ast.getLineNo() + lines.size() - 1; } } } From c36a287c30669256e08fcb7297feaa77202b402d Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 11 Aug 2025 14:08:02 -0600 Subject: [PATCH 02/11] improve test case, add a comment with non-code lines ending in code characters --- ...hould_FindNoErrors_when_OtherComments.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_OtherComments.java b/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_OtherComments.java index 8f6d9da..cec8181 100644 --- a/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_OtherComments.java +++ b/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_OtherComments.java @@ -9,4 +9,23 @@ public void hi() { int j = 4; System.out.println(i + j); } + + /** + * Lol idk seemed like a fun time; + * Javadoc comments can be weird sometimes; + * Documentation is great to have; + * but seems like most devs don't like writing it; + * + * @param a yes (extra details) + * @param b no (but is it actually?) + * @param c sometimes, but semicolons; + * @param d occasionally, + * @param e often ( + * @param f almost always / + * @param g literally never } + * @param h the only one actually used lol { + */ + public void hi(int a, int b, Object c, char d, boolean e, long f, Void g, String h) { + System.out.println(h + " lol!"); + } } \ No newline at end of file From a14137a15a872de622b636729488de364dea68f1 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 11 Aug 2025 18:05:46 -0600 Subject: [PATCH 03/11] rework commented code check --- .../checkstyle/readability/CommentedCode.java | 141 +++++++++++++++--- 1 file changed, 122 insertions(+), 19 deletions(-) diff --git a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java index df5d36d..3d21f8a 100644 --- a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java +++ b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java @@ -4,10 +4,8 @@ import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.regex.Pattern; /** * Reports successive lines of commented out code @@ -16,10 +14,52 @@ */ public class CommentedCode extends AbstractCheck { - private static final Set CODE_LINE_END_CHARS = Set.of(';', ',', '{', '}', '(', ')', '/'); + private static final Map ENTIRE_COMMENT_CODE_PATTERNS = new HashMap<>(); + private static final Map SINGLE_LINE_CODE_PATTERNS = new HashMap<>(); + private static final Map ENTIRE_COMMENT_NONCODE_PATTERNS = new HashMap<>(); + private static final Map SINGLE_LINE_NONCODE_PATTERNS = new HashMap<>(); + + private static final Set JAVA_RESERVED_WORDS = + Set.of("abstract", "continue", "for", "new", "switch", "assert", "default", "package", "synchronized", + "boolean", "do", "if", "private", "this", "break", "double", "implements", "protected", "throw", + "byte", "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", + "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", "class", + "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", "while"); + + static { + ENTIRE_COMMENT_CODE_PATTERNS.put(Pattern.compile("[\\s\\S]*(?:if|for|while)\\s*\\([\\s\\S]+\\)\\s*\\{[\\s\\S]*}[\\s\\S]*"), 0.9); //simple if/for/while + ENTIRE_COMMENT_CODE_PATTERNS.put(Pattern.compile("[\\s\\S]*if\\s*\\([\\s\\S]+\\)\\s*\\{[\\s\\S]*}\\s*else(?:\\sif\\s*\\([\\s\\S]+\\))?\\s*\\{[\\s\\S]*}[\\s\\S]*"), 0.95); //if/else or if/elseif + ENTIRE_COMMENT_CODE_PATTERNS.put(Pattern.compile("^(?:[\\s\\S]*\\n\\s*)?(?:private|public|protected)?\\s+\\w+\\s+\\w+\\s*\\([\\s\\S]*\\)\\s*\\{[\\s\\S]*}[\\s\\S]*$"), 0.9); //method declaration + + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^(?:if|while)\\s*\\([\\s\\S]+\\)\\s*\\{?\\s$"), 0.85); //simple if/while + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^for\\s*\\([\\s\\S]*;[\\s\\S]*;[\\s\\S]*\\)\\s*\\{?\\s$"), 0.9); //start of for loop + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^\\w+\\s+\\w+\\s*=[\\s\\S]*$"), 0.9); //variable declaration + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^\\w+\\s*(?:\\+|-|\\*|/|%|&|\\^|\\||<<|>>|>>>)?=[\\s\\S]*$"), 0.85); //variable assignment + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^(?:\\w+(?:\\(.*\\))?\\.)*\\w+\\(.*\\);$"), 0.85); //method call + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^return\\s+.*;$"), 0.9); // return statements + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^\\w+(?:--|\\+\\+);?$"), 0.9); //increment/decrement + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^.*;$"), 0.8); //end semicolon + SINGLE_LINE_CODE_PATTERNS.put(Pattern.compile("^}$"), 0.6); //only end curly + + + ENTIRE_COMMENT_NONCODE_PATTERNS.put(Pattern.compile("^(?:\\*.*\n)*\\*.*?$"), 0.85); //Javadoc comment + ENTIRE_COMMENT_NONCODE_PATTERNS.put(Pattern.compile("^\\{(?:\\s*\"\\w+\":\\s*(?:\"?\\w+\"?|\"\"|\\[[\\s\\S]*]|\\{[\\s\\S]*}),?\\s*)+}$"), 0.75); //JSON object + + SINGLE_LINE_NONCODE_PATTERNS.put(Pattern.compile("^\\*.*$"), 0.65); //start of javadoc comment line + SINGLE_LINE_NONCODE_PATTERNS.put(Pattern.compile("^\\*\\s+@(?:param|return|throws)\\s+.*$"), 0.8); //start of javadoc comment line + SINGLE_LINE_NONCODE_PATTERNS.put(Pattern.compile("^\"\\w+\":\\s*(?:\"?[\\w: ]+\"?|\"\"),?$"), 0.65); //individual line of json field + SINGLE_LINE_NONCODE_PATTERNS.put(Pattern.compile("^(?i)(?:TODO|FIXME):.*$"), 0.8); + SINGLE_LINE_NONCODE_PATTERNS.put(Pattern.compile("^NOTE:.*$"), 0.7); + } private int min = 5; + private double minConfidence = 0.5; + + private int entireCommentWeight = 15; + private int singleLineWeight = 7; + private int reservedWordWeight = 2; + private final List commentNodes = new ArrayList<>(); /** @@ -31,6 +71,27 @@ public void setMin(int min) { this.min = min; } + /** + * Sets the minimum confidence a selection of comments should be before reporting + * + * @param minConfidence minimum proportion + */ + public void setMinConfidence(double minConfidence) { + this.minConfidence = minConfidence; + } + + public void setEntireCommentWeight(int entireCommentWeight) { + this.entireCommentWeight = entireCommentWeight; + } + + public void setReservedWordWeight(int reservedWordWeight) { + this.reservedWordWeight = reservedWordWeight; + } + + public void setSingleLineWeight(int singleLineWeight) { + this.singleLineWeight = singleLineWeight; + } + @Override public int[] getDefaultTokens() { return getRequiredTokens(); @@ -76,26 +137,68 @@ private void checkCommentList() { return; } - int numSuccessiveLines = 0; - for(String comment : commentLines) { - if(comment.isBlank() || CODE_LINE_END_CHARS.contains(comment.charAt(comment.length() - 1))) { - numSuccessiveLines++; - } - else { -// int numSuccessiveLines = commentNodes.getLast().getLastLineNo() + 1 - commentNodes.getFirst().ast().getLineNo(); - if(numSuccessiveLines >= min) { - log(commentNodes.getFirst().ast(), String.format("%d lines of commented out code", numSuccessiveLines)); - } - numSuccessiveLines = 0; - } + String entireComment = String.join("\n", commentLines); + double entireCommentCodeScore = maxMatcher(entireComment, ENTIRE_COMMENT_CODE_PATTERNS); + double entireCommentNonCodeScore = maxMatcher(entireComment, ENTIRE_COMMENT_NONCODE_PATTERNS); + double entireCommentScore = (entireCommentCodeScore - entireCommentNonCodeScore) * entireCommentWeight; + + double singleLineCodeScore = maxMatcher(commentLines, SINGLE_LINE_CODE_PATTERNS); + double singleLineNonCodeScore = maxMatcher(commentLines, SINGLE_LINE_NONCODE_PATTERNS); + double singleLineScore = (singleLineCodeScore - singleLineNonCodeScore) * singleLineWeight; + + String[] allWords = entireComment.toLowerCase().split("\\s+"); + long reservedWordCount = Arrays.stream(allWords).filter(JAVA_RESERVED_WORDS::contains).count(); + double reservedWordScore = (double) reservedWordCount / allWords.length * reservedWordWeight; + + int totalWeight = reservedWordWeight; + double totalScore = reservedWordScore; + if(entireCommentScore != 0) { + totalWeight += entireCommentWeight; + totalScore += entireCommentScore; } - if(numSuccessiveLines >= min) { - log(commentNodes.getFirst().ast(), String.format("%d lines of commented out code", numSuccessiveLines)); + if(singleLineScore != 0) { + totalWeight += singleLineWeight; + totalScore += singleLineScore; + } + + double totalConfidence = totalScore / totalWeight; + + if (totalConfidence >= minConfidence) { + log(commentNodes.getFirst().ast(), String.format("%d comment lines likely commented code (%d%% confidence)", + commentNodes.getLast().getLastLineNo() + 1 - commentNodes.getFirst().ast().getLineNo(), + Math.round(totalConfidence * 100))); } commentNodes.clear(); } + private double maxMatcher(String match, Map patternScores) { + double max = 0; + for(var entry : patternScores.entrySet()) { + if(entry.getValue() > max && entry.getKey().matcher(match).matches()) { + max = entry.getValue(); + } + } + return max; + } + + private double maxMatcher(List matches, Map patternScores) { + if(matches.isEmpty()) { + return 0; + } + + double totalScore = 0; + int totalNonBlankLines = 0; + + for(String match : matches) { + if(!match.isBlank()) { + totalScore += maxMatcher(match, patternScores); + totalNonBlankLines++; + } + } + return totalNonBlankLines == 0 ? 0 : totalScore / totalNonBlankLines; + } + private record CommentNode(DetailAST ast, List lines) { int getLastLineNo() { return ast.getLineNo() + lines.size() - 1; From e575c193a590a3c17a1b93e6dfca2f3eeabdc3d7 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 11 Aug 2025 18:06:11 -0600 Subject: [PATCH 04/11] bump version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9f8e118..4dbc741 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 edu.byu.cs240 checkstyle - 1.0.8 + 1.0.9 C S 240 Checkstyle Checks 21 From 175882ee764531f2c514d0784756c3f71e83db01 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 11 Aug 2025 18:16:45 -0600 Subject: [PATCH 05/11] adjust commented code increase consequences of reserved words --- .../edu/byu/cs240/checkstyle/readability/CommentedCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java index 3d21f8a..aeafdbb 100644 --- a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java +++ b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java @@ -148,7 +148,7 @@ private void checkCommentList() { String[] allWords = entireComment.toLowerCase().split("\\s+"); long reservedWordCount = Arrays.stream(allWords).filter(JAVA_RESERVED_WORDS::contains).count(); - double reservedWordScore = (double) reservedWordCount / allWords.length * reservedWordWeight; + double reservedWordScore = Math.min(3.0 * reservedWordCount / allWords.length, 1) * reservedWordWeight; int totalWeight = reservedWordWeight; double totalScore = reservedWordScore; From 67c0ea11927d7b4a851081dff1f459470b68d6e4 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 11 Aug 2025 18:22:49 -0600 Subject: [PATCH 06/11] adjust commented code check fix error wording --- .../edu/byu/cs240/checkstyle/readability/CommentedCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java index aeafdbb..3d1e01c 100644 --- a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java +++ b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java @@ -164,7 +164,7 @@ private void checkCommentList() { double totalConfidence = totalScore / totalWeight; if (totalConfidence >= minConfidence) { - log(commentNodes.getFirst().ast(), String.format("%d comment lines likely commented code (%d%% confidence)", + log(commentNodes.getFirst().ast(), String.format("%d comment lines likely containing commented code (%d%% confidence)", commentNodes.getLast().getLastLineNo() + 1 - commentNodes.getFirst().ast().getLineNo(), Math.round(totalConfidence * 100))); } From 8cf903879bd865b45218c4b098d326aee1854f04 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 8 Sep 2025 18:01:58 -0600 Subject: [PATCH 07/11] add test for commented code below threshold --- .../readability/CommentedCodeTest.java | 7 +++++++ ...d_FindNoErrors_when_belowMinThreshold.java | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_belowMinThreshold.java diff --git a/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java b/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java index 3620d18..799c32a 100644 --- a/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java +++ b/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java @@ -60,6 +60,13 @@ public void should_FindNoErrors_when_commentInString() throws CheckstyleExceptio testFiles(0, fileName); } + @Test + @DisplayName("Should find no errors in code that has commented code below the min threshold") + public void should_FindNoErrors_when_belowMinThreshold() throws CheckstyleException { + String fileName = "testInputs/commentedCode/should_FindNoErrors_when_belowMinThreshold.java"; + testFiles(0, fileName); + } + @Test @DisplayName("Should find errors in code that has code comments") diff --git a/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_belowMinThreshold.java b/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_belowMinThreshold.java new file mode 100644 index 0000000..d4e62ce --- /dev/null +++ b/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindNoErrors_when_belowMinThreshold.java @@ -0,0 +1,20 @@ +import java.util.Scanner; + +class should_FindNoErrors_when_belowMinThreshold { + public void hi() { + +// System.out.println("Hello World!"); + + + System.out.println("Hello World!"); + + +// +// +// System.out.println("Shouldn't count blank lines towards total"); +// System.out.println("Hello World!"); +// +// + + } +} From 8a3bbb12553661562ce62611d97eb4be88850a94 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 8 Sep 2025 18:02:29 -0600 Subject: [PATCH 08/11] adjust positive test include commented whitespace between commented lines --- .../readability/CommentedCodeTest.java | 2 +- .../should_FindErrors_when_CodeComments.java | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java b/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java index 799c32a..883746f 100644 --- a/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java +++ b/src/test/java/edu/byu/cs240/checkstyle/readability/CommentedCodeTest.java @@ -72,7 +72,7 @@ public void should_FindNoErrors_when_belowMinThreshold() throws CheckstyleExcept @DisplayName("Should find errors in code that has code comments") public void should_FindErrors_when_CodeComments() throws CheckstyleException { String fileName = "testInputs/commentedCode/should_FindErrors_when_CodeComments.java"; - testFiles(2, fileName); + testFiles(3, fileName); } diff --git a/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindErrors_when_CodeComments.java b/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindErrors_when_CodeComments.java index 4beab6e..776b323 100644 --- a/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindErrors_when_CodeComments.java +++ b/src/test/resources/edu/byu/cs240/checkstyle/readability/testInputs/commentedCode/should_FindErrors_when_CodeComments.java @@ -15,5 +15,33 @@ public void hi() { // int i = 2477; // int j = 1734; // System.out.println(i + j); + System.out.println("Hello World!"); + int i = 1234; + int j = 4321; + System.out.println(i + j); + + +// +// +// System.out.println("Hello World!"); +// +// +// +// int i = 7; +// +// +// +// +// int j = 4; +// +// +// +// +// System.out.println(i + j); +// +// + + + } } \ No newline at end of file From 2d6a615fb46375e47200ae3a028ebdd6f98ae0c6 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 8 Sep 2025 18:10:42 -0600 Subject: [PATCH 09/11] fix CommentedCode check - blank lines don't count --- .../edu/byu/cs240/checkstyle/readability/CommentedCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java index 3d1e01c..359b98e 100644 --- a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java +++ b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java @@ -132,7 +132,7 @@ private void checkCommentList() { List commentLines = new ArrayList<>(); commentNodes.forEach(node -> commentLines.addAll(node.lines())); - if (commentLines.size() < min) { + if (commentLines.stream().filter(line -> !line.isBlank()).count() < min) { commentNodes.clear(); return; } From d2e4a6f4f83327931308bb32dfae5750d5472291 Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 8 Sep 2025 18:10:53 -0600 Subject: [PATCH 10/11] fix CommentedCode check - fix counting error --- .../edu/byu/cs240/checkstyle/readability/CommentedCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java index 359b98e..e8ffbf3 100644 --- a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java +++ b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java @@ -146,7 +146,7 @@ private void checkCommentList() { double singleLineNonCodeScore = maxMatcher(commentLines, SINGLE_LINE_NONCODE_PATTERNS); double singleLineScore = (singleLineCodeScore - singleLineNonCodeScore) * singleLineWeight; - String[] allWords = entireComment.toLowerCase().split("\\s+"); + String[] allWords = entireComment.trim().toLowerCase().split("\\s+"); long reservedWordCount = Arrays.stream(allWords).filter(JAVA_RESERVED_WORDS::contains).count(); double reservedWordScore = Math.min(3.0 * reservedWordCount / allWords.length, 1) * reservedWordWeight; From f5b05495d1bd67b4db69db591f2097b4e3827cce Mon Sep 17 00:00:00 2001 From: Michael Davenport Date: Mon, 8 Sep 2025 18:22:35 -0600 Subject: [PATCH 11/11] improve CommentedCode check - add minimum number of words before checking reserved words --- .../checkstyle/readability/CommentedCode.java | 44 +++++++++++++------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java index e8ffbf3..d5ab9f7 100644 --- a/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java +++ b/src/main/java/edu/byu/cs240/checkstyle/readability/CommentedCode.java @@ -60,6 +60,8 @@ public class CommentedCode extends AbstractCheck { private int singleLineWeight = 7; private int reservedWordWeight = 2; + private int minWords = 10; + private final List commentNodes = new ArrayList<>(); /** @@ -92,6 +94,10 @@ public void setSingleLineWeight(int singleLineWeight) { this.singleLineWeight = singleLineWeight; } + public void setMinWords(int minWords) { + this.minWords = minWords; + } + @Override public int[] getDefaultTokens() { return getRequiredTokens(); @@ -146,12 +152,30 @@ private void checkCommentList() { double singleLineNonCodeScore = maxMatcher(commentLines, SINGLE_LINE_NONCODE_PATTERNS); double singleLineScore = (singleLineCodeScore - singleLineNonCodeScore) * singleLineWeight; - String[] allWords = entireComment.trim().toLowerCase().split("\\s+"); - long reservedWordCount = Arrays.stream(allWords).filter(JAVA_RESERVED_WORDS::contains).count(); - double reservedWordScore = Math.min(3.0 * reservedWordCount / allWords.length, 1) * reservedWordWeight; + String[] allWords = entireComment.trim().split("\\W+"); + double reservedWordScore = 0; + if(Arrays.stream(allWords).filter(word -> !word.isBlank()).count() > minWords) { + long reservedWordCount = Arrays.stream(allWords).filter(JAVA_RESERVED_WORDS::contains).count(); + reservedWordScore = Math.min(3.0 * reservedWordCount / allWords.length, 1) * reservedWordWeight; + } + + double totalConfidence = getTotalConfidence(reservedWordScore, entireCommentScore, singleLineScore); + if (totalConfidence >= minConfidence) { + log(commentNodes.getFirst().ast(), String.format("%d comment lines likely containing commented code (%d%% confidence)", + commentNodes.getLast().getLastLineNo() + 1 - commentNodes.getFirst().ast().getLineNo(), + Math.round(totalConfidence * 100))); + } - int totalWeight = reservedWordWeight; - double totalScore = reservedWordScore; + commentNodes.clear(); + } + + private double getTotalConfidence(double reservedWordScore, double entireCommentScore, double singleLineScore) { + int totalWeight = 0; + double totalScore = 0; + if(reservedWordScore != 0) { + totalWeight += reservedWordWeight; + totalScore += reservedWordScore; + } if(entireCommentScore != 0) { totalWeight += entireCommentWeight; totalScore += entireCommentScore; @@ -161,15 +185,7 @@ private void checkCommentList() { totalScore += singleLineScore; } - double totalConfidence = totalScore / totalWeight; - - if (totalConfidence >= minConfidence) { - log(commentNodes.getFirst().ast(), String.format("%d comment lines likely containing commented code (%d%% confidence)", - commentNodes.getLast().getLastLineNo() + 1 - commentNodes.getFirst().ast().getLineNo(), - Math.round(totalConfidence * 100))); - } - - commentNodes.clear(); + return totalWeight == 0 ? 0 : totalScore / totalWeight; } private double maxMatcher(String match, Map patternScores) {