package analyzer; import java.util.Map; import java.util.Objects; /** * The {@link Comment} class models a single comment in the analysis output. * Each comment has a unique key that translates to a Markdown template in the * exercism/website-copy repository. *

* If the Markdown template contains any parameters, classes inheriting from {@link Comment} should override the * {@link Comment#getParameters()} method to return the parameter keys and values specific to that template. *

* Override the {@link Comment#getType()} method to change the {@link Type} associated to the comment. * * @see The analyzer interface in the Exercism documentation * @see Analyzer comments for the Java track in the website-copy */ public abstract class Comment { /** * The type of comment. * Note that the order defined here corresponds to the order in which comments are sorted in the analyzer output. * * @see Documentation on comment types */ public enum Type { ESSENTIAL, ACTIONABLE, INFORMATIVE, CELEBRATORY } /** * The comment key is a {@link String} that uniquely identifies the comment. *

* Comment keys use the format {@code "java.."}. * The {@code } can be either {@code general} for general comments, * or the slug of the exercise for exercise-specific comments. * The {@code } specifies the name of the comment. *

* The combination of {@code } and {@code } must be unique, and defines the location of the * Markdown template in the exercism/website-copy repository. *

* For example, the comment key {@code "java.hello-world.foo_bar"} would translate to the Markdown file at * {@code analyzer-comments/java/hello-world/foo_bar.md}. * * @return The unique comment key. */ public abstract String getKey(); /** * Each parameter in the Markdown template should have a corresponding parameter in the comment. * Parameters in Markdown templates are of the form {@code %s}. *

* For example, if the Markdown template contains a parameter {@code %s}, * the implementation of this method could look like this: *

{@code
     *     public Map getParameters() {
     *         return Map.of("methodName", "theNameOfTheMethod");
     *     }
     * }
* * @return The parameters for the comment. */ public Map getParameters() { return Map.of(); } /** * * * @return The type of the comment. * @see Documentation on comment types */ public Type getType() { return Type.INFORMATIVE; } @Override public boolean equals(Object obj) { return (obj instanceof Comment other) && equals(other); } public boolean equals(Comment other) { if (!getKey().equals(other.getKey()) || getType() != other.getType()) { return false; } var params = this.getParameters().entrySet(); var otherParams = other.getParameters().entrySet(); return params.containsAll(otherParams) && otherParams.containsAll(params); } @Override public int hashCode() { return Objects.hash(getKey(), getType(), getParameters()); } @Override public String toString() { return String.format("Comment{key=%s,params=%s,type=%s}", getKey(), getParameters(), getType()); } }