You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@netbeans.apache.org by GitBox <gi...@apache.org> on 2018/12/25 04:57:41 UTC

[GitHub] JaroslavTulach closed pull request #1049: Fixing implicit trees in conditions; when a variable/field pattern ha…

JaroslavTulach closed pull request #1049: Fixing implicit trees in conditions; when a variable/field pattern ha…
URL: https://github.com/apache/incubator-netbeans/pull/1049
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/java/java.hints.declarative/src/org/netbeans/modules/java/hints/declarative/Condition.java b/java/java.hints.declarative/src/org/netbeans/modules/java/hints/declarative/Condition.java
index 477e0ff027..044f992d75 100644
--- a/java/java.hints.declarative/src/org/netbeans/modules/java/hints/declarative/Condition.java
+++ b/java/java.hints.declarative/src/org/netbeans/modules/java/hints/declarative/Condition.java
@@ -26,6 +26,7 @@
 import javax.lang.model.type.TypeMirror;
 import org.netbeans.api.java.source.CompilationInfo;
 import org.netbeans.modules.java.hints.declarative.conditionapi.Context;
+import org.netbeans.modules.java.hints.declarative.conditionapi.Variable;
 
 /**
  *
@@ -59,13 +60,12 @@ public Instanceof(boolean not, String variable, String constraint, int[]  constr
 
         @Override
         public boolean holds(Context ctx, boolean global) {
-            if (global && !not) {
-                //if this is a global condition, not == false, then the computation should always lead to true
-                //note that ctx.getVariables().get(variable) might even by null (implicit this)
-                return true;
+            TreePath boundTo = APIAccessor.IMPL.getSingleVariable(ctx, new Variable(variable));
+
+            if (boundTo == null) {
+                throw new IllegalStateException();
             }
 
-            TreePath boundTo = APIAccessor.IMPL.getSingleVariable(ctx, ctx.variableForName(variable));
             CompilationInfo info = APIAccessor.IMPL.getHintContext(ctx).getInfo();
             TypeMirror realType = info.getTrees().getTypeMirror(boundTo);
             TypeMirror designedType = Hacks.parseFQNType(info, constraint);
diff --git a/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/ImplicitThisCheck.hint b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/ImplicitThisCheck.hint
new file mode 100644
index 0000000000..499880f665
--- /dev/null
+++ b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/ImplicitThisCheck.hint
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+$this.m() :: $this instanceof test.Test
+=>
+$this.m2() :: $this instanceof java.io.Serializable
+;;
diff --git a/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/ImplicitThisCheck.test b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/ImplicitThisCheck.test
new file mode 100644
index 0000000000..cb088bb051
--- /dev/null
+++ b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/ImplicitThisCheck.test
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+%%TestCase positive
+package test;
+import java.io.Serializable;
+public class Test implements Serializable {
+    public void m() {}
+    public void m2() {}
+    private void t() {
+        m();
+    }
+    private class I {
+        private void t() {
+            m();
+        }
+    }
+}
+%%=>
+package test;
+import java.io.Serializable;
+public class Test implements Serializable {
+    public void m() {}
+    public void m2() {}
+    private void t() {
+        m2();
+    }
+    private class I {
+        private void t() {
+            m();
+        }
+    }
+}
+%%=>
+package test;
+import java.io.Serializable;
+public class Test implements Serializable {
+    public void m() {}
+    public void m2() {}
+    private void t() {
+        m();
+    }
+    private class I {
+        private void t() {
+            m2();
+        }
+    }
+}
diff --git a/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/SubtypeOfSerializable.hint b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/SubtypeOfSerializable.hint
new file mode 100644
index 0000000000..dfe2d4045d
--- /dev/null
+++ b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/SubtypeOfSerializable.hint
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+$mods$ class $name extends $extends$ implements $implements$ {
+    $members$;
+} :: $name instanceof java.io.Serializable
+;;
diff --git a/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/SubtypeOfSerializable.test b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/SubtypeOfSerializable.test
new file mode 100644
index 0000000000..3fc1689f95
--- /dev/null
+++ b/java/java.hints.declarative/test/unit/src/org/netbeans/modules/java/hints/declarative/SubtypeOfSerializable.test
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+%%TestCase positive
+package test;
+public class Test implements java.io.Serializable {
+}
+%%=>
+SubtypeOfSerializable:Test
diff --git a/java/java.source.base/apichanges.xml b/java/java.source.base/apichanges.xml
index d1c2be7b4f..940b76f45b 100644
--- a/java/java.source.base/apichanges.xml
+++ b/java/java.source.base/apichanges.xml
@@ -25,6 +25,19 @@
     <apidef name="javasource_base">Java Source API</apidef>
 </apidefs>
 <changes>
+    <change id="Matcher.setKeepSyntheticTrees">
+        <api name="javasource_base"/>
+        <summary>Adding Matcher.setKeepSyntheticTrees method</summary>
+        <version major="1" minor="2.40"/>
+        <date day="7" month="12" year="2018"/>
+        <author login="jlahoda"/>
+        <compatibility addition="yes" binary="compatible" source="compatible"/>
+        <description>
+            Added Matcher.setKeepSyntheticTrees method, that allows to keep synthetically
+            generated variables mapping in the outgoing variables.
+        </description>
+        <class name="Matcher" package="org.netbeans.api.java.source.matching"/>
+    </change>
     <change id="TreeMaker.Case">
         <api name="javasource_base"/>
         <summary>Adding case-related overload to TreeMaker</summary>
diff --git a/java/java.source.base/nbproject/project.properties b/java/java.source.base/nbproject/project.properties
index 76919d6377..199f22b23e 100644
--- a/java/java.source.base/nbproject/project.properties
+++ b/java/java.source.base/nbproject/project.properties
@@ -23,7 +23,7 @@ javadoc.name=Java Source Base
 javadoc.title=Java Source Base
 javadoc.arch=${basedir}/arch.xml
 javadoc.apichanges=${basedir}/apichanges.xml
-spec.version.base=2.39.0
+spec.version.base=2.40.0
 test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/nb-javac-api.jar
 test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\
     ${o.n.core.dir}/lib/boot.jar:\
diff --git a/java/java.source.base/src/org/netbeans/api/java/source/matching/Matcher.java b/java/java.source.base/src/org/netbeans/api/java/source/matching/Matcher.java
index 51dd8224ff..3203d909e2 100644
--- a/java/java.source.base/src/org/netbeans/api/java/source/matching/Matcher.java
+++ b/java/java.source.base/src/org/netbeans/api/java/source/matching/Matcher.java
@@ -101,6 +101,17 @@ private Matcher(CompilationInfo info) {
         return this;
     }
 
+    /**When set, trees (like implicit receivers) that are not in the source code,
+     * but have variable in the pattern, will get a synthetic entry in variables.
+     *
+     * @return the matcher itself
+     * @since 2.40
+     */
+    public @NonNull Matcher setKeepSyntheticTrees() {
+        this.options.add(Options.KEEP_SYNTHETIC_THIS);
+        return this;
+    }
+
     /**Preset values of free variables in the pattern (see {@link Pattern#createPatternWithFreeVariables(com.sun.source.util.TreePath, java.util.Map)}).
      * A tree node will be marked as an occurrence of the pattern only if the subtree
      * corresponding to a specified free variable will match the given value.
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/matching/CopyFinder.java b/java/java.source.base/src/org/netbeans/modules/java/source/matching/CopyFinder.java
index 0f5b7fa08d..303ff24daf 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/matching/CopyFinder.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/matching/CopyFinder.java
@@ -1031,7 +1031,9 @@ private boolean deepVerifyIdentifier2MemberSelect(TreePath identifier, TreePath
                     return true;
                 }
             } finally {
-                bindState = origState;
+                if (!options.contains(Options.KEEP_SYNTHETIC_THIS)) {
+                    bindState = origState;
+                }
             }
         }
 
@@ -1554,15 +1556,16 @@ public Boolean visitVariable(VariableTree node, TreePath p) {
                 bindState.variables.put(name, getCurrentPath());
                 bindState.variables2Names.put(name, currentName);
             }
-        }
-
-        if (allowVariablesRemap) {
+        } else if (allowVariablesRemap) {
             VariableElement nodeEl = (VariableElement) info.getTrees().getElement(getCurrentPath());
             VariableElement pEl = (VariableElement) info.getTrees().getElement(p);
 
             if (nodeEl != null && pEl != null && isSameTypeForVariableRemap(nodeEl.asType(), pEl.asType())) {
                 bindState.variablesRemapToElement.put(pEl, nodeEl);
             }
+        } else {
+            if (!node.getName().contentEquals(name))
+                return false;
         }
 
         return scan(node.getInitializer(), t.getInitializer(), p);
@@ -1878,7 +1881,7 @@ public static State from(Map<String, TreePath> variables, Map<String, Collection
     }
 
     public enum Options {
-        ALLOW_VARIABLES_IN_PATTERN, ALLOW_REMAP_VARIABLE_TO_EXPRESSION, ALLOW_GO_DEEPER, NO_ELEMENT_VERIFY;
+        ALLOW_VARIABLES_IN_PATTERN, ALLOW_REMAP_VARIABLE_TO_EXPRESSION, ALLOW_GO_DEEPER, NO_ELEMENT_VERIFY, KEEP_SYNTHETIC_THIS;
     }
     
     //TODO: copied from java.hints' Utilities:
diff --git a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java
index d30dd72e2f..a12eba29ad 100644
--- a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java
+++ b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/hints/HintsInvoker.java
@@ -537,7 +537,7 @@ private HintsInvoker(HintsSettings settings, int caret, int from, int to, boolea
                 for (TreePath candidate : occ.getValue()) {
                     if (cancel.get()) return null;
                 
-                    Iterator<? extends Occurrence> verified = Matcher.create(info).setCancel(cancel).setSearchRoot(candidate).setTreeTopSearch().match(pattern).iterator();
+                    Iterator<? extends Occurrence> verified = Matcher.create(info).setCancel(cancel).setSearchRoot(candidate).setTreeTopSearch().setKeepSyntheticTrees().match(pattern).iterator();
 
                     if (!verified.hasNext()) {
                         continue;
diff --git a/java/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java b/java/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java
index 683b47a465..4b427b784a 100644
--- a/java/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java
+++ b/java/spi.java.hints/test/unit/src/org/netbeans/spi/java/hints/matching/CopyFinderTest.java
@@ -48,7 +48,9 @@
 import org.netbeans.api.java.source.SourceUtilsTestUtil;
 import org.netbeans.api.java.source.TestUtilities;
 import org.netbeans.api.java.source.TreePathHandle;
+import org.netbeans.api.java.source.matching.Matcher;
 import org.netbeans.api.java.source.matching.MatchingTestAccessor;
+import org.netbeans.api.java.source.matching.Occurrence;
 import org.netbeans.api.java.source.matching.Pattern;
 import org.netbeans.api.lexer.Language;
 import org.netbeans.junit.NbTestCase;
@@ -1256,6 +1258,36 @@ public void testAnnotation2() throws Exception {
                              false);
     }
     
+    public void testKeepImplicitThis() throws Exception {
+        prepareTest("package test; public class Test { void t() { toString(); } }", -1);
+
+        Map<String, TypeMirror> constraints = new HashMap<>();
+        String patternCode = PatternCompilerUtilities.parseOutTypesFromPattern(info, "$0{test.Test}.toString()", constraints);
+
+        Pattern pattern = PatternCompiler.compile(info, patternCode, constraints, Collections.<String>emptyList());
+
+        Collection<? extends Occurrence> occurrences = Matcher.create(info).setKeepSyntheticTrees().match(pattern);
+
+        assertEquals(1, occurrences.size());
+        Occurrence occ = occurrences.iterator().next();
+        assertEquals("this", occ.getVariables().get("$0").getLeaf().toString());
+    }
+
+    public void testFieldCheckName() throws Exception {
+        prepareTest("package test; public class Test { private int foo; private int foo2; }", -1);
+
+        Map<String, TypeMirror> constraints = new HashMap<>();
+        String patternCode = PatternCompilerUtilities.parseOutTypesFromPattern(info, "private int foo;", constraints);
+
+        Pattern pattern = PatternCompiler.compile(info, patternCode, constraints, Collections.<String>emptyList());
+
+        Collection<? extends Occurrence> occurrences = Matcher.create(info).match(pattern);
+
+        assertEquals(1, occurrences.size());
+        Occurrence occ = occurrences.iterator().next();
+        assertEquals("private int foo", occ.getOccurrenceRoot().getLeaf().toString());
+    }
+
     protected void prepareTest(String code) throws Exception {
         prepareTest(code, -1);
     }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists