-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement analyzer for
secrets
(#141)
* Adding Secrets Analyzer with Comments * Adding analyzer tests * Adding smoke tests * Fixing smoke tests indenting and prefer bitwise not comment javadoc * Applying suggestions Udating Analyzer root to run the analyzer on alphabetical order Changing implement operator comment to use bitwise operator Updating the analyzer to only return 1 essential comment at a time Generalizing the method that checks the usage of the operator Adding extra comment to check for conditional logic Updating preferBitwiseNot to trigger if the student used bitwise and * Adding extra scenario to match all essential comments * Updting visit analyzer method to only add one essential commit
- Loading branch information
1 parent
14e4f15
commit 136383d
Showing
38 changed files
with
700 additions
and
0 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
19 changes: 19 additions & 0 deletions
19
src/main/java/analyzer/exercises/secrets/AvoidConditionalLogic.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,19 @@ | ||
package analyzer.exercises.secrets; | ||
|
||
import analyzer.Comment; | ||
|
||
/** | ||
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/secrets/avoid_conditional_logic.md">Markdown Template</a> | ||
*/ | ||
class AvoidConditionalLogic extends Comment { | ||
|
||
@Override | ||
public String getKey() { | ||
return "java.secrets.avoid_conditional_logic"; | ||
} | ||
|
||
@Override | ||
public Type getType() { | ||
return Type.ACTIONABLE; | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/analyzer/exercises/secrets/PreferBitwiseNot.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,19 @@ | ||
package analyzer.exercises.secrets; | ||
|
||
import analyzer.Comment; | ||
|
||
/** | ||
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/secrets/prefer_bitwise_not.md">Markdown Template</a> | ||
*/ | ||
class PreferBitwiseNot extends Comment { | ||
|
||
@Override | ||
public String getKey() { | ||
return "java.secrets.prefer_bitwise_not"; | ||
} | ||
|
||
@Override | ||
public Type getType() { | ||
return Type.INFORMATIVE; | ||
} | ||
} |
94 changes: 94 additions & 0 deletions
94
src/main/java/analyzer/exercises/secrets/SecretsAnalyzer.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,94 @@ | ||
package analyzer.exercises.secrets; | ||
|
||
import com.github.javaparser.ast.CompilationUnit; | ||
import com.github.javaparser.ast.body.MethodDeclaration; | ||
import com.github.javaparser.ast.expr.BinaryExpr; | ||
import com.github.javaparser.ast.expr.ConditionalExpr; | ||
import com.github.javaparser.ast.expr.UnaryExpr; | ||
import com.github.javaparser.ast.stmt.IfStmt; | ||
import com.github.javaparser.ast.stmt.Statement; | ||
import com.github.javaparser.ast.visitor.VoidVisitorAdapter; | ||
|
||
import analyzer.Analyzer; | ||
import analyzer.OutputCollector; | ||
import analyzer.Solution; | ||
import analyzer.comments.ExemplarSolution; | ||
|
||
/** | ||
* The {@link SecretsAnalyzer} is the analyzer implementation for the {@code secrets} 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/concept/secrets">The secrets exercise on the Java track</a> | ||
*/ | ||
public class SecretsAnalyzer extends VoidVisitorAdapter<OutputCollector> implements Analyzer { | ||
private static final String EXERCISE_NAME = "Secrets"; | ||
private static final String SHIFT_BACK = "shiftBack"; | ||
private static final String SET_BITS = "setBits"; | ||
private static final String FLIP_BITS = "flipBits"; | ||
private static final String CLEAR_BITS = "clearBits"; | ||
private boolean essentialCommentAdded = false; | ||
|
||
@Override | ||
public void analyze(Solution solution, OutputCollector output) { | ||
for (CompilationUnit compilationUnit : solution.getCompilationUnits()) { | ||
compilationUnit.accept(this, output); | ||
} | ||
|
||
if (output.getComments().isEmpty()) { | ||
output.addComment(new ExemplarSolution(EXERCISE_NAME)); | ||
} | ||
} | ||
|
||
@Override | ||
public void visit(MethodDeclaration node, OutputCollector output) { | ||
|
||
if (!essentialCommentAdded && node.getNameAsString().equals(SHIFT_BACK) && doesNotUseOperator(node, BinaryExpr.Operator.UNSIGNED_RIGHT_SHIFT)) { | ||
output.addComment(new UseBitwiseOperator(">>>", SHIFT_BACK)); | ||
essentialCommentAdded = true; | ||
} | ||
|
||
if (!essentialCommentAdded && node.getNameAsString().equals(SET_BITS) && doesNotUseOperator(node, BinaryExpr.Operator.BINARY_OR)) { | ||
output.addComment(new UseBitwiseOperator("|", SET_BITS)); | ||
essentialCommentAdded = true; | ||
} | ||
|
||
if (!essentialCommentAdded && node.getNameAsString().equals(FLIP_BITS) && doesNotUseOperator(node, BinaryExpr.Operator.XOR)) { | ||
output.addComment(new UseBitwiseOperator("^", FLIP_BITS)); | ||
essentialCommentAdded = true; | ||
} | ||
|
||
if (!essentialCommentAdded && node.getNameAsString().equals(CLEAR_BITS) && doesNotUseOperator(node, BinaryExpr.Operator.BINARY_AND)) { | ||
output.addComment(new UseBitwiseOperator("&", CLEAR_BITS)); | ||
essentialCommentAdded = true; | ||
} | ||
|
||
if (!essentialCommentAdded && node.getNameAsString().equals(CLEAR_BITS) && !doesNotUseOperator(node, BinaryExpr.Operator.BINARY_AND) && doesNotImplementBitwiseNot(node)) { | ||
output.addComment(new PreferBitwiseNot()); | ||
} | ||
|
||
if (!essentialCommentAdded && hasConditional(node)) { | ||
output.addComment(new AvoidConditionalLogic()); | ||
} | ||
|
||
super.visit(node, output); | ||
} | ||
|
||
private static boolean doesNotUseOperator(MethodDeclaration node, BinaryExpr.Operator operator) { | ||
return node.findAll(BinaryExpr.class, x -> x.getOperator() == operator).isEmpty(); | ||
} | ||
|
||
private static boolean doesNotImplementBitwiseNot(MethodDeclaration node) { | ||
return node.findAll(UnaryExpr.class, x -> x.getOperator() == UnaryExpr.Operator.BITWISE_COMPLEMENT).isEmpty(); | ||
} | ||
|
||
private static boolean hasConditional(MethodDeclaration node) { | ||
return node.getBody() | ||
.map(body -> body.getStatements().stream() | ||
.anyMatch(SecretsAnalyzer::isConditionalExpresion)) | ||
.orElse(false); | ||
} | ||
|
||
private static boolean isConditionalExpresion(Statement statement) { | ||
return !statement.findAll(IfStmt.class).isEmpty() || !statement.findAll(ConditionalExpr.class).isEmpty(); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/analyzer/exercises/secrets/UseBitwiseOperator.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,36 @@ | ||
package analyzer.exercises.secrets; | ||
|
||
import analyzer.Comment; | ||
|
||
import java.util.Map; | ||
|
||
/** | ||
* @see <a href="https://github.com/exercism/website-copy/blob/main/analyzer-comments/java/secrets/use_bitwise_operator.md">Markdown Template</a> | ||
*/ | ||
class UseBitwiseOperator extends Comment { | ||
private final String operatorToUse; | ||
private final String calledMethod; | ||
|
||
public UseBitwiseOperator(String operatorToUse, String calledMethod) { | ||
this.operatorToUse = operatorToUse; | ||
this.calledMethod = calledMethod; | ||
} | ||
|
||
@Override | ||
public String getKey() { | ||
return "java.secrets.use_bitwise_operator"; | ||
} | ||
|
||
@Override | ||
public Map<String, String> getParameters() { | ||
return Map.of( | ||
"operatorToUse", this.operatorToUse, | ||
"calledMethod", this.calledMethod | ||
); | ||
} | ||
|
||
@Override | ||
public Type getType() { | ||
return Type.ESSENTIAL; | ||
} | ||
} |
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
11 changes: 11 additions & 0 deletions
11
src/test/resources/analyzer/AnalyzerIntegrationTest.secrets.ExemplarSolution.approved.txt
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,11 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.general.exemplar", | ||
"params": { | ||
"exerciseName": "Secrets" | ||
}, | ||
"type": "celebratory" | ||
} | ||
] | ||
} |
17 changes: 17 additions & 0 deletions
17
...s/analyzer/AnalyzerIntegrationTest.secrets.NotUsingAnyOfTheExpectedOperators.approved.txt
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,17 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.secrets.use_bitwise_operator", | ||
"params": { | ||
"calledMethod": "shiftBack", | ||
"operatorToUse": "\u003e\u003e\u003e" | ||
}, | ||
"type": "essential" | ||
}, | ||
{ | ||
"comment": "java.general.feedback_request", | ||
"params": {}, | ||
"type": "informative" | ||
} | ||
] | ||
} |
17 changes: 17 additions & 0 deletions
17
src/test/resources/analyzer/AnalyzerIntegrationTest.secrets.NotUsingBitwiseAnd.approved.txt
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,17 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.secrets.use_bitwise_operator", | ||
"params": { | ||
"calledMethod": "clearBits", | ||
"operatorToUse": "\u0026" | ||
}, | ||
"type": "essential" | ||
}, | ||
{ | ||
"comment": "java.general.feedback_request", | ||
"params": {}, | ||
"type": "informative" | ||
} | ||
] | ||
} |
14 changes: 14 additions & 0 deletions
14
src/test/resources/analyzer/AnalyzerIntegrationTest.secrets.NotUsingBitwiseNot.approved.txt
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,14 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.secrets.prefer_bitwise_not", | ||
"params": {}, | ||
"type": "informative" | ||
}, | ||
{ | ||
"comment": "java.general.feedback_request", | ||
"params": {}, | ||
"type": "informative" | ||
} | ||
] | ||
} |
17 changes: 17 additions & 0 deletions
17
src/test/resources/analyzer/AnalyzerIntegrationTest.secrets.NotUsingBitwiseOr.approved.txt
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,17 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.secrets.use_bitwise_operator", | ||
"params": { | ||
"calledMethod": "setBits", | ||
"operatorToUse": "|" | ||
}, | ||
"type": "essential" | ||
}, | ||
{ | ||
"comment": "java.general.feedback_request", | ||
"params": {}, | ||
"type": "informative" | ||
} | ||
] | ||
} |
17 changes: 17 additions & 0 deletions
17
src/test/resources/analyzer/AnalyzerIntegrationTest.secrets.NotUsingBitwiseXor.approved.txt
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,17 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.secrets.use_bitwise_operator", | ||
"params": { | ||
"calledMethod": "flipBits", | ||
"operatorToUse": "^" | ||
}, | ||
"type": "essential" | ||
}, | ||
{ | ||
"comment": "java.general.feedback_request", | ||
"params": {}, | ||
"type": "informative" | ||
} | ||
] | ||
} |
17 changes: 17 additions & 0 deletions
17
...esources/analyzer/AnalyzerIntegrationTest.secrets.NotUsingUnsignedRightShift.approved.txt
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,17 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.secrets.use_bitwise_operator", | ||
"params": { | ||
"calledMethod": "shiftBack", | ||
"operatorToUse": "\u003e\u003e\u003e" | ||
}, | ||
"type": "essential" | ||
}, | ||
{ | ||
"comment": "java.general.feedback_request", | ||
"params": {}, | ||
"type": "informative" | ||
} | ||
] | ||
} |
14 changes: 14 additions & 0 deletions
14
src/test/resources/analyzer/AnalyzerIntegrationTest.secrets.UsingIfStatement.approved.txt
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,14 @@ | ||
{ | ||
"comments": [ | ||
{ | ||
"comment": "java.secrets.avoid_conditional_logic", | ||
"params": {}, | ||
"type": "actionable" | ||
}, | ||
{ | ||
"comment": "java.general.feedback_request", | ||
"params": {}, | ||
"type": "informative" | ||
} | ||
] | ||
} |
19 changes: 19 additions & 0 deletions
19
src/test/resources/scenarios/secrets/ExemplarSolution.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,19 @@ | ||
package scenarios.secrets; | ||
|
||
public class Secrets { | ||
public static int shiftBack(int value, int amount) { | ||
return value >>> amount; | ||
} | ||
|
||
public static int setBits(int value, int mask) { | ||
return value | mask; | ||
} | ||
|
||
public static int flipBits(int value, int mask) { | ||
return value ^ mask; | ||
} | ||
|
||
public static int clearBits(int value, int mask) { | ||
return value & ~mask; | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/test/resources/scenarios/secrets/NotUsingAnyOfTheExpectedOperators.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,19 @@ | ||
package scenarios.secrets; | ||
|
||
public class Secrets { | ||
public static int shiftBack(int value, int amount) { | ||
return (value >> amount) & ~(Integer.MIN_VALUE >> (amount - 1)); | ||
} | ||
|
||
public static int setBits(int value, int mask) { | ||
return value + mask - (value & mask); | ||
} | ||
|
||
public static int flipBits(int value, int mask) { | ||
return (value & ~mask) | (~value & mask); | ||
} | ||
|
||
public static int clearBits(int value, int mask) { | ||
return ~(~value | mask); | ||
} | ||
} |
Oops, something went wrong.