You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by sk...@apache.org on 2021/07/30 14:59:24 UTC
[netbeans] branch master updated: Fixing handling of pattern
matching in instanceof in code generator (#3053)
This is an automated email from the ASF dual-hosted git repository.
skygo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 19be548 Fixing handling of pattern matching in instanceof in code generator (#3053)
19be548 is described below
commit 19be548f0bc53ecac53122e478a37e27ce344118
Author: Jan Lahoda <jl...@netbeans.org>
AuthorDate: Fri Jul 30 16:59:09 2021 +0200
Fixing handling of pattern matching in instanceof in code generator (#3053)
---
.../netbeans/modules/java/source/TreeShims.java | 2 +-
.../modules/java/source/save/CasualDiff.java | 22 ++++++++
.../source/transform/ImmutableTreeTranslator.java | 34 +++++++++---
.../api/java/source/gen/InstanceOfTest.java | 62 ++++++++++++++++++++--
.../modules/refactoring/java/test/RenameTest.java | 31 +++++++++++
5 files changed, 140 insertions(+), 11 deletions(-)
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
index ed13513..4cb0807 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/TreeShims.java
@@ -256,7 +256,7 @@ public class TreeShims {
}
@SuppressWarnings("unchecked")
- private static <T extends Throwable> RuntimeException throwAny(Throwable t) throws T {
+ public static <T extends Throwable> RuntimeException throwAny(Throwable t) throws T {
throw (T) t;
}
public static boolean isRecord(Element el) {
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
index 7979b08..5b879c2 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/save/CasualDiff.java
@@ -132,6 +132,7 @@ import com.sun.tools.javac.util.Position;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.Map.Entry;
@@ -1958,6 +1959,23 @@ public class CasualDiff {
return bounds[1];
}
+ protected int diffBindingPattern(Tree oldT, Tree newT, int[] bounds) {
+ VariableTree oldVar = getBindingVariableTree(oldT);
+ VariableTree newVar = getBindingVariableTree(newT);
+
+ return diffTree((JCTree) oldVar, (JCTree) newVar, bounds);
+ }
+
+ @NbBundle.Messages("ERR_PatternMatchingInstanceOf=Transformation for pattern matching in instanceof not supported on this version of JDK. Please run on JDK 16 or newer, or install nb-javac.")
+ public static VariableTree getBindingVariableTree(Tree node) {
+ try {
+ Class bpt = Class.forName("com.sun.source.tree.BindingPatternTree"); //NOI18N
+ return (VariableTree)bpt.getDeclaredMethod("getVariable").invoke(node); //NOI18N
+ } catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+ throw TreeShims.<RuntimeException>throwAny(Exceptions.attachLocalizedMessage(ex, Bundle.ERR_PatternMatchingInstanceOf()));
+ }
+ }
+
protected int diffCase(JCCase oldT, JCCase newT, int[] bounds) {
int localPointer = bounds[0];
List<JCExpression> oldPatterns = getCasePatterns(oldT);
@@ -5730,6 +5748,10 @@ public class CasualDiff {
retVal = diffSwitchExpression(oldT, newT, elementBounds);
break;
}
+ if(oldT.getKind().toString().equals(TreeShims.BINDING_PATTERN)){
+ retVal = diffBindingPattern(oldT, newT, elementBounds);
+ break;
+ }
String msg = "Diff not implemented: " +
((com.sun.source.tree.Tree)oldT).getKind().toString() +
" " + oldT.getClass().getName();
diff --git a/java/java.source.base/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java b/java/java.source.base/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java
index 85d1461..b490380 100644
--- a/java/java.source.base/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java
+++ b/java/java.source.base/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java
@@ -24,10 +24,10 @@ import com.sun.source.tree.*;
import com.sun.source.tree.Tree.Kind;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.model.JavacElements;
-import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCLambda;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
import com.sun.tools.javac.util.Context;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -48,9 +48,12 @@ import org.netbeans.modules.java.source.builder.QualIdentTree;
import org.netbeans.modules.java.source.builder.TreeFactory;
import org.netbeans.modules.java.source.pretty.ImportAnalysis2;
import org.netbeans.modules.java.source.query.CommentHandler;
+import org.netbeans.modules.java.source.save.CasualDiff;
import org.netbeans.modules.java.source.save.ElementOverlay;
import static org.netbeans.modules.java.source.save.PositionEstimator.*;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle;
/** A subclass of Tree.Visitor, this class defines
* a general tree translator pattern. Translation proceeds recursively in
@@ -119,9 +122,11 @@ public class ImmutableTreeTranslator implements TreeVisitor<Tree,Object> {
/** Visitor method: Translate a single node.
*/
public Tree translate(Tree tree) {
- if (tree == null)
+ if (tree == null) {
return null;
- else {
+ } else if (tree.getKind().name().equals(TreeShims.BINDING_PATTERN)) {
+ return rewriteChildrenBindingPattern(tree);
+ } else {
Tree t = tree.accept(this, null);
if (tree2Tag != null && tree != t && tmaker != null) {
@@ -1134,9 +1139,13 @@ public class ImmutableTreeTranslator implements TreeVisitor<Tree,Object> {
protected final InstanceOfTree rewriteChildren(InstanceOfTree tree) {
ExpressionTree expr = (ExpressionTree)translate(tree.getExpression());
- Tree clazz = translateClassRef(tree.getType());
- if (expr!=tree.getExpression() || clazz!=tree.getType()) {
- InstanceOfTree n = make.InstanceOf(expr, clazz);
+ Tree origPattern = TreeShims.getPattern(tree);
+ if (origPattern == null) {
+ origPattern = tree.getType();
+ }
+ Tree newPattern = translate(origPattern);
+ if (expr!=tree.getExpression() || newPattern!=origPattern) {
+ InstanceOfTree n = make.InstanceOf(expr, newPattern);
model.setType(n, model.getType(tree));
copyCommentTo(tree,n);
copyPosTo(tree,n);
@@ -1405,4 +1414,17 @@ public class ImmutableTreeTranslator implements TreeVisitor<Tree,Object> {
}
return tree;
}
+
+ private Tree rewriteChildrenBindingPattern(Tree tree) {
+ VariableTree var = CasualDiff.getBindingVariableTree(tree); //replace with tree.getVariable when javac supported is 16+:
+ VariableTree newVar = (VariableTree) translate(var);
+ if (newVar != var) {
+ Tree n = make.BindingPattern(newVar);
+ model.setType(n, model.getType(tree));
+ copyCommentTo(tree,n);
+ copyPosTo(tree,n);
+ tree = n;
+ }
+ return tree;
+ }
}
diff --git a/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/InstanceOfTest.java b/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/InstanceOfTest.java
index 19cc98d..aff6ea1 100644
--- a/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/InstanceOfTest.java
+++ b/java/java.source.base/test/unit/src/org/netbeans/api/java/source/gen/InstanceOfTest.java
@@ -21,16 +21,17 @@ package org.netbeans.api.java.source.gen;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.IfTree;
import com.sun.source.tree.InstanceOfTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.tree.ParenthesizedTree;
+import com.sun.source.tree.Tree;
import com.sun.source.tree.VariableTree;
-import com.sun.tools.javac.tree.JCTree;
+import com.sun.source.util.TreeScanner;
import java.io.File;
import java.io.IOException;
import java.util.EnumSet;
-import javax.lang.model.SourceVersion;
import javax.lang.model.element.Modifier;
import org.netbeans.api.java.source.Task;
import org.netbeans.api.java.source.JavaSource;
@@ -197,11 +198,64 @@ public class InstanceOfTest extends GeneratorTestMDRCompat {
assertEquals(golden, res);
}
+ public void testRenamePatternMatchingType() throws Exception {
+ if (!typeTestPatternAvailable())
+ return ;
+
+ testFile = new File(getWorkDir(), "Test.java");
+ TestUtilities.copyStringToFile(testFile,
+ "package hierbas.del.litoral;\n\n" +
+ "public class Test {\n" +
+ " public boolean taragui(Object o) {\n" +
+ " return o instanceof Test t;\n" +
+ " }\n" +
+ "}\n"
+ );
+ String golden =
+ "package hierbas.del.litoral;\n\n" +
+ "public class Test {\n" +
+ " public boolean taragui(Object o) {\n" +
+ " return o2 instanceof Test2 t;\n" +
+ " }\n" +
+ "}\n";
+ JavaSource src = getJavaSource(testFile);
+
+ Task<WorkingCopy> task = new Task<WorkingCopy>() {
+
+ public void run(WorkingCopy workingCopy) throws IOException {
+ workingCopy.toPhase(Phase.RESOLVED);
+ CompilationUnitTree cut = workingCopy.getCompilationUnit();
+ TreeMaker make = workingCopy.getTreeMaker();
+ new TreeScanner<Void, Void>() {
+ @Override
+ public Void visitVariable(VariableTree node, Void p) {
+ if (node.getName().contentEquals("t")) {
+ workingCopy.rewrite(node.getType(), make.Identifier("Test2"));
+ }
+ return super.visitVariable(node, p);
+ }
+ @Override
+ public Void visitIdentifier(IdentifierTree node, Void p) {
+ if (node.getName().contentEquals("o")) {
+ workingCopy.rewrite(node, workingCopy.getTreeMaker().setLabel(node, "o2"));
+ }
+ return super.visitIdentifier(node, p);
+ }
+ }.scan(cut, null);
+ }
+
+ };
+ src.runModificationTask(task).commit();
+ String res = TestUtilities.copyFileToString(testFile);
+ System.err.println(res);
+ assertEquals(golden, res);
+ }
+
private boolean typeTestPatternAvailable() {
try {
- Class.forName("com.sun.source.tree.BindingPatternTree", false, JCTree.class.getClassLoader());
+ Class.forName("com.sun.source.tree.BindingPatternTree", false, Tree.class.getClassLoader()).getDeclaredMethod("getVariable");
return true;
- } catch (ClassNotFoundException ex) {
+ } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) {
//OK
return false;
}
diff --git a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/RenameTest.java b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/RenameTest.java
index 0f2686f..f3d878d 100644
--- a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/RenameTest.java
+++ b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/RenameTest.java
@@ -1483,6 +1483,27 @@ public class RenameTest extends RefactoringTestBase {
}
+ public void testRenameBindingVariableType() throws Exception {
+ if (!typeTestPatternAvailable()) return; //only run the test when javac supports it
+ writeFilesAndWaitForScan(src,
+ new File("t/A.java", "package t;\n"
+ + "public class A {\n"
+ + " public boolean taragui(Object o) {\n"
+ + " return o instanceof A a && a.toString() != null;\n"
+ + " }\n"
+ + "}"));
+ JavaRenameProperties props = new JavaRenameProperties();
+ performRename(src.getFileObject("t/A.java"), 25, "B", props, true);
+ verifyContent(src,
+ new File("t/A.java", "package t;\n"
+ + "public class B {\n"
+ + " public boolean taragui(Object o) {\n"
+ + " return o instanceof B a && a.toString() != null;\n"
+ + " }\n"
+ + "}"));
+
+ }
+
private void performRename(FileObject source, final int position, final int position2, final String newname, final JavaRenameProperties props, final boolean searchInComments, Problem... expectedProblems) throws Exception {
final RenameRefactoring[] r = new RenameRefactoring[1];
JavaSource.forFileObject(source).runUserActionTask(new Task<CompilationController>() {
@@ -1557,4 +1578,14 @@ public class RenameTest extends RefactoringTestBase {
assertProblems(Arrays.asList(expectedProblems), problems);
}
+
+ private boolean typeTestPatternAvailable() {
+ try {
+ Class.forName("com.sun.source.tree.BindingPatternTree", false, Tree.class.getClassLoader()).getDeclaredMethod("getVariable");
+ return true;
+ } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) {
+ //OK
+ return false;
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists