This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 244487 - JavaFixUtilities.rewriteFix matches the wrong variable
Summary: JavaFixUtilities.rewriteFix matches the wrong variable
Status: NEW
Alias: None
Product: java
Classification: Unclassified
Component: Hints (show other bugs)
Version: 8.0
Hardware: PC Windows 7
: P3 normal (vote)
Assignee: Svata Dedic
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-05-14 12:41 UTC by markiewb
Modified: 2016-07-05 23:09 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description markiewb 2014-05-14 12:41:38 UTC
See this simple testcase, which introduces a "join assignment" hint (https://netbeans.org/bugzilla/show_bug.cgi?id=155043)

Example

int bar;
bar = 42;
int foo;
f|oo = 42; //| marks the caret, invoke the hint here

ACTUAL:
int bar = 42;
int foo;
foo = 42;
-> the wrong variable (bar instead of foo) is matched

EXPECTED:
int bar;
bar = 42;
int foo = 42;

The hint is a very easy TriggerPattern-type one. See the code below. Is the pattern wrong or the implementation of JavaFixUtilities?


package de.markiewb.netbeans.plugins.hints.join;

import org.junit.Test;
import org.netbeans.modules.java.hints.test.api.HintTest;
import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.editor.hints.Fix;
import org.netbeans.spi.editor.hints.Severity;
import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
import org.netbeans.spi.java.hints.Hint;
import org.netbeans.spi.java.hints.HintContext;
import org.netbeans.spi.java.hints.TriggerPattern;
import org.openide.util.NbBundle;

/**
 *
 * @author markiewb
 */
@NbBundle.Messages({
    "DN_JoinAssignment=Join assignment",
    "DESC_JoinAssignment=Join assignment. <br>For example: <tt>int foo; foo=42;</tt> will be transformed to <tt>int foo = 42;</tt><p>Provided by <a href=\"https://github.com/markiewb/nb-additional-hints\">nb-additional-hints</a> plugin</p>",})
@Hint(displayName = "#DN_JoinAssignment", description = "#DESC_JoinAssignment", category = "suggestions", hintKind = Hint.Kind.ACTION, severity = Severity.HINT)
public class JoinAssignmentFixTest {

    @TriggerPattern(value = "$type $name;$name=$value;")
    @NbBundle.Messages("ERR_JoinAssignment=Join assignment")
    public static ErrorDescription computeAssertTrueWithoutMessage(HintContext ctx) {
        Fix fix = org.netbeans.spi.java.hints.JavaFixUtilities.rewriteFix(ctx, Bundle.ERR_JoinAssignment(), ctx.getPath(), "$type $name = $value;");
        return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.ERR_JoinAssignment(), fix);
    }

    @Test
    public void testSimpleJoin_severalCandiates() throws Exception {
        HintTest.create().
                setCaretMarker('|').
                input("package test;\n"
                        + "public class Test {\n"
                        + "    public static void main(String[] args) {\n"
                        + "        int bar;\n"
                        + "        bar = 42;\n"
                        + "        int f|oo;\n"
                        + "        foo = 42;\n"
                        + "    }\n"
                        + "}\n", true).
                run(JoinAssignmentFixTest.class).
                findWarning("5:13-5:13:hint:" + Bundle.ERR_JoinAssignment()).
                applyFix(Bundle.ERR_JoinAssignment()).
                assertCompilable().
                assertOutput("package test;\n"
                        + "public class Test {\n"
                        + "    public static void main(String[] args) {\n"
                        + "        int bar;\n"
                        + "        bar = 42;\n"
                        + "        int foo = 42;\n"
                        + "    }\n"
                        + "}\n"
                );

    }

}


Product Version: NetBeans IDE 8.0 (Build 201403101706)
Updates: Updates available to version , NetBeans 8.0 Patch 1.1
Java: 1.8.0_05; Java HotSpot(TM) 64-Bit Server VM 25.5-b02
Runtime: Java(TM) SE Runtime Environment 1.8.0_05-b13
System: Windows 7 version 6.1 running on amd64; Cp1252; en_US (nb)
User directory: C:\Users\markiewb\AppData\Roaming\NetBeans\8.0
Cache directory: C:\Users\markiewb\AppData\Local\NetBeans\Cache\8.0
Comment 1 markiewb 2014-05-14 12:42:40 UTC
Sorry typo
(In reply to markiewb from comment #0)
> Example
> 
> int bar;
> bar = 42;
> int foo;
> f|oo = 42; //| marks the caret, invoke the hint here
> 

int bar;
bar = 42;
int fo|o; //| marks the caret, invoke the hint here
foo = 42;
Comment 2 Svata Dedic 2014-05-16 13:29:44 UTC
You hit two deficiencies in the pattern matching support. In fact it is the pattern matcher, which matches the wrong decl+assignment despite that the caret position indicates position the match should contain.

The matcher internally creates a { $$1$; yourStatements; $$2$; } pattern to match statements in a middle of a block. However the matcher finds only the first match in such case - the 'bar' variable and terminates.

I'll make the matching position-sensitive, so if a caret is specified for the matching, the user-specified pattern must contain the caret position. This does not solve the first-fit-only issue, but helps in your case and possibly in other suggestions which may currently also match and produce hint for an unrelated piece of code in the same codeblock.
Comment 3 markiewb 2014-07-21 20:54:57 UTC
(In reply to Svata Dedic from comment #2)
> You hit two deficiencies in the pattern matching support. In fact it is the
> pattern matcher, which matches the wrong decl+assignment despite that the
> caret position indicates position the match should contain.
> 
> The matcher internally creates a { $$1$; yourStatements; $$2$; } pattern to
> match statements in a middle of a block. However the matcher finds only the
> first match in such case - the 'bar' variable and terminates.
> 
> I'll make the matching position-sensitive, so if a caret is specified for
> the matching, the user-specified pattern must contain the caret position.
> This does not solve the first-fit-only issue, but helps in your case and
> possibly in other suggestions which may currently also match and produce
> hint for an unrelated piece of code in the same codeblock.

I guess, this isn't possible for NB8.0.1 anymore, right?
Comment 4 markiewb 2015-03-08 13:46:19 UTC
@Svata: Is there any workaround I can use in my plugin? 
Or I have to switch to @org.netbeans.spi.java.hints.TriggerTreeKind for this usecase?

-- https://github.com/markiewb/nb-additional-hints/issues/21
Comment 5 markiewb 2016-01-23 11:27:12 UTC
@Svata: Could this be fixed in 8.2?
Comment 6 markiewb 2016-07-05 23:09:10 UTC
@Svata: Any news here?