Search code examples
javanetbeansnetbeans-platform

How do I write a hint for Netbeans?


I have looked everywhere, and the only example I could find was one for marking JOptionPane.show and removing it. That doesn't help me much.


Solution

  • Note: This goes over making a hint that will match a method, but when you are done, you should be able to match more (like learning RegEx)

    This was rather difficult to do and figure out... I am going to assume you have gone over the tutorial at https://platform.netbeans.org/tutorials/nbm-java-hint.html. After creating the hint via the instructions there, you now have a basic Hint implementation:

    @Hint(displayName = "#DN_MainCallHint", description = "#DESC_MainCallHint",
            category = "general")
            @Messages({
        "DN_MainCallHint=MainCall",
        "DESC_MainCallHint=Warns the user when they are manually calling public "
                + "static void main"
    })
    public class MainCallHint {
        @TriggerPattern(value = "$str.equals(\"\")", //Specify a pattern as needed
                constraints = @ConstraintVariableType(variable = "$str", type
                        = "java.lang.String"))
        @Messages("ERR_MainCallHint=Directly calling main! Did you mean to do that?")
        public static ErrorDescription computeWarning(HintContext ctx) {
            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.
                    ERR_MainCallHint());
        }
    }
    

    The main trouble I had was with @TriggerPattern.value. If you wanted to match a method call, you would set it to something like this:

    "$caller.method($arg1, $arg2)"
    

    and can set type constraints for each of those variables. One important thing to note: if you are trying to match a static method of a particular type, use the FQN of that class or it won't work with arguments. So use something like this:

    "test.HintTest.main($args)"
    

    Resulting in the @TriggerPattern bit to look like this:

    @TriggerPattern(value = "test.HintTest.main($args)", //Specify a pattern as needed
                constraints = @ConstraintVariableType(variable = "$args", type
                        = "java.lang.String[]"))
    

    And you get this:

    Display of hint

    Now, the tutorial shows a very cumbersome way to implement a fix. If all you need to do is a simple replace, then it can be done like this:

    public static ErrorDescription computeWarning(HintContext ctx) {
        Fix fix = JavaFixUtilities.rewriteFix(ctx, "Use notMain instead",
                ctx.getPath(), "test.HintTest.notMain($args)");
        return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.
                ERR_MainCallHint(), fix);
    }
    

    Note: The variables used for rewriteFix must be the same you used in @TriggerPattern or they will be interpreted as literals.