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 2021/06/02 21:33:39 UTC
[groovy] branch master updated: GROOVY-10122: stubgen: find type of
helper method in special ctor call
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 9a4df4d GROOVY-10122: stubgen: find type of helper method in special ctor call
9a4df4d is described below
commit 9a4df4dd29723e4073e59832c23d0308710039b0
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Jun 2 16:03:59 2021 -0500
GROOVY-10122: stubgen: find type of helper method in special ctor call
---
.../groovy/tools/javac/JavaStubGenerator.java | 78 +++++++++-------------
.../groovy/tools/stubgenerator/Groovy10122.groovy | 53 +++++++++++++++
2 files changed, 83 insertions(+), 48 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 1a41e7b..543c011 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -18,6 +18,7 @@
*/
package org.codehaus.groovy.tools.javac;
+import org.apache.groovy.ast.tools.ExpressionUtils;
import org.apache.groovy.io.StringBuilderWriter;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
@@ -40,6 +41,7 @@ import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.ast.expr.ListExpression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.expr.PropertyExpression;
import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.ast.stmt.BlockStatement;
@@ -88,6 +90,7 @@ import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveFloat;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveInt;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveLong;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveShort;
+import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveVoid;
import static org.codehaus.groovy.ast.ClassHelper.isStringType;
@@ -120,8 +123,6 @@ public class JavaStubGenerator {
dir.mkdirs();
}
-
- private static final int DEFAULT_BUFFER_SIZE = 8 * 1024; // 8K
public void generateClass(ClassNode classNode) throws FileNotFoundException {
// Only attempt to render our self if our super-class is resolved, else wait for it
if (requireSuperResolved && !classNode.getSuperClass().isResolved()) {
@@ -165,6 +166,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);
@@ -450,16 +453,7 @@ public class JavaStubGenerator {
}
private static boolean sameParameterTypes(final Parameter[] firstParams, final Parameter[] secondParams) {
- boolean sameParams = firstParams.length == secondParams.length;
- if (sameParams) {
- for (int i = 0; i < firstParams.length; i++) {
- if (!firstParams[i].getType().equals(secondParams[i].getType())) {
- sameParams = false;
- break;
- }
- }
- }
- return sameParams;
+ return org.codehaus.groovy.ast.tools.ParameterUtils.parametersEqual(firstParams, secondParams);
}
private void printConstructors(PrintWriter out, ClassNode classNode) {
@@ -642,73 +636,64 @@ public class JavaStubGenerator {
return true;
}
- private void printSpecialConstructorArgs(PrintWriter out, ConstructorNode node, ConstructorCallExpression constrCall) {
+ private void printSpecialConstructorArgs(final PrintWriter out, final ConstructorNode ctor, final ConstructorCallExpression ctorCall) {
// Select a constructor from our class, or super-class which is legal to call,
// then write out an invoke w/nulls using casts to avoid ambiguous calls
-
- Parameter[] params = selectAccessibleConstructorFromSuper(node);
+ Parameter[] params = selectAccessibleConstructorFromSuper(ctor);
if (params != null) {
out.print("super (");
-
for (int i = 0, n = params.length; i < n; i += 1) {
printDefaultValue(out, params[i].getType());
if (i + 1 < n) {
out.print(", ");
}
}
-
out.println(");");
return;
}
// Otherwise try the older method based on the constructor's call expression
- Expression arguments = constrCall.getArguments();
-
- if (constrCall.isSuperCall()) {
+ Expression arguments = ctorCall.getArguments();
+ if (ctorCall.isSuperCall()) {
out.print("super(");
} else {
out.print("this(");
}
-
- // Else try to render some arguments
if (arguments instanceof ArgumentListExpression) {
- ArgumentListExpression argumentListExpression = (ArgumentListExpression) arguments;
- List<Expression> args = argumentListExpression.getExpressions();
-
+ List<Expression> args = ((ArgumentListExpression) arguments).getExpressions();
+ int i = 0, n = args.size();
for (Expression arg : args) {
if (arg instanceof ConstantExpression) {
- ConstantExpression expression = (ConstantExpression) arg;
- Object o = expression.getValue();
-
- if (o instanceof String) {
+ Object value = ((ConstantExpression) arg).getValue();
+ if (value instanceof String) {
out.print("(String)null");
} else {
- out.print(expression.getText());
+ out.print(arg.getText());
}
} else {
- ClassNode type = getConstructorArgumentType(arg, node);
- printDefaultValue(out, type);
+ printDefaultValue(out, getConstructorArgumentType(arg, ctor));
}
-
- if (arg != args.get(args.size() - 1)) {
+ if (++i < n) {
out.print(", ");
}
}
}
-
out.println(");");
}
- private static ClassNode getConstructorArgumentType(Expression arg, ConstructorNode node) {
- if (!(arg instanceof VariableExpression)) return arg.getType();
- VariableExpression vexp = (VariableExpression) arg;
- String name = vexp.getName();
- for (Parameter param : node.getParameters()) {
- if (param.getName().equals(name)) {
- return param.getType();
+ private static ClassNode getConstructorArgumentType(final Expression arg, final ConstructorNode ctor) {
+ if (arg instanceof VariableExpression) {
+ return ((VariableExpression) arg).getAccessedVariable().getType();
+ }
+ if (arg instanceof MethodCallExpression) { // GROOVY-10122
+ MethodCallExpression mce = (MethodCallExpression) arg;
+ if (ExpressionUtils.isThisExpression(mce.getObjectExpression())) {
+ MethodNode mn = ctor.getDeclaringClass().tryFindPossibleMethod(mce.getMethodAsString(), mce.getArguments());
+ if (mn != null) return mn.getReturnType();
}
+ return null;
}
- return vexp.getType();
+ return arg.getType();
}
private void printMethod(PrintWriter out, ClassNode clazz, MethodNode methodNode) {
@@ -837,13 +822,12 @@ public class JavaStubGenerator {
}
private void printDefaultValue(final PrintWriter out, final ClassNode type) {
- if (!isPrimitiveBoolean(type)) {
+ if (type != null && !isPrimitiveBoolean(type)) {
out.print("(");
printType(out, type);
out.print(")");
}
-
- if (ClassHelper.isPrimitiveType(type)) {
+ if (type != null && isPrimitiveType(type)) {
if (isPrimitiveBoolean(type)) {
out.print("false");
} else {
@@ -1077,14 +1061,12 @@ public class JavaStubGenerator {
private static String escapeSpecialChars(String value) {
return InvokerHelper.escapeBackslashes(value).replace("\"", "\\\"");
-
}
private static boolean isInterfaceOrTrait(ClassNode cn) {
return cn.isInterface() || Traits.isTrait(cn);
}
-
private final Set<JavaFileObject> javaStubCompilationUnitSet = new HashSet<>();
public Set<JavaFileObject> getJavaStubCompilationUnitSet() {
diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122.groovy
new file mode 100644
index 0000000..0ba0ba4
--- /dev/null
+++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy10122.groovy
@@ -0,0 +1,53 @@
+/*
+ * 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 Groovy10122 extends StringSourcesStubTestCase {
+
+ @Override
+ Map<String, String> provideSources() {
+ [
+ 'A.java': '''
+ public abstract class A {
+ A(Integer i) {
+ }
+ }
+ ''',
+ 'C.groovy': '''
+ class C extends A {
+ C() { super(m()) }
+ static Integer m() { 42 }
+ }
+ ''',
+ '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.Integer)null'
+ }
+}