Skip to content

Commit

Permalink
feat: add UnnecessaryModifier rule (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinWitt authored Oct 24, 2022
1 parent c3fdd5d commit 165bbde
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import xyz.keksdose.spoon.code_solver.analyzer.qodana.rules.SizeReplaceableByIsEmpty;
import xyz.keksdose.spoon.code_solver.analyzer.qodana.rules.UnnecessaryInterfaceModifier;
import xyz.keksdose.spoon.code_solver.analyzer.qodana.rules.UnnecessaryLocalVariable;
import xyz.keksdose.spoon.code_solver.analyzer.qodana.rules.UnnecessaryModifier;
import xyz.keksdose.spoon.code_solver.analyzer.qodana.rules.UnnecessaryReturn;
import xyz.keksdose.spoon.code_solver.analyzer.qodana.rules.UnnecessaryToStringCall;
import xyz.keksdose.spoon.code_solver.analyzer.qodana.rules.UnusedImport;
Expand All @@ -33,7 +34,9 @@ public enum QodanaRules implements AnalyzerRule {
UNNECESSARY_TO_STRING_CALL("UnnecessaryToStringCall", UnnecessaryToStringCall::new),
UNUSED_IMPORT("UnusedImport", UnusedImport::new),
PROTECTED_MEMBER_IN_FINAL_CLASS("ProtectedMemberInFinalClass", ProtectedMemberInFinalClass::new),
UNNECESSARY_MODIFIER("UnnecessaryModifier", UnnecessaryModifier::new),
POINTLESS_BOOLEAN_EXPRESSION("PointlessBooleanExpression", PointlessBooleanExpression::new);

private final String ruleId;
private final Function<AnalyzerResult, AbstractRefactoring> refactoring;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package xyz.keksdose.spoon.code_solver.analyzer.qodana.rules;

import java.nio.file.Path;
import java.util.HashSet;
import java.util.List;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtModifiable;
import spoon.reflect.declaration.CtType;
import xyz.keksdose.spoon.code_solver.analyzer.PositionScanner;
import xyz.keksdose.spoon.code_solver.api.analyzer.AnalyzerResult;
import xyz.keksdose.spoon.code_solver.history.Change;
import xyz.keksdose.spoon.code_solver.history.ChangeListener;
import xyz.keksdose.spoon.code_solver.history.MarkdownString;
import xyz.keksdose.spoon.code_solver.transformations.BadSmell;

public class UnnecessaryModifier extends AbstractRefactoring {

public UnnecessaryModifier(AnalyzerResult result) {
super(result);
}

private static final BadSmell UNNECESSARY_MODIFIER = new BadSmell() {
@Override
public MarkdownString getName() {
return MarkdownString.fromRaw("Unnecessary-Modifier");
}

@Override
public MarkdownString getDescription() {
return MarkdownString.fromRaw(
"Some modifiers are not needed, because they are already the default and implicit. These modifiers can be removed.");
}
};

@Override
public void refactor(ChangeListener listener, CtType<?> type) {
if (type.isAnonymous() || !isSameType(type, Path.of(result.filePath()))) {
return;
}
String modifier = result.messageMarkdown().split("`")[1];
if (modifier == null || modifier.isEmpty()) {
return;
}
for (CtElement match : PositionScanner.findLineOnly(type, result.position())) {
if (match instanceof CtModifiable ctModifierHandler) {
var modifiers = new HashSet<>(ctModifierHandler.getModifiers());
modifiers.removeIf(v -> v.toString().equals(modifier.toLowerCase()));
ctModifierHandler.setModifiers(modifiers);
listener.setChanged(
type.getTopLevelType(),
new Change(
UNNECESSARY_MODIFIER,
MarkdownString.fromMarkdown(
"Unnecessary modifier " + modifier + " removed",
"Unnecessary modifier `" + modifier + "` removed"),
type.getTopLevelType(),
result));
}
}
}

@Override
public List<BadSmell> getHandledBadSmells() {
return List.of(UNNECESSARY_MODIFIER);
}
}

0 comments on commit 165bbde

Please sign in to comment.