Skip to content

Commit

Permalink
Add Java analyzer for Annalyns Infiltration
Browse files Browse the repository at this point in the history
  • Loading branch information
Gyoo committed Feb 6, 2024
1 parent aa58443 commit c3b1395
Show file tree
Hide file tree
Showing 12 changed files with 269 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/main/java/analyzer/AnalyzerRoot.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import analyzer.comments.FeedbackRequest;
import analyzer.exercises.GlobalAnalyzer;
import analyzer.exercises.annalynsinfiltration.AnnalynsInfiltrationAnalyzer;
import analyzer.exercises.hamming.HammingAnalyzer;
import analyzer.exercises.lasagna.LasagnaAnalyzer;
import analyzer.exercises.leap.LeapAnalyzer;
Expand Down Expand Up @@ -49,6 +50,7 @@ private static List<Analyzer> createAnalyzers(String slug) {
case "lasagna" -> analyzers.add(new LasagnaAnalyzer());
case "leap" -> analyzers.add(new LeapAnalyzer());
case "two-fer" -> analyzers.add(new TwoferAnalyzer());
case "annalyns-infiltration" -> analyzers.add(new AnnalynsInfiltrationAnalyzer());
}

return List.copyOf(analyzers);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package analyzer.exercises.annalynsinfiltration;

import analyzer.Analysis;
import analyzer.Analyzer;
import analyzer.Solution;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.expr.BinaryExpr;
import com.github.javaparser.ast.expr.BooleanLiteralExpr;
import com.github.javaparser.ast.expr.EnclosedExpr;
import com.github.javaparser.ast.stmt.IfStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;

/**
* The {@link AnnalynsInfiltrationAnalyzer} is the analyzer implementation for the {@code annalyns-infiltration} practice exercise.
* It extends from the {@link VoidVisitorAdapter} and uses the visitor pattern to traverse each compilation unit.
*
* @see <a href="https://github.com/exercism/java/tree/main/exercises/practice/annalyns-infiltration">The Annalyns Infiltration exercise on the Java track</a>
*/
public class AnnalynsInfiltrationAnalyzer extends VoidVisitorAdapter<Analysis> implements Analyzer {
@Override
public void analyze(Solution solution, Analysis analysis) {
for (CompilationUnit compilationUnit : solution.getCompilationUnits()) {
compilationUnit.accept(this, analysis);
}
}

@Override
public void visit(IfStmt node, Analysis analysis) {
analysis.addComment(new AvoidIfStatements());
super.visit(node, analysis);
}

@Override
public void visit(ReturnStmt node, Analysis analysis) {
if (node.getExpression().isPresent() && node.getExpression().get() instanceof BooleanLiteralExpr) {
analysis.addComment(new AvoidBooleanLiteralReturns());
}
super.visit(node, analysis);
}

@Override
public void visit(BinaryExpr node, Analysis analysis) {
if (node.getOperator().equals(BinaryExpr.Operator.OR)) {
for (Node childNode : node.getChildNodes()) {
if (childNode instanceof EnclosedExpr
&& ((EnclosedExpr) childNode).getInner() instanceof BinaryExpr
&& ((BinaryExpr) ((EnclosedExpr) childNode).getInner()).getOperator().equals(BinaryExpr.Operator.AND)) {
analysis.addComment(new AvoidUnnecessaryParenthesis());
}
}
}
if (node.getOperator().equals(BinaryExpr.Operator.EQUALS)
&& (node.getLeft() instanceof BooleanLiteralExpr || node.getRight() instanceof BooleanLiteralExpr)) {
analysis.addComment(new AvoidComparisonWithLiteral());
}
super.visit(node, analysis);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package analyzer.exercises.annalynsinfiltration;

import analyzer.Comment;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/annalyns-infiltration/avoid_boolean_literal_returns.md">Markdown Template</a>
*/
public class AvoidBooleanLiteralReturns extends Comment {
@Override
public String getKey() {
return "java.annalynsinfiltration.avoid_boolean_literal_returns";
}

@Override
public Type getType() {
return Type.ESSENTIAL;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package analyzer.exercises.annalynsinfiltration;

import analyzer.Comment;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/annalyns-infiltration/avoid_comparison_with_literal.md">Markdown Template</a>
*/
public class AvoidComparisonWithLiteral extends Comment {
@Override
public String getKey() {
return "java.annalynsinfiltration.avoid_comparison_with_literal";
}

@Override
public Type getType() {
return Type.ESSENTIAL;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package analyzer.exercises.annalynsinfiltration;

import analyzer.Comment;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/annalyns-infiltration/avoid_if_statements.md">Markdown Template</a>
*/
public class AvoidIfStatements extends Comment {
@Override
public String getKey() {
return "java.annalynsinfiltration.avoid_if_statements";
}

@Override
public Type getType() {
return Type.ESSENTIAL;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package analyzer.exercises.annalynsinfiltration;

import analyzer.Comment;

/**
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/annalyns-infiltration/avoid_unnecessary_parenthesis.md">Markdown Template</a>
*/
public class AvoidUnnecessaryParenthesis extends Comment {
@Override
public String getKey() {
return "java.annalynsinfiltration.avoid_unnecessary_parenthesis";
}

@Override
public Type getType() {
return Type.INFORMATIVE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package analyzer.exercises.annalynsinfiltration;

import analyzer.AnalyzerRoot;
import analyzer.Comment;
import analyzer.SolutionFromResourceFiles;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;

public class AnnalynsInfiltrationTest {

@Test
public void optimalSolution() {
var solution = new SolutionFromResourceFiles("annalyns-infiltration", getResourceFileName("OptimalSolution.java"));
var analysis = AnalyzerRoot.analyze(solution);
assertThat(analysis.getComments()).isEmpty();
}

private static Stream<Arguments> testCases() {
return Stream.of(
Arguments.of("ComparingBooleanWithLiteral.java", new AvoidComparisonWithLiteral()),
Arguments.of("ReturningBooleanLiteral.java", new AvoidBooleanLiteralReturns()),
Arguments.of("UsingIfStatement.java", new AvoidIfStatements()),
Arguments.of("UsingUnnecessaryParenthesis.java", new AvoidUnnecessaryParenthesis())
);
}

@ParameterizedTest(name = "{0}")
@MethodSource("testCases")
public void testCommentsOnSolution(String filename, Comment expectedComment) {
var solution = new SolutionFromResourceFiles("annalyns-infiltration", getResourceFileName(filename));
var analysis = AnalyzerRoot.analyze(solution);
assertThat(analysis.getComments()).contains(expectedComment);
}

private static String getResourceFileName(String testFileName) {
return "/analyzer/exercises/annalynsinfiltration/" + testFileName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class AnnalynsInfiltration {
public static boolean canFastAttack(boolean knightIsAwake) {
return !knightIsAwake;
}

public static boolean canSpy(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake) {
return knightIsAwake || archerIsAwake || prisonerIsAwake;
}

public static boolean canSignalPrisoner(boolean archerIsAwake, boolean prisonerIsAwake) {
return prisonerIsAwake == true && archerIsAwake == false;
}

public static boolean canFreePrisoner(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake, boolean petDogIsPresent) {
return !archerIsAwake && (petDogIsPresent || prisonerIsAwake && !knightIsAwake);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class AnnalynsInfiltration {
public static boolean canFastAttack(boolean knightIsAwake) {
return !knightIsAwake;
}

public static boolean canSpy(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake) {
return knightIsAwake || archerIsAwake || prisonerIsAwake;
}

public static boolean canSignalPrisoner(boolean archerIsAwake, boolean prisonerIsAwake) {
return prisonerIsAwake && !archerIsAwake;
}

public static boolean canFreePrisoner(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake, boolean petDogIsPresent) {
return !archerIsAwake && (petDogIsPresent || prisonerIsAwake && !knightIsAwake);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class AnnalynsInfiltration {
public static boolean canFastAttack(boolean knightIsAwake) {
return !knightIsAwake;
}

public static boolean canSpy(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake) {
if(knightIsAwake) return true;
if(archerIsAwake) return true;
if(prisonerIsAwake) return true;
return false;
}

public static boolean canSignalPrisoner(boolean archerIsAwake, boolean prisonerIsAwake) {
return prisonerIsAwake && !archerIsAwake;
}

public static boolean canFreePrisoner(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake, boolean petDogIsPresent) {
return !archerIsAwake && (petDogIsPresent || prisonerIsAwake && !knightIsAwake);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class AnnalynsInfiltration {
public static boolean canFastAttack(boolean knightIsAwake) {
return !knightIsAwake;
}

public static boolean canSpy(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake) {
return knightIsAwake || archerIsAwake || prisonerIsAwake;
}

public static boolean canSignalPrisoner(boolean archerIsAwake, boolean prisonerIsAwake) {
return prisonerIsAwake && !archerIsAwake;
}

public static boolean canFreePrisoner(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake, boolean petDogIsPresent) {
if(!archerIsAwake){
return petDogIsPresent || prisonerIsAwake && !knightIsAwake;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class AnnalynsInfiltration {
public static boolean canFastAttack(boolean knightIsAwake) {
return !knightIsAwake;
}

public static boolean canSpy(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake) {
return knightIsAwake || archerIsAwake || prisonerIsAwake;
}

public static boolean canSignalPrisoner(boolean archerIsAwake, boolean prisonerIsAwake) {
return prisonerIsAwake && !archerIsAwake;
}

public static boolean canFreePrisoner(boolean knightIsAwake, boolean archerIsAwake, boolean prisonerIsAwake, boolean petDogIsPresent) {
return !archerIsAwake && (petDogIsPresent || (prisonerIsAwake && !knightIsAwake));
}
}

0 comments on commit c3b1395

Please sign in to comment.