This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
new 9d0d67197e GROOVY-5106, GROOVY-11508: re-implement trait with new type
args warning
9d0d67197e is described below
commit 9d0d67197eb8cd333e973b08d4d0f4b7f3f41475
Author: Eric Milles <[email protected]>
AuthorDate: Fri Oct 25 11:29:38 2024 -0500
GROOVY-5106, GROOVY-11508: re-implement trait with new type args warning
(closes #2117)
---
.../org/codehaus/groovy/classgen/Verifier.java | 12 ++-
.../codehaus/groovy/control/ResolveVisitor.java | 85 +++++++++++++---------
.../groovy/transform/traitx/Groovy11508.groovy} | 31 ++++----
.../groovy/transform/traitx/Groovy8864.groovy} | 19 +++--
4 files changed, 87 insertions(+), 60 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 248bec3c98..19a36ee116 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -363,9 +363,15 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
for (ClassNode t : set) { // find match and check
generics
if (t.equals(in)) {
String one = in.toString(false), two =
t.toString(false);
- if (!one.equals(two))
- throw new RuntimeParserException("The
interface " + in.getNameWithoutPackage() +
- " cannot be implemented more than
once with different arguments: " + one + " and " + two, cn);
+ if (!one.equals(two)) {
+ if (Traits.isTrait(in)) { //
GROOVY-11508
+
cn.getModule().getContext().addWarning("The trait " +
in.getNameWithoutPackage() +
+ " is implemented more than
once with different arguments: " + one + " and " + two, cn);
+ } else {
+ throw new
RuntimeParserException("The interface " + in.getNameWithoutPackage() +
+ " cannot be implemented more
than once with different arguments: " + one + " and " + two, cn);
+ }
+ }
break;
}
}
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index 3ddc87b547..1af01a97d9 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -263,25 +263,61 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
return source;
}
+ @Override
+ public void visitField(final FieldNode node) {
+ Map<GenericsTypeName, GenericsType> oldNames = genericParameterNames;
+ if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
+ genericParameterNames = Collections.emptyMap();
+ }
+
+ if (!fieldTypesChecked.contains(node)) {
+ resolveOrFail(node.getType(), node);
+ }
+ super.visitField(node);
+
+ genericParameterNames = oldNames;
+ }
+
+ @Override
+ public void visitProperty(final PropertyNode node) {
+ Map<GenericsTypeName, GenericsType> oldNames = genericParameterNames;
+ if (!canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())) {
+ genericParameterNames = Collections.emptyMap();
+ }
+
+ resolveOrFail(node.getType(), node);
+ fieldTypesChecked.add(node.getField());
+
+ super.visitProperty(node);
+
+ genericParameterNames = oldNames;
+ }
+
+ private static boolean canSeeTypeVars(final int mods, final ClassNode
node) {
+ return !Modifier.isStatic(mods) || Traits.isTrait(node); //
GROOVY-8864, GROOVY-11508
+ }
+
@Override
protected void visitConstructorOrMethod(final MethodNode node, final
boolean isConstructor) {
VariableScope oldScope = currentScope;
currentScope = node.getVariableScope();
Map<GenericsTypeName, GenericsType> oldNames = genericParameterNames;
- genericParameterNames = node.isStatic() &&
!Traits.isTrait(node.getDeclaringClass())
- ? new HashMap<>() : new HashMap<>(genericParameterNames);
+ genericParameterNames =
+ canSeeTypeVars(node.getModifiers(), node.getDeclaringClass())
+ ? new HashMap<>(genericParameterNames) : new HashMap<>();
resolveGenericsHeader(node.getGenericsTypes());
+ resolveOrFail(node.getReturnType(), node);
for (Parameter p : node.getParameters()) {
p.setInitialExpression(transform(p.getInitialExpression()));
- resolveOrFail(p.getType(), p.getType());
+ ClassNode t = p.getType();
+ resolveOrFail(t, t);
visitAnnotations(p);
}
- resolveOrFail(node.getReturnType(), node);
if (node.getExceptions() != null) {
for (ClassNode t : node.getExceptions()) {
- resolveOrFail(t, node);
+ resolveOrFail(t, t);
}
}
@@ -289,6 +325,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
MethodNode oldCurrentMethod = currentMethod;
currentMethod = node;
+
super.visitConstructorOrMethod(node, isConstructor);
currentMethod = oldCurrentMethod;
@@ -296,30 +333,6 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
currentScope = oldScope;
}
- @Override
- public void visitField(final FieldNode node) {
- ClassNode t = node.getType();
- if (!fieldTypesChecked.contains(node)) {
- resolveOrFail(t, node);
- }
- super.visitField(node);
- }
-
- @Override
- public void visitProperty(final PropertyNode node) {
- Map<GenericsTypeName, GenericsType> oldPNames = genericParameterNames;
- if (node.isStatic() && !Traits.isTrait(node.getDeclaringClass())) {
- genericParameterNames = new HashMap<>();
- }
-
- ClassNode t = node.getType();
- resolveOrFail(t, node);
- super.visitProperty(node);
- fieldTypesChecked.add(node.getField());
-
- genericParameterNames = oldPNames;
- }
-
private void resolveOrFail(final ClassNode type, final ASTNode node) {
resolveOrFail(type, "", node);
}
@@ -1098,14 +1111,14 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
protected Expression transformClosureExpression(final ClosureExpression
ce) {
boolean oldInClosure = inClosure;
inClosure = true;
- for (Parameter para : getParametersSafe(ce)) {
- ClassNode t = para.getType();
- resolveOrFail(t, ce);
- visitAnnotations(para);
- if (para.hasInitialExpression()) {
-
para.setInitialExpression(transform(para.getInitialExpression()));
+ for (Parameter p : getParametersSafe(ce)) {
+ ClassNode t = p.getType();
+ resolveOrFail(t, t);
+ visitAnnotations(p);
+ if (p.hasInitialExpression()) {
+ p.setInitialExpression(transform(p.getInitialExpression()));
}
- visitAnnotations(para);
+ visitAnnotations(p);
}
Statement code = ce.getCode();
diff --git a/src/test/groovy/bugs/Groovy8864Bug.groovy
b/src/test/org/codehaus/groovy/transform/traitx/Groovy11508.groovy
similarity index 62%
copy from src/test/groovy/bugs/Groovy8864Bug.groovy
copy to src/test/org/codehaus/groovy/transform/traitx/Groovy11508.groovy
index 27d804f23c..ddf72729e5 100644
--- a/src/test/groovy/bugs/Groovy8864Bug.groovy
+++ b/src/test/org/codehaus/groovy/transform/traitx/Groovy11508.groovy
@@ -16,25 +16,30 @@
* specific language governing permissions and limitations
* under the License.
*/
-package groovy.bugs
+package org.codehaus.groovy.transform.traitx
-import groovy.test.GroovyTestCase
+import org.junit.Test
-class Groovy8864Bug extends GroovyTestCase {
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy11508 {
+ @Test
void testGenericsAppliedToStaticMethodsForTraits() {
assertScript '''
- trait Foo<T> {
- static T INSTANCE
- static T get(T arg) {
- null
- }
+ trait T<U> {
+ static U getYou() {
+ }
+ }
+ class C implements T<C> {
}
+ class D extends C implements T<D> {
+ }
+
+ C c = C.you
+ D d = D.you
- class Bar implements Foo<Bar> {}
- assert Bar.getMethod("get", [Bar] as Class[]).returnType == Bar
- assert Bar.getDeclaredField("Foo__INSTANCE").type == Bar
- assert Bar.getMethod("setINSTANCE", [Bar] as Class[])
- assert Bar.getMethod("getINSTANCE").returnType == Bar
+ assert C.getMethod('getYou').returnType == C
+ assert D.getMethod('getYou').returnType == D
'''
}
}
diff --git a/src/test/groovy/bugs/Groovy8864Bug.groovy
b/src/test/org/codehaus/groovy/transform/traitx/Groovy8864.groovy
similarity index 78%
rename from src/test/groovy/bugs/Groovy8864Bug.groovy
rename to src/test/org/codehaus/groovy/transform/traitx/Groovy8864.groovy
index 27d804f23c..de702ef144 100644
--- a/src/test/groovy/bugs/Groovy8864Bug.groovy
+++ b/src/test/org/codehaus/groovy/transform/traitx/Groovy8864.groovy
@@ -16,24 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
-package groovy.bugs
+package org.codehaus.groovy.transform.traitx
-import groovy.test.GroovyTestCase
+import org.junit.Test
-class Groovy8864Bug extends GroovyTestCase {
+import static groovy.test.GroovyAssert.assertScript
+
+final class Groovy8864 {
+ @Test
void testGenericsAppliedToStaticMethodsForTraits() {
assertScript '''
trait Foo<T> {
static T INSTANCE
- static T get(T arg) {
- null
- }
+ static T get(T t) {
+ }
+ }
+ class Bar implements Foo<Bar> {
}
- class Bar implements Foo<Bar> {}
assert Bar.getMethod("get", [Bar] as Class[]).returnType == Bar
assert Bar.getDeclaredField("Foo__INSTANCE").type == Bar
- assert Bar.getMethod("setINSTANCE", [Bar] as Class[])
+ assert Bar.getMethod("setINSTANCE", new Class[]{Bar})
assert Bar.getMethod("getINSTANCE").returnType == Bar
'''
}