This is an automated email from the ASF dual-hosted git repository.
neilcsmith pushed a commit to branch delivery
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/delivery by this push:
new 2dcead8 attempt to make JackpotTrees more robust.
new e6bef73 Merge pull request #3283 from mbien/happytrees
2dcead8 is described below
commit 2dcead8dde01037abf983d7632e3143d1e3fee88
Author: Michael Bien <[email protected]>
AuthorDate: Thu Oct 28 22:50:30 2021 +0200
attempt to make JackpotTrees more robust.
- JackpotTrees.createInstance() will match constructors directly
(no unknown parameter filling with null anymore)
- extracted typesafe factory methods to keep the fragile code in one
place and make it hopefully easier to update it in future
---
.../modules/java/hints/spiimpl/JackpotTrees.java | 91 +++++++++++-----------
.../modules/java/hints/spiimpl/Utilities.java | 13 +---
2 files changed, 48 insertions(+), 56 deletions(-)
diff --git
a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java
b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java
index 96d3e00..8515d68 100644
---
a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java
+++
b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/JackpotTrees.java
@@ -33,6 +33,7 @@ import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.JCTree.JCCase;
import com.sun.tools.javac.tree.JCTree.Visitor;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.Context;
@@ -40,9 +41,7 @@ import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -61,7 +60,35 @@ import net.bytebuddy.matcher.ElementMatchers;
public class JackpotTrees {
private static final Map<Class<?>, Class<?>> baseClass2Impl = new
HashMap<>();
- public static <T> T createInstance(Context ctx, Class<T> clazz, Name
ident, JCIdent jcIdent, Class<?>[] requiredConstructor, Object[] params) {
+
+ // JDK 8-11
+ public static JCCase createJCCase(Name ident, JCIdent jcIdent, List<?>
stats) {
+ return createInstance(JCCase.class, ident, jcIdent,
+ new Class<?>[] {JCExpression.class, List.class},
+ new Object[] {jcIdent, stats});
+ }
+
+ // JDK 12-17+
+ public static JCCase createJCCase(Name ident, JCIdent jcIdent, String
caseKind, List<?> labels, List<?> stats, JCTree body) throws
ReflectiveOperationException {
+
+ @SuppressWarnings("rawtypes")
+ Class kindClass =
Class.forName("com.sun.source.tree.CaseTree$CaseKind", false,
JCCase.class.getClassLoader());
+ @SuppressWarnings("unchecked")
+ Object caseKindValue = Enum.valueOf(kindClass, caseKind);
+
+ return createInstance(JCCase.class, ident, jcIdent,
+ new Class<?>[] {kindClass, List.class, List.class,
JCTree.class},
+ new Object[] {caseKindValue, labels, stats, body});
+ }
+
+ // JDK 8-17+
+ public static JCVariableDecl createJCVariableDecl(Name ident, JCIdent
jcIdent, JCModifiers mods, Name param2, JCExpression vartype, JCExpression
init, VarSymbol sym) {
+ return createInstance(JCVariableDecl.class, ident, jcIdent,
+ new Class<?>[] {JCModifiers.class, Name.class,
JCExpression.class, JCExpression.class, VarSymbol.class},
+ new Object[] {mods, param2, vartype, init, sym});
+ }
+
+ private static <T> T createInstance(Class<T> clazz, Name ident, JCIdent
jcIdent, Class<?>[] requiredConstructor, Object[] params) {
try {
Class<?> fake = baseClass2Impl.get(clazz);
@@ -84,37 +111,31 @@ public class JackpotTrees {
.getLoaded();
baseClass2Impl.put(clazz, fake);
}
-
- NEXT: for (Constructor<?> c : fake.getDeclaredConstructors()) {
- if (c.getParameterCount() < requiredConstructor.length)
- continue;
- for (int e = 0; e < requiredConstructor.length; e++) {
- if
(!c.getParameterTypes()[e].equals(requiredConstructor[e])) {
- continue NEXT;
- }
- }
- java.util.List<Object> instances = new ArrayList<>();
- instances.addAll(Arrays.asList(params));
- for (int i = instances.size(); i < c.getParameterCount(); i++)
{
- instances.add(null);
+
+ Constructor<?> compatible = null;
+ for (Constructor<?> constructor : fake.getDeclaredConstructors()) {
+ if (Arrays.equals(constructor.getParameterTypes(),
requiredConstructor)) {
+ compatible = constructor;
+ break;
}
-
- JCTree tree = (JCTree) c.newInstance(instances.toArray(new
Object[0]));
+ }
+
+ if (compatible != null) {
+
+ JCTree tree = (JCTree) compatible.newInstance(params);
Field identField = fake.getDeclaredField("ident");
-
identField.set(tree, ident);
Field jcIdentField = fake.getDeclaredField("jcIdent");
-
jcIdentField.set(tree, jcIdent);
return clazz.cast(tree);
+ } else {
+ throw new IllegalStateException("no compatible constructors
found in: "+Arrays.asList(fake.getDeclaredConstructors()).toString());
}
-
- throw new
IllegalStateException(Arrays.asList(fake.getDeclaredConstructors()).toString());
- } catch (IllegalAccessException | IllegalArgumentException |
IllegalStateException | InstantiationException | NoSuchFieldException |
NoSuchMethodException | SecurityException | InvocationTargetException ex) {
- throw new IllegalStateException(ex);
+ } catch (ReflectiveOperationException | IllegalArgumentException |
IllegalStateException | SecurityException ex) {
+ throw new IllegalStateException("can't instantiate
"+Arrays.asList(requiredConstructor).toString()+" of "+clazz, ex);
}
}
@@ -202,27 +223,7 @@ public class JackpotTrees {
err.type = Symtab.instance(ctx).errType;
- JCVariableDecl var;
-
- try {
- var = createInstance(ctx,
- JCVariableDecl.class,
- name,
- jcIdent,
- new Class<?>[] {JCModifiers.class,
Name.class, JCExpression.class, JCExpression.class, VarSymbol.class},
- new Object[] {new FakeModifiers(), name, err,
null, null});
- } catch (IllegalStateException ex) {
- try {
- var = createInstance(ctx,
- JCVariableDecl.class,
- name,
- jcIdent,
- new Class<?>[] {JCModifiers.class,
Name.class, JCExpression.class, JCExpression.class, VarSymbol.class,
List.class},
- new Object[] {new FakeModifiers(), name,
err, null, null, List.nil()});
- } catch (IllegalStateException ex2) {
- throw ex;
- }
- }
+ JCVariableDecl var = createJCVariableDecl(name, jcIdent, new
FakeModifiers(), name, err, null, null);
var.sym = new VarSymbol(0, name, var.vartype.type,
Symtab.instance(ctx).errSymbol);
var.type = var.vartype.type;
diff --git
a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
index 59d17bc..b41ef37 100644
---
a/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
+++
b/java/spi.java.hints/src/org/netbeans/modules/java/hints/spiimpl/Utilities.java
@@ -1525,8 +1525,7 @@ public class Utilities {
}
JCIdent identTree = F.at(pos).Ident(name);
-
- return JackpotTrees.createInstance(ctx, JCCase.class,
name, identTree, new Class<?>[] {JCExpression.class,
com.sun.tools.javac.util.List.class}, new Object[] {identTree,
com.sun.tools.javac.util.List.nil()});
+ return JackpotTrees.createJCCase(name, identTree,
com.sun.tools.javac.util.List.nil());
}
}
}
@@ -1555,17 +1554,9 @@ public class Utilities {
nextToken();
}
- @SuppressWarnings("rawtypes")
- Class caseKind =
Class.forName("com.sun.source.tree.CaseTree$CaseKind", false,
JCCase.class.getClassLoader());
- @SuppressWarnings("unchecked")
- Object statement = Enum.valueOf(caseKind, "STATEMENT");
-
JCIdent identTree = F.at(pos).Ident(name);
return com.sun.tools.javac.util.List.of(
- JackpotTrees.createInstance(ctx,
JCCase.class, name, identTree,
- new Class<?>[] {caseKind,
com.sun.tools.javac.util.List.class, com.sun.tools.javac.util.List.class,
JCTree.class},
- new Object[] {statement,
com.sun.tools.javac.util.List.of(identTree),
com.sun.tools.javac.util.List.nil(), null}
- )
+ JackpotTrees.createJCCase(name, identTree,
"STATEMENT", com.sun.tools.javac.util.List.of(identTree),
com.sun.tools.javac.util.List.nil(), null)
);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists