Skip to content

Commit

Permalink
Merge pull request #195 from jborgers/Issues-193-194
Browse files Browse the repository at this point in the history
Fixes: NullPointerException and Useless Suppressions
  • Loading branch information
jborgers authored Nov 19, 2024
2 parents 06c764a + c5a7b3b commit 843e038
Showing 1 changed file with 13 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static net.sourceforge.pmd.reporting.RuleViolation.*;

Expand All @@ -36,9 +34,6 @@
* @author jborgers
*/
public class UselessSuppressionsHelper {
static final Pattern NEXT_METHOD_NAME_PATTERN = Pattern.compile("\\R*^\\s*[\\w\\s<>]+\\s+(\\w+)\\(");
static final Pattern NEXT_FIELD_NAME_PATTERN = Pattern.compile("\\R*\\s*[\\w\\s<>,?]+\\s+(\\w+)\\s*[=;]");
static final Pattern COMMENT_PATTERN = Pattern.compile("(//.*|/\\*(?s:.)*?\\*/)"); // Matches single-line and multi-line comments
static final String NO_METHOD = "<nom>";
final Map<String, Set<String>> classMethodToRuleNameOfSuppressedViolationsMap = new HashMap<>();
final Map<String, Set<String>> classMethodToRuleNameOfViolationsMap = new HashMap<>();
Expand All @@ -57,9 +52,10 @@ public class UselessSuppressionsHelper {

void storeRuleNameForMethod(Report.SuppressedViolation suppressed) {
RuleViolation violation = suppressed.getRuleViolation();
var packageName = violation.getAdditionalInfo().get(PACKAGE_NAME);
var className = violation.getAdditionalInfo().get(CLASS_NAME);
var methodName = violation.getAdditionalInfo().get(METHOD_NAME);
Map<String,String> addInfo = violation.getAdditionalInfo();
var packageName = addInfo.get(PACKAGE_NAME);
var className = addInfo.get(CLASS_NAME);
var methodName = addInfo.get(METHOD_NAME);
if (methodName != null && !methodName.isEmpty()) {
// store for method
String methodKey = packageName + "-" + className + "-" + methodName;
Expand All @@ -81,9 +77,10 @@ void storeRuleNameForMethod(Report.SuppressedViolation suppressed) {
}

void storeRuleNameForMethod(RuleViolation violation) {
var packageName = violation.getAdditionalInfo().get(PACKAGE_NAME);
var className = violation.getAdditionalInfo().get(CLASS_NAME);
var methodName = violation.getAdditionalInfo().get(METHOD_NAME);
Map<String,String> addInfo = violation.getAdditionalInfo();
var packageName = addInfo.get(PACKAGE_NAME);
var className = addInfo.get(CLASS_NAME);
var methodName = addInfo.get(METHOD_NAME);

if (methodName != null && !methodName.isEmpty()) {
// store for method
Expand Down Expand Up @@ -188,14 +185,11 @@ ViolatingAnnotationHolder getAnnotationContext(PMDViolation annotationViolation)
if (doc != null) {
int startOffset = doc.getLineStartOffset(annotationViolation.getBeginLine() - 1) + annotationViolation.getBeginColumn();
int endOffset = doc.getLineStartOffset(annotationViolation.getEndLine() - 1) + annotationViolation.getEndColumn() - 1;
String violatingAnnotation = doc.getText(new TextRange(startOffset, endOffset));
String methodName;
if (!annotationViolation.getMethodName().isEmpty()) { // an annotation inside a method
methodName = annotationViolation.getMethodName();
} else {
int startAfter = doc.getLineStartOffset(annotationViolation.getEndLine());
String after = doc.getText(new TextRange(startAfter, doc.getTextLength() - 1));
methodName = findMethodName(after);
String violatingAnnotation = doc.getText(new TextRange(startOffset, endOffset - 1)); // -1 to remove the quote (")
String methodName = annotationViolation.getMethodName();
if (methodName == null || methodName.isEmpty()) { // not an annotation on a method
methodName = NO_METHOD;
// pmd7 fixes the method name of a violation, we don't have to find it in the code anymore
}
annotationContextResult = new ViolatingAnnotationHolder(violatingAnnotation, methodName);
}
Expand All @@ -204,46 +198,6 @@ ViolatingAnnotationHolder getAnnotationContext(PMDViolation annotationViolation)
return annotationContextResult;
}

/**
* Find out name of method following annotation, from the document. Implemented with text matching.
* Limitation: Cannot deal with comments containing code, and not with all cases.
* TODO use proper parsing with PSIDocumentManager
*
* @param code document after the annotation
* @return name of the method, or NO_METHOD when annotation is on class or field
*/
String findMethodName(String code) {
code = removeComments(code);
int classIndex = code.indexOf(" class ");
if (classIndex > 0) { // on class or has a subclass, remove code it
code = code.substring(0, classIndex);
}
String methodName = NO_METHOD; // for class level annotations
Matcher methodMatcher = NEXT_METHOD_NAME_PATTERN.matcher(code);
if (methodMatcher.find()) {
if (methodMatcher.groupCount() > 0) {
methodName = methodMatcher.group(1);
// it may be on a field
String afterAnnoBeforeMethod = "";
int methodPos = code.indexOf(methodName + "(");
if (methodPos >= 0) {
afterAnnoBeforeMethod = code.substring(0, methodPos);
}
Matcher fieldMatcher = NEXT_FIELD_NAME_PATTERN.matcher(afterAnnoBeforeMethod);
if (fieldMatcher.find()) {
methodName = NO_METHOD; // on field, map to class for now
}
}
}
return methodName;
}

private String removeComments(String code) {
Matcher matcher = COMMENT_PATTERN.matcher(code);
// Remove the comments from the code string
return matcher.replaceAll("");
}

static class ViolatingAnnotationHolder {
ViolatingAnnotationHolder(String annotationValue, String method) {
this.annotationValue = annotationValue;
Expand Down

0 comments on commit 843e038

Please sign in to comment.