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/05/01 18:54:34 UTC
[groovy] branch master updated: GROOVY-10611: stubgen: static final field with integer or decimal value
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 469e4d02ad GROOVY-10611: stubgen: static final field with integer or decimal value
469e4d02ad is described below
commit 469e4d02ad95d8dcf0366c778c58addd9b5677b0
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun May 1 13:47:14 2022 -0500
GROOVY-10611: stubgen: static final field with integer or decimal value
---
.../org/codehaus/groovy/classgen/Verifier.java | 6 +-
.../groovy/control/AnnotationConstantsVisitor.java | 49 +++++++--------
.../groovy/tools/javac/JavaStubGenerator.java | 71 +++++++++++++---------
.../groovy/tools/stubgenerator/Groovy10611.groovy | 50 +++++++++++++++
4 files changed, 117 insertions(+), 59 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 99f52fbc2a..6cd9d6528a 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -1136,7 +1136,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
ConstructorCallExpression specialCtorCall = getFirstIfSpecialConstructorCall(firstStatement);
// in case of this(...) let the other constructor initialize
- if (specialCtorCall != null && (specialCtorCall.isThisCall())) return;
+ if (specialCtorCall != null && specialCtorCall.isThisCall()) return;
boolean isEnum = node.isEnum();
List<Statement> statements = new ArrayList<>();
@@ -1283,8 +1283,8 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
expression
));
if (fieldNode.isStatic()) {
- // GROOVY-3311: pre-defined constants added by groovy compiler for numbers/characters should be
- // initialized first so that code dependent on it does not see their values as empty
+ // GROOVY-3311: pre-defined constants added by compiler for numbers/characters should be
+ // initialized first so that code dependent on them does not see their values as empty
Expression initialValueExpression = fieldNode.getInitialValueExpression();
Expression transformed = transformInlineConstants(initialValueExpression, fieldNode.getType());
if (transformed instanceof ConstantExpression) {
diff --git a/src/main/java/org/codehaus/groovy/control/AnnotationConstantsVisitor.java b/src/main/java/org/codehaus/groovy/control/AnnotationConstantsVisitor.java
index 9e48fcfa46..7de3e635a5 100644
--- a/src/main/java/org/codehaus/groovy/control/AnnotationConstantsVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/AnnotationConstantsVisitor.java
@@ -43,34 +43,36 @@ import static org.codehaus.groovy.ast.ClassHelper.isWrapperInteger;
import static org.codehaus.groovy.ast.ClassHelper.isWrapperShort;
/**
- * Visitor to resolve constants in annotation definitions.
+ * Resolves constants in annotation definitions.
*/
public class AnnotationConstantsVisitor extends ClassCodeVisitorSupport {
- private SourceUnit source;
- private boolean inAnnotationDef;
- public void visitClass(ClassNode node, SourceUnit source) {
- this.source = source;
- this.inAnnotationDef = node.isAnnotationDefinition();
- super.visitClass(node);
- this.inAnnotationDef = false;
- }
+ private boolean annotationDef;
+ private SourceUnit sourceUnit;
@Override
- protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) {
- if (!inAnnotationDef) return;
- visitStatement(node.getFirstStatement(), node.getReturnType());
+ protected SourceUnit getSourceUnit() {
+ return sourceUnit;
}
- private static void visitStatement(Statement statement, ClassNode returnType) {
- if (statement instanceof ReturnStatement) {
- // normal path
- ReturnStatement rs = (ReturnStatement) statement;
- rs.setExpression(transformConstantExpression(rs.getExpression(), returnType));
- } else if (statement instanceof ExpressionStatement) {
- // path for JavaStubGenerator
- ExpressionStatement es = (ExpressionStatement) statement;
- es.setExpression(transformConstantExpression(es.getExpression(), returnType));
+ public void visitClass(final ClassNode classNode, final SourceUnit sourceUnit) {
+ this.sourceUnit = sourceUnit;
+ this.annotationDef = classNode.isAnnotationDefinition();
+ super.visitClass(classNode);
+ this.annotationDef = false;
+ }
+
+ @Override
+ protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
+ if (annotationDef) {
+ Statement statement = node.getFirstStatement();
+ if (statement instanceof ReturnStatement) {
+ ReturnStatement rs = (ReturnStatement) statement;
+ rs.setExpression(transformConstantExpression(rs.getExpression(), node.getReturnType()));
+ } else if (statement instanceof ExpressionStatement) {
+ ExpressionStatement es = (ExpressionStatement) statement;
+ es.setExpression(transformConstantExpression(es.getExpression(), node.getReturnType()));
+ }
}
}
@@ -134,9 +136,4 @@ public class AnnotationConstantsVisitor extends ClassCodeVisitorSupport {
result.setSourcePosition(orig);
return result;
}
-
- @Override
- protected SourceUnit getSourceUnit() {
- return source;
- }
}
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 6509911596..31a51afbcf 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -83,6 +83,7 @@ import java.util.stream.Stream;
import static org.apache.groovy.ast.tools.ConstructorNodeUtils.getFirstIfSpecialConstructorCall;
import static org.codehaus.groovy.ast.ClassHelper.CLASS_Type;
import static org.codehaus.groovy.ast.ClassHelper.getUnwrapper;
+import static org.codehaus.groovy.ast.ClassHelper.isBigDecimalType;
import static org.codehaus.groovy.ast.ClassHelper.isCachedType;
import static org.codehaus.groovy.ast.ClassHelper.isClassType;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveBoolean;
@@ -100,6 +101,8 @@ import static org.codehaus.groovy.ast.ClassHelper.isStringType;
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;
@@ -251,38 +254,41 @@ public class JavaStubGenerator {
}
@Override
- public void visitProperty(PropertyNode node) {
+ public void visitProperty(PropertyNode pn) {
// GROOVY-8233 skip static properties for traits since they don't make the interface
- if (!node.isStatic() || !Traits.isTrait(node.getDeclaringClass())) {
- super.visitProperty(node);
+ if (!pn.isStatic() || !Traits.isTrait(pn.getDeclaringClass())) {
+ super.visitProperty(pn);
}
}
@Override
public void addCovariantMethods(ClassNode cn) {}
@Override
- protected void addInitialization(ClassNode node) {}
+ protected void addInitialization(ClassNode cn) {}
@Override
- protected void addPropertyMethod(MethodNode method) {
- doAddMethod(method);
+ protected void addInitialization(ClassNode cn, ConstructorNode c) {}
+ @Override
+ protected void addPropertyMethod(MethodNode mn) {
+ doAddMethod(mn);
}
@Override
- protected void addReturnIfNeeded(MethodNode node) {}
+ protected void addReturnIfNeeded(MethodNode mn) {}
+
@Override
- protected MethodNode addMethod(ClassNode node, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
+ protected MethodNode addMethod(ClassNode cn, boolean shouldBeSynthetic, String name, int modifiers, ClassNode returnType, Parameter[] parameters, ClassNode[] exceptions, Statement code) {
return doAddMethod(new MethodNode(name, modifiers, returnType, parameters, exceptions, code));
}
@Override
- protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) {
- if (code instanceof ExpressionStatement) {//GROOVY-4508
- Statement temp = code;
+ protected void addConstructor(Parameter[] params, ConstructorNode ctor, Statement code, ClassNode node) {
+ if (code instanceof ExpressionStatement) { //GROOVY-4508
+ Statement stmt = code;
code = new BlockStatement();
- ((BlockStatement) code).addStatement(temp);
+ ((BlockStatement) code).addStatement(stmt);
}
- ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code);
- ctrNode.setDeclaringClass(node);
- constructors.add(ctrNode);
+ ConstructorNode newCtor = new ConstructorNode(ctor.getModifiers(), params, ctor.getExceptions(), code);
+ newCtor.setDeclaringClass(node);
+ constructors.add(newCtor);
}
@Override
@@ -399,8 +405,7 @@ public class JavaStubGenerator {
private void printMethods(PrintWriter out, ClassNode classNode, boolean isEnum) {
if (!isEnum) printConstructors(out, classNode);
- @SuppressWarnings("unchecked")
- List<MethodNode> methods = (List) propertyMethods.clone();
+ List<MethodNode> methods = new ArrayList<>(propertyMethods);
methods.addAll(classNode.getMethods());
for (MethodNode method : methods) {
if (isEnum && method.isSynthetic()) {
@@ -527,16 +532,22 @@ public class JavaStubGenerator {
out.print(fieldNode.getName());
if (isInterface || fieldNode.isFinal()) {
out.print(" = ");
- Expression valueExpr = fieldNode.getInitialValueExpression();
- if (valueExpr instanceof ConstantExpression) {
- valueExpr = Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) valueExpr);
+ if (fieldNode.isStatic()) {
+ Expression value = fieldNode.getInitialValueExpression();
+ value = ExpressionUtils.transformInlineConstants(value, type);
+ if (value instanceof ConstantExpression) {
+ value = Verifier.transformToPrimitiveConstantIfPossible((ConstantExpression) value);
+ if ((type.equals(value.getType()) // GROOVY-10611: integer/decimal value
+ || (isLongCategory(type) && isPrimitiveInt(value.getType()))
+ || (isFloatingCategory(type) && isBigDecimalType(value.getType())))
+ && (isPrimitiveBoolean(type) || isStaticConstantInitializerType(type))) {
+ printValue(out, (ConstantExpression) value);
+ out.println(';');
+ return;
+ }
+ }
}
- if (valueExpr instanceof ConstantExpression
- && fieldNode.isStatic() && fieldNode.isFinal()
- && fieldNode.getType().equals(valueExpr.getType())
- && (isStaticConstantInitializerType(valueExpr.getType()) || isPrimitiveBoolean(valueExpr.getType()))) {
- printValue(out, (ConstantExpression) valueExpr);
- } else if (isPrimitiveType(type)) {
+ if (isPrimitiveType(type)) {
if (isPrimitiveBoolean(type)) {
out.print("false");
} else {
@@ -826,7 +837,7 @@ public class JavaStubGenerator {
out.print(ce.getText());
out.print('L');
} else {
- if (!isPrimitiveInt(type) && !isPrimitiveBoolean(type)) {
+ if (!isPrimitiveInt(type) && !isPrimitiveBoolean(type) && !isBigDecimalType(type)) {
out.print('(');
printType(out, type);
out.print(')');
@@ -835,10 +846,10 @@ public class JavaStubGenerator {
}
}
- private void printReturn(PrintWriter out, ClassNode retType) {
- if (!isPrimitiveVoid(retType)) {
+ private void printReturn(final PrintWriter out, final ClassNode type) {
+ if (!isPrimitiveVoid(type)) {
out.print("return ");
- printDefaultValue(out, retType);
+ printDefaultValue(out, type);
out.print(";");
}
}
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";');
+ }
+}