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 <mbie...@gmail.com>
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: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

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

Reply via email to