-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(spoon): Add spoon based analyzer (#806)
- Loading branch information
1 parent
466d962
commit 24affc8
Showing
49 changed files
with
2,578 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
...on/src/main/java/xyz/keksdose/spoon/code_solver/analyzer/spoon/AnalyzerResultVisitor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
package xyz.keksdose.spoon.code_solver.analyzer.spoon; | ||
|
||
import io.github.martinwitt.laughing_train.domain.entity.AnalyzerResult; | ||
import io.github.martinwitt.laughing_train.domain.value.Position; | ||
import io.github.martinwitt.laughing_train.domain.value.RuleId; | ||
import io.github.martinwitt.spoon_analyzer.BadSmell; | ||
import io.github.martinwitt.spoon_analyzer.BadSmellVisitor; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.Index_off_replaceable_by_contains.IndexOfReplaceableByContains; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.access_static_via_instance.AccessStaticViaInstance; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.array_can_be_replaced_with_enum_values.ArrayCanBeReplacedWithEnumValues; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.charset_object_can_be_used.CharsetObjectCanBeUsed; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.innerclass_may_be_static.InnerClassMayBeStatic; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.non_protected_constructor_In_abstract_class.NonProtectedConstructorInAbstractClass; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.private_final_method.PrivateFinalMethod; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.size_replaceable_by_is_empty.SizeReplaceableByIsEmpty; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.unnecessary_implements.UnnecessaryImplements; | ||
import io.github.martinwitt.spoon_analyzer.badsmells.unnecessary_tostring.UnnecessaryTostring; | ||
import java.util.ArrayList; | ||
import java.util.Optional; | ||
import spoon.reflect.code.CtBinaryOperator; | ||
import spoon.reflect.cu.SourcePosition; | ||
import spoon.reflect.declaration.CtType; | ||
|
||
class AnalyzerResultVisitor implements BadSmellVisitor<AnalyzerResult> { | ||
|
||
private static final AnalyzerResultVisitor analyzerResultVisitor = new AnalyzerResultVisitor(); | ||
|
||
public static Optional<AnalyzerResult> toAnalyzerResult(BadSmell badSmell) { | ||
return Optional.ofNullable(badSmell.accept(analyzerResultVisitor)); | ||
} | ||
|
||
private AnalyzerResultVisitor() {} | ||
|
||
@Override | ||
public AnalyzerResult visit(IndexOfReplaceableByContains badSmell) { | ||
return toSpoonAnalyzerResult( | ||
badSmell, | ||
badSmell.getIndexOfCall().getPosition(), | ||
badSmell.getIndexOfCall() | ||
.getParent(CtBinaryOperator.class) | ||
.getOriginalSourceFragment() | ||
.toString()); | ||
} | ||
|
||
private String getAbsolutePath(BadSmell badSmell) { | ||
return badSmell.getAffectedType().getPosition().getFile().getAbsolutePath(); | ||
} | ||
|
||
private Position toPosition(SourcePosition position) { | ||
int sourceStart = position.getSourceStart(); | ||
int sourceEnd = position.getSourceEnd(); | ||
int line = position.getLine(); | ||
int column = position.getColumn(); | ||
int endColumn = position.getEndColumn(); | ||
int endLine = position.getEndLine(); | ||
return new Position(line, endLine, column, endColumn, sourceStart, sourceEnd - sourceStart); | ||
} | ||
|
||
public AnalyzerResult toSpoonAnalyzerResult(BadSmell badSmell, SourcePosition position, String snippet) { | ||
String absolutePath = getAbsolutePath(badSmell); | ||
RuleId ruleId = new RuleId(badSmell.getName()); | ||
return new SpoonAnalyzerResult( | ||
ruleId, | ||
absolutePath, | ||
toPosition(position), | ||
badSmell.getDescription(), | ||
badSmell.getDescription(), | ||
snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(AccessStaticViaInstance badSmell) { | ||
String snippet = | ||
badSmell.getAffectedCtInvocation().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult( | ||
badSmell, badSmell.getAffectedCtInvocation().getPosition(), snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(ArrayCanBeReplacedWithEnumValues badSmell) { | ||
String snippet = | ||
badSmell.getAffectedElement().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getAffectedElement().getPosition(), snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(CharsetObjectCanBeUsed badSmell) { | ||
if (badSmell.getInvocation() != null) { | ||
String snippet = | ||
badSmell.getInvocation().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getInvocation().getPosition(), snippet); | ||
} else { | ||
String snippet = badSmell.getCtorCall().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getCtorCall().getPosition(), snippet); | ||
} | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(InnerClassMayBeStatic badSmell) { | ||
CtType<?> clone = badSmell.getAffectedType().clone(); | ||
clone.setTypeMembers(new ArrayList<>()); | ||
String snippet = clone.toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getAffectedType().getPosition(), snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(NonProtectedConstructorInAbstractClass badSmell) { | ||
String snippet = badSmell.getCtConstructor().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getCtConstructor().getPosition(), snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(PrivateFinalMethod badSmell) { | ||
String snippet = | ||
badSmell.getAffectedMethod().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getAffectedMethod().getPosition(), snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(SizeReplaceableByIsEmpty badSmell) { | ||
String snippet = | ||
badSmell.getSizeInvocation().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getSizeInvocation().getPosition(), snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(UnnecessaryImplements badSmell) { | ||
|
||
CtType<?> clone = badSmell.getAffectedType().clone(); | ||
clone.setTypeMembers(new ArrayList<>()); | ||
String snippet = clone.toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getAffectedType().getPosition(), snippet); | ||
} | ||
|
||
@Override | ||
public AnalyzerResult visit(UnnecessaryTostring badSmell) { | ||
String snippet = | ||
badSmell.getNotNeededTostring().getOriginalSourceFragment().toString(); | ||
return toSpoonAnalyzerResult(badSmell, badSmell.getNotNeededTostring().getPosition(), snippet); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...tion/src/main/java/xyz/keksdose/spoon/code_solver/analyzer/spoon/SpoonAnalyzerResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package xyz.keksdose.spoon.code_solver.analyzer.spoon; | ||
|
||
import io.github.martinwitt.laughing_train.domain.entity.AnalyzerResult; | ||
import io.github.martinwitt.laughing_train.domain.value.Position; | ||
import io.github.martinwitt.laughing_train.domain.value.RuleId; | ||
|
||
public record SpoonAnalyzerResult( | ||
RuleId ruleID, String filePath, Position position, String message, String messageMarkdown, String snippet) | ||
implements AnalyzerResult { | ||
|
||
@Override | ||
public String getAnalyzer() { | ||
return "Spoon"; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...ation/src/main/java/xyz/keksdose/spoon/code_solver/analyzer/spoon/SpoonBasedAnalyzer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package xyz.keksdose.spoon.code_solver.analyzer.spoon; | ||
|
||
import io.github.martinwitt.laughing_train.domain.entity.AnalyzerResult; | ||
import io.github.martinwitt.spoon_analyzer.BadSmell; | ||
import io.github.martinwitt.spoon_analyzer.SpoonAnalyzer; | ||
import java.nio.file.Path; | ||
import java.util.List; | ||
|
||
public class SpoonBasedAnalyzer { | ||
|
||
public List<AnalyzerResult> analyze(Path sourceRoot) { | ||
SpoonAnalyzer analyzer = new SpoonAnalyzer(); | ||
List<BadSmell> analyze = analyzer.analyze(sourceRoot.toAbsolutePath().toString()); | ||
return analyze.stream() | ||
.map(AnalyzerResultVisitor::toAnalyzerResult) | ||
.filter(v -> v.isPresent()) | ||
.map(v -> v.get()) | ||
.toList(); | ||
} | ||
} |
3 changes: 2 additions & 1 deletion
3
.../laughing_train/data/AnalyzerRequest.java → ...g_train/data/request/AnalyzerRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
...bot/src/main/java/io/github/martinwitt/laughing_train/data/result/CodeAnalyzerResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package io.github.martinwitt.laughing_train.data.result; | ||
|
||
import io.github.martinwitt.laughing_train.data.Project; | ||
import io.github.martinwitt.laughing_train.domain.entity.AnalyzerResult; | ||
import java.io.Serializable; | ||
import java.util.List; | ||
|
||
public interface CodeAnalyzerResult extends Serializable { | ||
|
||
record Success(List<AnalyzerResult> results, Project project) implements CodeAnalyzerResult {} | ||
|
||
record Failure(String message) implements CodeAnalyzerResult {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.