Skip to content

Commit b61a5e4

Browse files
committed
Fix for #1542: create a @Generated annotation for each delegate method
1 parent 9f3799e commit b61a5e4

File tree

11 files changed

+421
-234
lines changed

11 files changed

+421
-234
lines changed

base/org.eclipse.jdt.groovy.core/src/org/codehaus/jdt/groovy/internal/compiler/ast/GroovyCompilationUnitDeclaration.java

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2023 the original author or authors.
2+
* Copyright 2009-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,7 +15,9 @@
1515
*/
1616
package org.codehaus.jdt.groovy.internal.compiler.ast;
1717

18+
import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.isGenerated;
1819
import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
20+
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.plus;
1921
import static org.codehaus.groovy.runtime.StringGroovyMethods.find;
2022

2123
import java.io.PrintWriter;
@@ -1523,10 +1525,10 @@ private void createConstructorDeclarations(ClassNode classNode, List<AbstractMet
15231525
if (!variables.isEmpty()) constructorDecl.statements = createStatements(variables.values());
15241526
}
15251527
if (constructorNode.hasDefaultValue()) {
1526-
Annotation[] generated = createAnnotations(ClassHelper.make(groovy.transform.Generated.class));
15271528
for (Argument[] variantArgs : getVariantsAllowingForDefaulting(constructorNode.getParameters(), constructorDecl.arguments)) {
15281529
ConstructorDeclaration variantDecl = new ConstructorDeclaration(unitDeclaration.compilationResult);
1529-
variantDecl.annotations = constructorDecl.annotations == null ? generated : ArrayUtils.concat(constructorDecl.annotations, generated);
1530+
variantDecl.annotations = createAnnotations(isGenerated(constructorNode) ? constructorNode.getAnnotations()
1531+
: plus(constructorNode.getAnnotations(), new AnnotationNode(ClassHelper.make(groovy.transform.Generated.class))));
15301532
variantDecl.arguments = variantArgs;
15311533
variantDecl.bits = constructorDecl.bits;
15321534
variantDecl.javadoc = constructorDecl.javadoc;
@@ -1601,10 +1603,11 @@ private void createMethodDeclarations(ClassNode classNode, GroovyTypeDeclaration
16011603
}
16021604

16031605
if (methodNode.hasDefaultValue()) {
1604-
Annotation[] generated = createAnnotations(ClassHelper.make(groovy.transform.Generated.class));
16051606
for (Argument[] variantArgs : getVariantsAllowingForDefaulting(methodNode.getParameters(), methodDecl.arguments)) {
16061607
AbstractMethodDeclaration variantDecl = createMethodDeclaration(classNode, methodNode);
1607-
variantDecl.annotations = variantDecl.annotations == null ? generated : ArrayUtils.concat(variantDecl.annotations, generated);
1608+
variantDecl.annotations = ArrayUtils.concat(
1609+
variantDecl.annotations != null ? variantDecl.annotations : new Annotation[0],
1610+
createAnnotations(ClassHelper.make(groovy.transform.Generated.class)));
16081611
variantDecl.arguments = variantArgs;
16091612

16101613
variantDecl.declarationSourceStart = 0;

base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/core/GroovyPropertyTester.java

+9-12
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import org.codehaus.groovy.ast.Parameter;
2626
import org.eclipse.core.expressions.PropertyTester;
2727
import org.eclipse.core.runtime.Adapters;
28-
import org.eclipse.core.runtime.IAdaptable;
2928

3029
public class GroovyPropertyTester extends PropertyTester {
3130

@@ -50,17 +49,15 @@ private static boolean oneStringArray(Parameter[] p) {
5049

5150
@Override
5251
public boolean test(Object receiver, String property, Object[] arguments, Object expectedValue) {
53-
if (receiver instanceof IAdaptable) {
54-
ModuleNode node = Adapters.adapt(receiver, ModuleNode.class);
55-
if (node != null && !Boolean.TRUE.equals(node.getNodeMetaData("ParseError"))) {
56-
switch (property) {
57-
case "hasMain":
58-
return node.getClasses().stream().flatMap(cn -> cn.getDeclaredMethods("main").stream()).anyMatch(JAVA_MAIN);
59-
case "isScript":
60-
return !node.getStatementBlock().isEmpty() || (!node.getClasses().isEmpty() &&
61-
node.getClasses().get(0).getNameEnd() < 1 /* un-named */ && getGroovyVersion().getMajor() >= 5 &&
62-
node.getClasses().get(0).getDeclaredMethods("main").stream().anyMatch(JEP_445_MAIN.and(JAVA_MAIN.negate())));
63-
}
52+
ModuleNode node = Adapters.adapt(receiver, ModuleNode.class);
53+
if (node != null && !node.encounteredUnrecoverableError()) {
54+
switch (property) {
55+
case "hasMain":
56+
return node.getClasses().stream().flatMap(cn -> cn.getDeclaredMethods("main").stream()).anyMatch(JAVA_MAIN);
57+
case "isScript":
58+
return !node.getStatementBlock().isEmpty() || (!node.getClasses().isEmpty() &&
59+
node.getClasses().get(0).getNameEnd() < 1 /* un-named */ && getGroovyVersion().getMajor() >= 5 &&
60+
node.getClasses().get(0).getDeclaredMethods("main").stream().anyMatch(JEP_445_MAIN.and(JAVA_MAIN.negate())));
6461
}
6562
}
6663
return false;

base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/core/util/GroovyUtils.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.codehaus.groovy.ast.Parameter;
4747
import org.codehaus.groovy.ast.PropertyNode;
4848
import org.codehaus.groovy.ast.Variable;
49+
import org.codehaus.groovy.ast.expr.ConstantExpression;
4950
import org.codehaus.groovy.ast.expr.Expression;
5051
import org.codehaus.groovy.ast.expr.MethodCallExpression;
5152
import org.codehaus.groovy.ast.expr.TernaryExpression;
@@ -427,7 +428,7 @@ public static Expression getTraitFieldExpression(MethodCallExpression call) {
427428
} else if (objType.equals(ClassHelper.CLASS_Type) && asBoolean(objType.getGenericsTypes())) {
428429
objType = objType.getGenericsTypes()[0].getType(); // look for $static$self.T__name$get()
429430
}
430-
if (Traits.isTrait(objType)) {
431+
if (Traits.isTrait(objType) && call.getMethod() instanceof ConstantExpression) {
431432
Matcher m = Pattern.compile(".+__(\\p{javaJavaIdentifierPart}+)\\$[gs]et").matcher(call.getMethodAsString());
432433
if (m.matches()) {
433434
String fieldName = m.group(1);

base/org.eclipse.jdt.groovy.core/src/org/eclipse/jdt/groovy/search/TypeInferencingVisitorWithRequestor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -2071,14 +2071,14 @@ private boolean handleSimpleExpression(final Expression node) {
20712071
primaryType = null; // implicit-this calls are handled like free variables
20722072
isStatic = scope.isStatic();
20732073
} else {
2074-
isStatic = mce.getObjectExpression() instanceof ClassExpression || primaryType.equals(VariableScope.CLASS_CLASS_NODE);
2074+
isStatic = mce.getObjectExpression() instanceof ClassExpression || VariableScope.CLASS_CLASS_NODE.equals(primaryType);
20752075
}
20762076
} else if (enclosingNode instanceof PropertyExpression) {
20772077
PropertyExpression pe = (PropertyExpression) enclosingNode;
2078-
isStatic = pe.getObjectExpression() instanceof ClassExpression || primaryType.equals(VariableScope.CLASS_CLASS_NODE);
2078+
isStatic = pe.getObjectExpression() instanceof ClassExpression || VariableScope.CLASS_CLASS_NODE.equals(primaryType);
20792079
} else if (enclosingNode instanceof MethodPointerExpression) {
20802080
MethodPointerExpression mpe = (MethodPointerExpression) enclosingNode;
2081-
isStatic = mpe.getExpression() instanceof ClassExpression || primaryType.equals(VariableScope.CLASS_CLASS_NODE);
2081+
isStatic = mpe.getExpression() instanceof ClassExpression || VariableScope.CLASS_CLASS_NODE.equals(primaryType);
20822082
} else /*if (enclosingNode instanceof ImportNode)*/ {
20832083
isStatic = true;
20842084
}

ide-test/org.codehaus.groovy.alltests/src/org/codehaus/groovy/alltests/AllGroovyTests.groovy

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2023 the original author or authors.
2+
* Copyright 2009-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -94,6 +94,7 @@ import org.junit.runners.Suite
9494
// org.codehaus.groovy.eclipse.junit.tests
9595
org.codehaus.groovy.eclipse.junit.test.JUnit3TestFinderTests,
9696
org.codehaus.groovy.eclipse.junit.test.JUnit4TestFinderTests,
97+
org.codehaus.groovy.eclipse.junit.test.JUnit5TestFinderTests,
9798
org.codehaus.groovy.eclipse.junit.test.MainMethodFinderTests,
9899

99100
// org.codehaus.groovy.eclipse.quickfix.tests

ide-test/org.codehaus.groovy.eclipse.junit.test/src/org/codehaus/groovy/eclipse/junit/test/JUnit3TestFinderTests.groovy

+69-37
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2020 the original author or authors.
2+
* Copyright 2009-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,87 +15,119 @@
1515
*/
1616
package org.codehaus.groovy.eclipse.junit.test
1717

18+
import org.codehaus.groovy.eclipse.test.GroovyEclipseTestSuite
19+
import org.codehaus.groovy.eclipse.test.SynchronizationUtils
1820
import org.eclipse.jdt.core.ICompilationUnit
1921
import org.eclipse.jdt.core.IType
2022
import org.eclipse.jdt.internal.junit.launcher.JUnit3TestFinder
23+
import org.junit.Before
2124
import org.junit.Test
2225

23-
final class JUnit3TestFinderTests extends JUnitTestSuite {
26+
final class JUnit3TestFinderTests extends GroovyEclipseTestSuite {
2427

25-
private void assertTypeIsTest(boolean expected, ICompilationUnit unit, String typeName, String reasonText = '') {
28+
@Before
29+
void setUp() {
30+
addJUnit(3)
31+
}
32+
33+
private Set<IType> getAllTests() {
34+
Set<IType> testTypes = []
35+
SynchronizationUtils.waitForIndexingToComplete()
36+
new JUnit3TestFinder().findTestsInContainer(packageFragmentRoot, testTypes, null)
37+
return testTypes
38+
}
39+
40+
private boolean isTest(ICompilationUnit unit, String typeName = unit.types[0].elementName) {
2641
def type = unit.getType(typeName)
2742
assert type.exists() : "Groovy type $typeName should exist"
28-
assert new JUnit3TestFinder().isTest(type) == expected : "Groovy type $typeName should${expected ? '' : 'n\'t'} be a JUnit 3 test $reasonText"
43+
return new JUnit3TestFinder().isTest(type)
2944
}
3045

46+
//--------------------------------------------------------------------------
47+
3148
@Test
32-
void testFinderWithSuite() {
33-
def test = addGroovySource '''
34-
class A {
35-
static junit.framework.Test suite() throws Exception {}
49+
void testIsTest0() {
50+
def unit = addGroovySource '''
51+
class C {
52+
void test() { }
3653
}
37-
'''
54+
''', 'C', 'p'
55+
assert !isTest(unit)
56+
}
3857

39-
assertTypeIsTest(true, test, 'A')
58+
@Test
59+
void testIsTest1() {
60+
def unit = addGroovySource '''
61+
class C extends junit.framework.TestCase {
62+
void test() { }
63+
}
64+
''', 'C', 'p'
65+
assert isTest(unit)
4066
}
4167

4268
@Test
43-
void testFinderOfSubclass() {
44-
def base = addGroovySource '''
45-
abstract class TestBase extends junit.framework.TestCase {
69+
void testIsTest2() {
70+
def unit = addGroovySource '''
71+
class C {
72+
static junit.framework.Test suite() { }
4673
}
47-
'''
74+
''', 'C', 'p'
75+
assert isTest(unit)
76+
}
4877

49-
def test = addGroovySource '''
50-
class B extends TestBase {
78+
@Test
79+
void testIsTest3() {
80+
def unit = addGroovySource '''
81+
abstract class TestBase extends junit.framework.TestCase {
5182
}
52-
'''
83+
''', 'TestBase', 'p'
84+
assert !isTest(unit)
5385

54-
assertTypeIsTest(false, base, 'TestBase', '(it is abstract)')
55-
assertTypeIsTest(true, test, 'B')
86+
unit = addGroovySource '''
87+
class C extends TestBase {
88+
}
89+
''', 'C', 'p'
90+
assert isTest(unit)
5691
}
5792

5893
@Test
59-
void testFinderOfNonPublicSubclass() {
60-
def base = addGroovySource '''
94+
void testIsTest4() {
95+
def unit = addGroovySource '''
6196
abstract class TestBase extends junit.framework.TestCase {
6297
}
63-
'''
98+
''', 'TestBase', 'p'
99+
assert !isTest(unit)
64100

65-
def test = addGroovySource '''
101+
unit = addGroovySource '''
66102
@groovy.transform.PackageScope class C extends TestBase {
67103
}
68-
'''
69-
70-
assertTypeIsTest(false, base, 'TestBase', '(it is abstract)')
71-
assertTypeIsTest(true, test, 'C')
104+
''', 'C', 'p'
105+
assert isTest(unit)
72106
}
73107

108+
//
109+
74110
@Test
75-
void testFindAllTestSuites() {
111+
void testFindTests() {
76112
addGroovySource '''
77113
abstract class TestBase extends junit.framework.TestCase {
78114
}
79-
'''
80-
115+
''', 'TestBase', 'p'
81116
addGroovySource '''
82117
class X extends TestBase {
83118
}
84-
'''
85-
119+
''', 'X', 'p'
86120
addGroovySource '''
87121
class Y extends junit.framework.TestCase {
88122
}
89-
'''
90-
123+
''', 'Y', 'p'
91124
addGroovySource '''
92125
class Z {
93126
static junit.framework.Test suite() throws Exception {}
94127
}
95-
'''
128+
''', 'Z', 'p'
96129

97-
Set<IType> testTypes = []
98-
new JUnit3TestFinder().findTestsInContainer(packageFragmentRoot, testTypes, null)
130+
Set<IType> testTypes = allTests
99131

100132
assert testTypes.any { it.elementName == 'X' } : 'X should be a test type'
101133
assert testTypes.any { it.elementName == 'Y' } : 'Y should be a test type'

0 commit comments

Comments
 (0)