Skip to content

Commit 183554e

Browse files
committed
GROOVY-8433
1 parent e30b62e commit 183554e

File tree

5 files changed

+372
-15
lines changed

5 files changed

+372
-15
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/CategoryTests.java

+36-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2019 the original author or authors.
2+
* Copyright 2009-2022 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.
@@ -27,7 +27,7 @@ public final class CategoryTests extends GroovyCompilerTestSuite {
2727
public void testCategory0() {
2828
//@formatter:off
2929
String[] sources = {
30-
"Demo.groovy",
30+
"Main.groovy",
3131
"use(NumberCategory) {\n" +
3232
" def dist = 300.meters\n" +
3333
" \n" +
@@ -58,7 +58,7 @@ public void testCategory0() {
5858
public void testCategory1() {
5959
//@formatter:off
6060
String[] sources = {
61-
"Demo.groovy",
61+
"Main.groovy",
6262
"use(NumberCategory) {\n" +
6363
" def dist = 300.meters\n" +
6464
" \n" +
@@ -89,7 +89,7 @@ public void testCategory1() {
8989
public void testCategory2() {
9090
//@formatter:off
9191
String[] sources = {
92-
"Foo.groovy",
92+
"Main.groovy",
9393
"assert new Plane().fly() ==\n" +
9494
" \"I'm the Concorde and I fly!\"\n" +
9595
"assert new Submarine().dive() ==\n" +
@@ -139,11 +139,35 @@ public void testCategory2() {
139139
runConformTest(sources, "I'm the James Bond's vehicle and I dive!");
140140
}
141141

142+
@Test
143+
public void testCategory8433() {
144+
//@formatter:off
145+
String[] sources = {
146+
"Main.groovy",
147+
"use(NumberCategory) {\n" +
148+
" print 1.something()\n" +
149+
"}\n",
150+
151+
"NumberCategory.groovy",
152+
"@Category(Number) class NumberCategory {\n" +
153+
" def something() {\n" +
154+
" String variable = 'works'\n" +
155+
" new Object() {\n" + // cast exception due to implicit first param "this"
156+
" String toString() { variable }\n" +
157+
" }\n" +
158+
" }\n" +
159+
"}\n",
160+
};
161+
//@formatter:on
162+
163+
runConformTest(sources, "works");
164+
}
165+
142166
@Test // not a great test, needs work
143167
public void testCategory_STS3822() {
144168
//@formatter:off
145169
String[] sources = {
146-
"bad.groovy",
170+
"Bad.groovy",
147171
"@Category(C.class) \n" +
148172
"@ScriptMixin(C.class)\n" +
149173
"class Bad {\n" +
@@ -156,37 +180,37 @@ public void testCategory_STS3822() {
156180

157181
runNegativeTest(sources,
158182
"----------\n" +
159-
"1. ERROR in bad.groovy (at line 1)\n" +
183+
"1. ERROR in Bad.groovy (at line 1)\n" +
160184
"\t@Category(C.class) \n" +
161185
"\t^^^^^^^^^^^^^^^^^^\n" +
162186
"Groovy:@groovy.lang.Category must define \'value\' which is the class to apply this category to\n" +
163187
"----------\n" +
164-
"2. ERROR in bad.groovy (at line 1)\n" +
188+
"2. ERROR in Bad.groovy (at line 1)\n" +
165189
"\t@Category(C.class) \n" +
166190
"\t ^\n" +
167191
"Groovy:unable to find class \'C.class\' for annotation attribute constant\n" +
168192
"----------\n" +
169-
"3. ERROR in bad.groovy (at line 1)\n" +
193+
"3. ERROR in Bad.groovy (at line 1)\n" +
170194
"\t@Category(C.class) \n" +
171195
"\t ^^^^^^^\n" +
172196
"Groovy:Only classes and closures can be used for attribute \'value\' in @groovy.lang.Category\n" +
173197
"----------\n" +
174-
"4. ERROR in bad.groovy (at line 2)\n" +
198+
"4. ERROR in Bad.groovy (at line 2)\n" +
175199
"\t@ScriptMixin(C.class)\n" +
176200
"\t^^^^^^^^^^^^\n" +
177201
"Groovy:class ScriptMixin is not an annotation in @ScriptMixin\n" +
178202
"----------\n" +
179-
"5. ERROR in bad.groovy (at line 2)\n" +
203+
"5. ERROR in Bad.groovy (at line 2)\n" +
180204
"\t@ScriptMixin(C.class)\n" +
181205
"\t ^^^^^^^^^^^\n" +
182206
"Groovy:unable to resolve class ScriptMixin for annotation\n" +
183207
"----------\n" +
184-
"6. ERROR in bad.groovy (at line 2)\n" +
208+
"6. ERROR in Bad.groovy (at line 2)\n" +
185209
"\t@ScriptMixin(C.class)\n" +
186210
"\t ^\n" +
187211
"Groovy:unable to find class \'C.class\' for annotation attribute constant\n" +
188212
"----------\n" +
189-
"7. ERROR in bad.groovy (at line 4)\n" +
213+
"7. ERROR in Bad.groovy (at line 4)\n" +
190214
"\t@Override\n" +
191215
"\t^^^^^^^^^\n" +
192216
"Groovy:Method \'toString\' from class \'Bad\' does not override method from its superclass or interfaces but is annotated with @Override.\n" +

base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/InnerClassVisitor.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public void visitConstructorCallExpression(ConstructorCallExpression call) {
220220
innerClass.addConstructor(ACC_SYNTHETIC, parameters.toArray(Parameter.EMPTY_ARRAY), ClassNode.EMPTY_ARRAY, block);
221221
}
222222

223-
private boolean isStatic(InnerClassNode innerClass, VariableScope scope, final ConstructorCallExpression call) {
223+
private boolean isStatic(final ClassNode innerClass, final VariableScope scope, final ConstructorCallExpression call) {
224224
boolean isStatic = innerClass.isStaticClass();
225225
if (!isStatic) {
226226
if (currentMethod != null) {
@@ -255,6 +255,10 @@ public void visitConstructorCallExpression(ConstructorCallExpression cce) {
255255
isStatic = currentField.isStatic();
256256
}
257257
}
258+
// GRECLIPSE add -- GROOVY-8433: Category transform applies static
259+
isStatic = isStatic || innerClass.getOuterClass().getAnnotations().stream()
260+
.anyMatch(a -> a.getClassNode().getName().equals("groovy.lang.Category"));
261+
// GRECLIPSE end
258262
return isStatic;
259263
}
260264

base/org.codehaus.groovy30/src/org/codehaus/groovy/classgen/InnerClassVisitor.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ public void visitConstructorCallExpression(ConstructorCallExpression call) {
225225
innerClass.addConstructor(ACC_SYNTHETIC, parameters.toArray(Parameter.EMPTY_ARRAY), ClassNode.EMPTY_ARRAY, block);
226226
}
227227

228-
private boolean isStatic(InnerClassNode innerClass, VariableScope scope, ConstructorCallExpression call) {
228+
private boolean isStatic(final ClassNode innerClass, final VariableScope scope, final ConstructorCallExpression call) {
229229
boolean isStatic = innerClass.isStaticClass();
230230
if (!isStatic) {
231231
if (currentMethod != null) {
@@ -253,6 +253,10 @@ public void visitConstructorCallExpression(ConstructorCallExpression cce) {
253253
isStatic = currentField.isStatic();
254254
}
255255
}
256+
// GRECLIPSE add -- GROOVY-8433: Category transform applies static
257+
isStatic = isStatic || innerClass.getOuterClass().getAnnotations().stream()
258+
.anyMatch(a -> a.getClassNode().getName().equals("groovy.lang.Category"));
259+
// GRECLIPSE end
256260
return isStatic;
257261
}
258262

base/org.codehaus.groovy40/.checkstyle

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<file-match-pattern match-pattern="groovy/ast/expr/RangeExpression.java" include-pattern="false" />
3636
<file-match-pattern match-pattern="groovy/ast/expr/(Static)?MethodCallExpression.java" include-pattern="false" />
3737
<file-match-pattern match-pattern="groovy/ast/tools/(Expression|Generics)Utils.java" include-pattern="false" />
38-
<file-match-pattern match-pattern="groovy/classgen/(Annotation|Enum|VariableScope)Visitor.java" include-pattern="false" />
38+
<file-match-pattern match-pattern="groovy/classgen/(Annotation|Enum|InnerClass|VariableScope)Visitor.java" include-pattern="false" />
3939
<file-match-pattern match-pattern="groovy/classgen/(Extended)?Verifier.java" include-pattern="false" />
4040
<file-match-pattern match-pattern="groovy/classgen/asm/WriterController.java" include-pattern="false" />
4141
<file-match-pattern match-pattern="groovy/classgen/asm/sc/StaticInvocationWriter.java" include-pattern="false" />

0 commit comments

Comments
 (0)