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

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

commit e7d918f11e044c89096d73d4a6938203534662cf
Author: Eric Milles <[email protected]>
AuthorDate: Mon Mar 13 11:15:46 2023 -0500

    GROOVY-10299, GROOVY-10611: stubgen: primitive or integer/decimal values
    
    2_5_X backport
---
 .../groovy/tools/javac/JavaStubGenerator.java      | 104 +++++++++++++--------
 src/test/groovy/bugs/Groovy5260Bug.groovy          |  91 +++++++++---------
 .../AnnotationDefaultValuesStubTest.groovy         |   6 +-
 .../groovy/tools/stubgenerator/Groovy10299.groovy  |  46 +++++++++
 .../groovy/tools/stubgenerator/Groovy10611.groovy  |  50 ++++++++++
 5 files changed, 210 insertions(+), 87 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 8a1a7d07b0..fbf1190678 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -80,6 +80,8 @@ import java.util.Set;
 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;
+import static 
org.codehaus.groovy.ast.tools.WideningCategories.isFloatingCategory;
+import static org.codehaus.groovy.ast.tools.WideningCategories.isLongCategory;
 
 public class JavaStubGenerator {
     private final boolean java5;
@@ -451,24 +453,33 @@ public class JavaStubGenerator {
         out.print(field.getName());
 
         if (interfaceOrTrait || field.isFinal()) {
-            // GROOVY-5150: initialize field with a value so Java compiles 
correctly
             out.print(" = ");
-            Expression valueExpr = field.getInitialValueExpression();
-            if (valueExpr instanceof ConstantExpression && 
!type.equals(ClassHelper.STRING_TYPE)) {
-                valueExpr = 
Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) valueExpr);
-            }
-            ClassNode valueType;
-            if (field.isStatic()
-                    && valueExpr instanceof ConstantExpression
-                    && (valueType = valueExpr.getType()).equals(type)
-                    && ClassHelper.isStaticConstantInitializerType(valueType)) 
{
-                if (ClassHelper.isNumberType(valueType)) {
-                    out.print("(" + type.toString(false) + ") ");
+            if (field.isStatic() && field.hasInitialExpression()) {
+                Expression value = 
ExpressionUtils.transformInlineConstants(field.getInitialValueExpression(), 
type);
+                if (value instanceof ConstantExpression) {
+                    if (ClassHelper.isPrimitiveType(type)) { // do not pass 
string of length 1 for String field:
+                        value = 
Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) value);
+                    }
+                    if ((type.equals(value.getType()) // GROOVY-10611: 
integer/decimal value
+                                || (isLongCategory(type) && 
value.getType().equals(ClassHelper.int_TYPE))
+                                || (isFloatingCategory(type) && 
ClassHelper.BigDecimal_TYPE.equals(value.getType())))
+                            && (type.equals(ClassHelper.boolean_TYPE) || 
ClassHelper.isStaticConstantInitializerType(type))) {
+                        printValue(out, (ConstantExpression) value);
+                        out.println(';');
+                        return;
+                    }
+                }
+
+                // GROOVY-5150, GROOVY-10902, GROOVY-10928: output dummy value
+                if (ClassHelper.isPrimitiveType(type) || 
type.equals(ClassHelper.STRING_TYPE)) {
+                    out.print("new " + ClassHelper.getWrapper(type) + "(");
+                    printDefaultValue(out, type);
+                    out.print(')');
+                } else {
+                    out.print("null");
                 }
-                printValue(out, valueExpr, false);
             } else if (ClassHelper.isPrimitiveType(type)) {
-                String value = type.equals(ClassHelper.boolean_TYPE) ? "false" 
: "(" + type.toString(false) + ")0";
-                out.print("new " + ClassHelper.getWrapper(type) + "(" + value 
+ ")");
+                printDefaultValue(out, type);
             } else {
                 out.print("null");
             }
@@ -685,7 +696,8 @@ public class JavaStubGenerator {
                     Expression re = es.getExpression();
                     out.print(" default ");
                     ClassNode rt = methodNode.getReturnType();
-                    boolean classReturn = ClassHelper.CLASS_Type.equals(rt) || 
(rt.isArray() && ClassHelper.CLASS_Type.equals(rt.getComponentType()));
+                    boolean classReturn = rt.equals(ClassHelper.CLASS_Type)
+                            || (rt.isArray() && 
rt.getComponentType().equals(ClassHelper.CLASS_Type));
                     if (re instanceof ListExpression) {
                         out.print("{ ");
                         ListExpression le = (ListExpression) re;
@@ -733,36 +745,50 @@ public class JavaStubGenerator {
         return Traits.isTrait(methodNode.getDeclaringClass()) && 
Traits.hasDefaultImplementation(methodNode);
     }
 
-    private static void printValue(PrintWriter out, Expression re, boolean 
assumeClass) {
+    private void printValue(final PrintWriter out, final Expression exp, final 
boolean assumeClass) {
         if (assumeClass) {
-            if (re.getType().getName().equals("groovy.lang.Closure")) {
+            if (exp.getType().getName().equals("groovy.lang.Closure")) {
                 out.print("groovy.lang.Closure.class");
                 return;
             }
-            String className = re.getText();
+            String className = exp.getText();
             out.print(className);
             if (!className.endsWith(".class")) {
                 out.print(".class");
             }
-        } else if (re instanceof ConstantExpression) {
-            ConstantExpression ce = (ConstantExpression) re;
-            Object value = ce.getValue();
-            if (ClassHelper.STRING_TYPE.equals(ce.getType())) {
-                out.print("\"" + escapeSpecialChars((String) value) + "\"");
-            } else if (ClassHelper.char_TYPE.equals(ce.getType())
-                    || ClassHelper.Character_TYPE.equals(ce.getType())) {
-                out.print("'" + escapeSpecialChars("" + 
value.toString().charAt(0)) + "'");
-            } else if (ClassHelper.long_TYPE.equals(ce.getType())) {
-                out.print("" + value + "L");
-            } else if (ClassHelper.float_TYPE.equals(ce.getType())) {
-                out.print("" + value + "f");
-            } else if (ClassHelper.double_TYPE.equals(ce.getType())) {
-                out.print("" + value + "d");
-            } else {
-                out.print(re.getText());
-            }
+        } else if (exp instanceof ConstantExpression) {
+            printValue(out, (ConstantExpression) exp);
+        } else {
+            out.print(exp.getText());
+        }
+    }
+
+    private void printValue(final PrintWriter out, final ConstantExpression 
ce) {
+        ClassNode type = ClassHelper.getUnwrapper(ce.getType());
+        if (type == ClassHelper.char_TYPE) {
+            out.print("'");
+            out.print(escapeSpecialChars(ce.getText().substring(0, 1)));
+            out.print("'");
+        } else if (type.equals(ClassHelper.STRING_TYPE)) {
+            out.print('"');
+            out.print(escapeSpecialChars(ce.getText()));
+            out.print('"');
+        } else if (type == ClassHelper.double_TYPE) {
+            out.print(ce.getText());
+            out.print('d');
+        } else if (type == ClassHelper.float_TYPE) {
+            out.print(ce.getText());
+            out.print('f');
+        } else if (type == ClassHelper.long_TYPE) {
+            out.print(ce.getText());
+            out.print('L');
         } else {
-            out.print(re.getText());
+            if (type != ClassHelper.int_TYPE && type != 
ClassHelper.boolean_TYPE && !type.equals(ClassHelper.BigDecimal_TYPE)) {
+                out.print('(');
+                printType(out, type);
+                out.print(')');
+            }
+            out.print(ce.getText());
         }
     }
 
@@ -776,9 +802,9 @@ public class JavaStubGenerator {
 
     private void printDefaultValue(final PrintWriter out, final ClassNode 
type) {
         if (type != null && !type.equals(ClassHelper.boolean_TYPE)) {
-            out.print("(");
+            out.print('(');
             printType(out, type);
-            out.print(")");
+            out.print(')');
         }
         if (type != null && ClassHelper.isPrimitiveType(type)) {
             if (type.equals(ClassHelper.boolean_TYPE)) {
diff --git a/src/test/groovy/bugs/Groovy5260Bug.groovy 
b/src/test/groovy/bugs/Groovy5260Bug.groovy
index 05be441129..d854ae1b20 100644
--- a/src/test/groovy/bugs/Groovy5260Bug.groovy
+++ b/src/test/groovy/bugs/Groovy5260Bug.groovy
@@ -18,22 +18,22 @@
  */
 package groovy.bugs
 
+import org.codehaus.groovy.ast.ClassHelper
 import org.codehaus.groovy.ast.ClassNode
 import org.codehaus.groovy.ast.CompileUnit
 import org.codehaus.groovy.ast.ModuleNode
 import org.codehaus.groovy.tools.javac.JavaStubGenerator
-import org.objectweb.asm.Opcodes
-import org.codehaus.groovy.ast.ClassHelper
-import org.codehaus.groovy.ast.FieldNode
-import org.codehaus.groovy.ast.expr.ConstantExpression
 
-class Groovy5260Bug extends GroovyTestCase implements Opcodes {
-    File outputDir
-    
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX
+
+final class Groovy5260Bug extends GroovyTestCase implements 
org.objectweb.asm.Opcodes {
+
+    private File outputDir
+
     @Override
     protected void setUp() {
         super.setUp()
-        outputDir = File.createTempFile("stub","groovy")
+        outputDir = File.createTempFile('stub', 'groovy')
         outputDir.mkdirs()
     }
 
@@ -43,77 +43,78 @@ class Groovy5260Bug extends GroovyTestCase implements 
Opcodes {
         outputDir.delete()
     }
 
-    private void checkConstant(ConstantExpression constant, String 
expectation) {
-        ClassNode cn = new ClassNode("Foo", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE)
-        ModuleNode module = new ModuleNode(new CompileUnit(null,null))
-        cn.setModule(module)
-        cn.addField(new FieldNode("constant", ACC_PUBLIC+ACC_STATIC+ACC_FINAL, 
constant.type, cn, constant))
-        StringWriter wrt = new StringWriter()
-        PrintWriter out = new PrintWriter(wrt)
-        JavaStubGenerator generator = new StringJavaStubGenerator(outputDir, 
out)
-        generator.generateClass(cn)
-
-        String stub = wrt.toString()
-        assert (stub =~ expectation)
+    void testIntConstant() {
+        checkConstant(ClassHelper.int_TYPE, 666, /final int constant = 666;/)
     }
 
     void testLongConstant() {
-        def constant = new ConstantExpression(666, true)
-        constant.type = ClassHelper.long_TYPE
-        checkConstant(constant, /\(long\) 666L/)
+        checkConstant(ClassHelper.long_TYPE, 666, 'final long constant = 
666L;')
     }
 
-    void testIntConstant() {
-        def constant = new ConstantExpression(666, true)
-        constant.type = ClassHelper.int_TYPE
-        checkConstant(constant, /\(int\) 666/)
+    void testFloatConstant() {
+        checkConstant(ClassHelper.float_TYPE, 3.14f, 'final float constant = 
3.14f;')
     }
 
     void testByteConstant() {
-        def constant = new ConstantExpression(123, true)
-        constant.type = ClassHelper.byte_TYPE
-        checkConstant(constant, /\(byte\) 123/)
+        checkConstant(ClassHelper.byte_TYPE, 123, /final byte constant = 
\(byte\)123;/)
     }
 
-    void testBooleanConstant() {
-        def constant = new ConstantExpression(false, true)
-        constant.type = ClassHelper.boolean_TYPE
-        // boolean type is not optimized yet
-        checkConstant(constant, /new java.lang.Boolean\(false\)/)
+    void testCharConstant() {
+        checkConstant(ClassHelper.char_TYPE, 'c', 'final char constant = 
\'c\';')
     }
 
     void testStringConstant() {
-        def constant = new ConstantExpression('foo', true)
-        constant.type = ClassHelper.STRING_TYPE
-        checkConstant(constant, /"foo"/)
+        checkConstant(ClassHelper.STRING_TYPE, 'foo', 'final java.lang.String 
constant = "foo";')
+    }
+
+    void testBooleanConstant() {
+        checkConstant(ClassHelper.boolean_TYPE, true, 'final boolean constant 
= true;')
+    }
+
+    
//--------------------------------------------------------------------------
+
+    private void checkConstant(ClassNode type, Object value, String 
expectation) {
+        def constant = constX(value, true)
+        constant.type = type
+
+        ClassNode cn = new ClassNode('script', ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE)
+        cn.addField('constant', ACC_PUBLIC | ACC_STATIC | ACC_FINAL, 
constant.type, constant)
+        ModuleNode module = new ModuleNode(new CompileUnit(null, null))
+        cn.setModule(module)
+
+        StringWriter wrt = new StringWriter()
+        PrintWriter out = new PrintWriter(wrt)
+        JavaStubGenerator generator = new StringJavaStubGenerator(outputDir, 
out)
+        generator.generateClass(cn)
+
+        String stub = wrt.toString()
+        assert (stub =~ expectation)
     }
 
     /**
      * Helper class, which generates code in a string instead of an output 
file.
      */
     private static final class StringJavaStubGenerator extends 
JavaStubGenerator {
+
         PrintWriter out
+
         StringJavaStubGenerator(File outFile, PrintWriter out) {
             super(outFile)
             this.out = out
         }
-        public void generateClass(ClassNode classNode) throws 
FileNotFoundException {
-
 
+        public void generateClass(ClassNode classNode) throws 
FileNotFoundException {
             try {
                 String packageName = classNode.getPackageName();
                 if (packageName != null) {
                     out.println("package " + packageName + ";\n");
                 }
-
                 super.printImports(out, classNode);
                 super.printClassContents(out, classNode);
-
             } finally {
                 try {
-                    out.close();
-                } catch (Exception e) {
-                    // ignore
+                    out.close()
+                } catch (ignore) {
                 }
             }
         }
diff --git 
a/src/test/org/codehaus/groovy/tools/stubgenerator/AnnotationDefaultValuesStubTest.groovy
 
b/src/test/org/codehaus/groovy/tools/stubgenerator/AnnotationDefaultValuesStubTest.groovy
index d4d038cff0..6b34a22c7e 100644
--- 
a/src/test/org/codehaus/groovy/tools/stubgenerator/AnnotationDefaultValuesStubTest.groovy
+++ 
b/src/test/org/codehaus/groovy/tools/stubgenerator/AnnotationDefaultValuesStubTest.groovy
@@ -21,7 +21,7 @@ package org.codehaus.groovy.tools.stubgenerator
 /**
  * Checks that default values from annotation definitions appear within stubs.
  */
-class AnnotationDefaultValuesStubTest extends StringSourcesStubTestCase {
+final class AnnotationDefaultValuesStubTest extends StringSourcesStubTestCase {
 
     Map<String, String> provideSources() {
         [
@@ -73,8 +73,8 @@ class AnnotationDefaultValuesStubTest extends 
StringSourcesStubTestCase {
         assert stubSource.contains('float f() default 3.0f;')
         assert stubSource.contains('double d() default 3.0d;')
         assert stubSource.contains('long l() default 3L;')
-        assert stubSource.contains('byte me() default 3;')
-        assert stubSource.contains('short s() default 3;')
+        assert stubSource.contains('byte me() default (byte)3;')
+        assert stubSource.contains('short s() default (short)3;')
         assert stubSource.contains("char c1() default 'A';")
         assert stubSource.contains("char c2() default 'A';")
         assert stubSource.contains("char c3() default 'A';")
diff --git 
a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10299.groovy 
b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10299.groovy
new file mode 100644
index 0000000000..991936477d
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10299.groovy
@@ -0,0 +1,46 @@
+/*
+ *  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 Groovy10299 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'Pogo.groovy': '''
+                class Pogo {
+                    public final boolean must_init
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new Pogo();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        String stub = stubJavaSourceFor('Pogo')
+        assert stub.contains('final boolean must_init = false;')
+    }
+}
diff --git 
a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10611.groovy 
b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10611.groovy
new file mode 100644
index 0000000000..f2cca7f3f6
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10611.groovy
@@ -0,0 +1,50 @@
+/*
+ *  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 Groovy10611 extends StringSourcesStubTestCase {
+
+    @Override
+    Map<String, String> provideSources() {
+        [
+            'C.groovy': '''
+                class C {
+                    public static final long LONG = 123_456
+                    public static final float FLOAT = 78.90
+                    public static final String STRING = 'x'+'y'
+                }
+            ''',
+            'Main.java': '''
+                public class Main {
+                    public static void main(String[] args) {
+                        new C();
+                    }
+                }
+            ''',
+        ]
+    }
+
+    @Override
+    void verifyStubs() {
+        String stub = stubJavaSourceFor('C')
+        assert stub.contains('final long LONG = 123456;');
+        assert stub.contains('final float FLOAT = 78.90;');
+        assert stub.contains('final java.lang.String STRING = "xy";');
+    }
+}

Reply via email to