You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/01/30 21:40:09 UTC

[groovy] 04/04: GROOVY-10464: stubgen: super ctor call: handle class cases

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit bfb29e8eeda0e9b516f94d27fc42930567fd279e
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Jan 27 11:10:21 2022 -0600

    GROOVY-10464: stubgen: super ctor call: handle class cases
    
    Conflicts:
    	src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
---
 .../groovy/tools/javac/JavaStubGenerator.java      | 38 +++++++++------
 .../tools/stubgenerator/Groovy10122pt2.groovy      | 54 ++++++++++++++++++++++
 .../groovy/tools/stubgenerator/Groovy10464.groovy  | 52 +++++++++++++++++++++
 .../tools/stubgenerator/Groovy10464pt2.groovy      | 54 ++++++++++++++++++++++
 4 files changed, 183 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
index a780d8e..4bf8e1b 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -25,6 +25,7 @@ import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.ConstructorNode;
+import org.codehaus.groovy.ast.DynamicVariable;
 import org.codehaus.groovy.ast.FieldNode;
 import org.codehaus.groovy.ast.GenericsType;
 import org.codehaus.groovy.ast.ImportNode;
@@ -33,6 +34,7 @@ import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.ModuleNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.PropertyNode;
+import org.codehaus.groovy.ast.Variable;
 import org.codehaus.groovy.ast.decompiled.DecompiledClassNode;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.ClassExpression;
@@ -81,6 +83,7 @@ import java.util.stream.Stream;
 
 import static org.apache.groovy.ast.tools.ConstructorNodeUtils.getFirstIfSpecialConstructorCall;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
+import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
 
 public class JavaStubGenerator {
@@ -155,11 +158,8 @@ public class JavaStubGenerator {
         javaStubCompilationUnitSet.add(new RawJavaFileObject(createJavaStubFile(fileName).toPath().toUri()));
     }
 
-    private static final int DEFAULT_BUFFER_SIZE = 8 * 1024; // 8K
-
     private String generateStubContent(ClassNode classNode) {
-        Writer writer = new StringBuilderWriter(DEFAULT_BUFFER_SIZE);
-
+        Writer writer = new StringBuilderWriter(8192);
         try (PrintWriter out = new PrintWriter(writer)) {
             boolean packageInfo = "package-info".equals(classNode.getNameWithoutPackage());
             String packageName = classNode.getPackageName();
@@ -212,7 +212,7 @@ public class JavaStubGenerator {
                         Map<String, ClassNode> generics = trait.isUsingGenerics() ? createGenericsSpec(trait) : null;
                         for (PropertyNode traitProperty : trait.getProperties()) {
                             ClassNode traitPropertyType = traitProperty.getType();
-                            traitProperty.setType(correctToGenericsSpec(generics, traitPropertyType));
+                            traitProperty.setType(correctToGenericsSpecRecurse(generics, traitPropertyType));
                             super.visitProperty(traitProperty);
                             traitProperty.setType(traitPropertyType);
                         }
@@ -407,15 +407,14 @@ public class JavaStubGenerator {
                         }
                     }
                 }
-                if (existingMethod != null) continue;
-                boolean isCandidate = isCandidateTraitMethod(trait, traitMethod);
-                if (!isCandidate) continue;
-                printMethod(out, classNode, traitMethod);
+                if (existingMethod == null && isCandidateTraitMethod(trait, traitMethod)) {
+                    printMethod(out, classNode, traitMethod);
+                }
             }
         }
     }
 
-    private boolean isCandidateTraitMethod(ClassNode trait, MethodNode traitMethod) {
+    private boolean isCandidateTraitMethod(final ClassNode trait, final MethodNode traitMethod) {
         boolean precompiled = trait.redirect() instanceof DecompiledClassNode;
         if (!precompiled) return !traitMethod.isAbstract();
         List<MethodNode> helperMethods = Traits.findHelper(trait).getMethods();
@@ -569,7 +568,7 @@ public class JavaStubGenerator {
                     normalizedType = normalizedType.getPlainNodeReference();
                 } else {
                     // GROOVY-7306: apply type arguments from declaring type to parameter type
-                    normalizedType = correctToGenericsSpec(superTypeGenerics, normalizedType);
+                    normalizedType = correctToGenericsSpecRecurse(superTypeGenerics, normalizedType);
                 }
                 return new Parameter(normalizedType, parameter.getName());
             }).toArray(Parameter[]::new);
@@ -655,7 +654,17 @@ public class JavaStubGenerator {
 
     private static ClassNode getConstructorArgumentType(final Expression arg, final ConstructorNode ctor) {
         if (arg instanceof VariableExpression) {
-            return ((VariableExpression) arg).getAccessedVariable().getType();
+            Variable variable = ((VariableExpression) arg).getAccessedVariable();
+            if (variable instanceof DynamicVariable) { // GROOVY-10464
+                return ClassHelper.CLASS_Type.getPlainNodeReference();
+            }
+            return variable.getType(); // field, property, parameter
+        }
+        if (arg instanceof PropertyExpression) {
+            if ("class".equals(((PropertyExpression) arg).getPropertyAsString())) {
+                return ClassHelper.CLASS_Type.getPlainNodeReference();
+            }
+            return null;
         }
         if (arg instanceof MethodCallExpression) { // GROOVY-10122
             MethodCallExpression mce = (MethodCallExpression) arg;
@@ -669,7 +678,7 @@ public class JavaStubGenerator {
     }
 
     private void printMethod(PrintWriter out, ClassNode clazz, MethodNode methodNode) {
-        if (methodNode.getName().equals("<clinit>")) return;
+        if (methodNode.isStaticConstructor()) return;
         if (methodNode.isPrivate() || !Utilities.isJavaIdentifier(methodNode.getName())) return;
         if (methodNode.isSynthetic() && methodNode.getName().equals("$getStaticMetaClass")) return;
 
@@ -813,7 +822,6 @@ public class JavaStubGenerator {
             printType(out, type);
             out.print(")");
         }
-
         if (type != null && ClassHelper.isPrimitiveType(type)) {
             if (type.equals(ClassHelper.boolean_TYPE)) {
                 out.print("false");
@@ -960,7 +968,7 @@ public class JavaStubGenerator {
             val = ((Expression) memberValue).getText();
         } else if (memberValue instanceof VariableExpression) {
             val = ((Expression) memberValue).getText();
-            //check for an alias
+            // check for an alias
             ImportNode alias = currentModule.getStaticImports().get(val);
             if (alias != null)
                 val = alias.getClassName() + "." + alias.getFieldName();
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122pt2.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122pt2.groovy
new file mode 100644
index 0000000..cf7b245
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122pt2.groovy
@@ -0,0 +1,54 @@
+/*
+ *  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.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy10122pt2 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'A.java': '''
+                public abstract class A<T> {
+                    A(T t) {
+                    }
+                }
+            ''',
+            'C.groovy': '''
+                class C<T> extends A<T> {
+                    C(T t) {
+                        super(t)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C(null);
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        def specialCtorCall = (stubJavaSourceFor('C') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(T)null'
+    }
+}
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464.groovy
new file mode 100644
index 0000000..38760a8
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464.groovy
@@ -0,0 +1,52 @@
+/*
+ *  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.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy10464 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'C.groovy': '''
+                public abstract class A<B> {
+                    A(Class<B> class_of_b) {
+                    }
+                }
+                class C extends A<String> {
+                    C() {
+                        super(String.class)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        def specialCtorCall = (stubJavaSourceFor('C') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(java.lang.Class<java.lang.String>)null'
+    }
+}
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464pt2.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464pt2.groovy
new file mode 100644
index 0000000..bef8ae4
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10464pt2.groovy
@@ -0,0 +1,54 @@
+/*
+ *  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.
+ */
+package org.codehaus.groovy.tools.stubgenerator
+
+final class Groovy10464pt2 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'A.java': '''
+                public abstract class A<B> {
+                    A(Class<B> class_of_b) {
+                    }
+                }
+            ''',
+            'C.groovy': '''
+                class C extends A<String> {
+                    C() {
+                        super(String)
+                    }
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        def specialCtorCall = (stubJavaSourceFor('C') =~ /super\s*\((.+?)\);/)
+        assert specialCtorCall.find() && specialCtorCall.group(1) == '(java.lang.Class)null'
+    }
+}