Skip to content

Commit 8144a70

Browse files
committed
GROOVY-5736, GROOVY-7439
1 parent 7b09099 commit 8144a70

9 files changed

Lines changed: 241 additions & 123 deletions

File tree

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/basic/TraitsTests.java

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,24 +1783,21 @@ public void testTraits7288() {
17831783
String[] sources = {
17841784
"Script.groovy",
17851785
"trait T {\n" +
1786-
" String STATIC = 'const'\n" +
1787-
" def so() {\n" +
1788-
" print \"STATIC=${STATIC}\"\n" +
1789-
" }\n" +
1786+
" final foo = 'bar'\n" +
17901787
"}\n" +
1791-
"class C implements T {\n" +
1788+
"class D implements T {\n" +
17921789
" def m() {\n" +
17931790
" print 'works'\n" +
17941791
" }\n" +
17951792
"}\n" +
1796-
"class D {\n" + // The class 'D' must be declared abstract or the method 'java.lang.String T__STATIC$get()' must be implemented
1797-
" @Delegate C delegates = new C()\n" +
1793+
"class C {\n" + // The class must be declared abstract or the method 'java.lang.String T__foo$get()' must be implemented
1794+
" @Delegate D delegates = new D()\n" +
17981795
"}\n" +
1799-
"new D().m()\n",
1796+
"new C().m()\n",
18001797
};
18011798
//@formatter:on
18021799

1803-
runConformTest(sources, "");
1800+
runConformTest(sources, "works");
18041801
}
18051802

18061803
@Test
@@ -1856,34 +1853,6 @@ public void testTraits7399() {
18561853
runConformTest(sources, "");
18571854
}
18581855

1859-
@Test @Ignore
1860-
public void testTraits7439() {
1861-
vmArguments = new String[] {"-Djava.system.class.loader=org.codehaus.groovy.tools.RootLoader"};
1862-
1863-
//@formatter:off
1864-
String[] sources = {
1865-
"Script.groovy",
1866-
"@Grab('org.slf4j:slf4j-simple:1.7.30')\n" +
1867-
"import groovy.transform.CompileStatic\n" +
1868-
"import groovy.util.logging.Slf4j\n" +
1869-
"\n" +
1870-
"@CompileStatic @Slf4j('LOG')\n" +
1871-
"trait T {\n" +
1872-
// " static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(this)\n" +
1873-
// " static org.slf4j.Logger getLOG() { ??? }\n" +
1874-
" void m() {\n" +
1875-
" LOG.debug('works')\n" + // Cannot find matching method java.lang.Object#debug(java.lang.String)
1876-
" }\n" +
1877-
"}\n" +
1878-
"class C implements T {\n" +
1879-
"}\n" +
1880-
"new C().m()\n",
1881-
};
1882-
//@formatter:on
1883-
1884-
runConformTest(sources, "works");
1885-
}
1886-
18871856
@Test
18881857
public void testTraits7456() {
18891858
//@formatter:off
@@ -2133,7 +2102,7 @@ public void testTraits8587() {
21332102
};
21342103
//@formatter:on
21352104

2136-
runConformTest(sources, "");
2105+
runConformTest(sources, "A");
21372106
}
21382107

21392108
@Test
Lines changed: 143 additions & 24 deletions
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-2021 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,6 +15,9 @@
1515
*/
1616
package org.eclipse.jdt.groovy.core.tests.xform;
1717

18+
import static org.eclipse.jdt.groovy.core.tests.GroovyBundle.isAtLeastGroovy;
19+
import static org.junit.Assume.assumeTrue;
20+
1821
import org.eclipse.jdt.groovy.core.tests.basic.GroovyCompilerTestSuite;
1922
import org.junit.Test;
2023

@@ -23,98 +26,214 @@
2326
*/
2427
public final class LoggingTests extends GroovyCompilerTestSuite {
2528

29+
// TODO: Test category and name attributes
30+
2631
@Test
2732
public void testCommons() {
2833
//@formatter:off
2934
String[] sources = {
3035
"CommonsExample.groovy",
3136
"import groovy.util.logging.*\n" +
3237
"@Commons\n" +
33-
"class CommonsExample {\n" +
34-
" def meth() {\n" +
38+
"class C {\n" +
39+
" void test() {\n" +
3540
" log.info('yay!')\n" +
3641
" }\n" +
37-
"}\n",
42+
"}\n" +
43+
"new C().test()\n",
3844
};
3945
//@formatter:on
4046

41-
runNegativeTest(sources, "");
47+
vmArguments = new String[] {"-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog"};
48+
addRuntimeLibrary("commons-logging:commons-logging:1.2");
49+
runConformTest(sources, "", "[INFO] C - yay!");
4250
}
4351

4452
@Test
4553
public void testLog() {
54+
if (Float.parseFloat(System.getProperty("java.specification.version")) > 8)
55+
vmArguments = new String[] {"--add-opens", "java.logging/java.util.logging=ALL-UNNAMED"};
56+
4657
//@formatter:off
4758
String[] sources = {
4859
"LogExample.groovy",
4960
"import groovy.util.logging.*\n" +
61+
"import java.util.logging.*\n" +
5062
"@Log\n" +
51-
"class LogExample {\n" +
52-
//" static void main(args) {\n" +
53-
//" new LogExample().meth()\n" +
54-
//" }\n" +
55-
" def meth() {\n" +
63+
"class C {\n" +
64+
" void test() {\n" +
65+
" log.addHandler(new ConsoleHandler(formatter:{ record -> \"$record.level: $record.message\".toString() }))\n" +
66+
" log.useParentHandlers = false\n" +
5667
" log.info('yay!')\n" +
5768
" }\n" +
58-
"}\n",
69+
"}\n" +
70+
"new C().test()\n",
5971
};
6072
//@formatter:on
6173

62-
runNegativeTest(sources, ""); // TODO: Test the output produced
74+
runConformTest(sources, "", "INFO: yay!");
6375
}
6476

65-
// TODO: Test category and name attributes
66-
6777
@Test
6878
public void testLog4j() {
79+
assumeTrue(Boolean.getBoolean("eclipse.pde.launch"));
80+
6981
//@formatter:off
7082
String[] sources = {
7183
"Log4jExample.groovy",
84+
"import static org.apache.log4j.BasicConfigurator.configure\n" +
7285
"import groovy.util.logging.*\n" +
7386
"@Log4j\n" +
74-
"class Log4jExample {\n" +
75-
" def meth() {\n" +
87+
"class C {\n" +
88+
" void test() {\n" +
7689
" log.info('yay!')\n" +
7790
" }\n" +
78-
"}\n",
91+
"}\n" +
92+
"configure()\n" +
93+
"new C().test()\n",
7994
};
8095
//@formatter:on
8196

82-
runNegativeTest(sources, "");
97+
addRuntimeLibrary("log4j:log4j:1.2.17");
98+
runConformTest(sources, "0 [Thread-0] INFO C - yay!");
8399
}
84100

85101
@Test
86102
public void testLog4j2() {
103+
assumeTrue(Boolean.getBoolean("eclipse.pde.launch"));
104+
87105
//@formatter:off
88106
String[] sources = {
89107
"Log4j2Example.groovy",
90108
"import groovy.util.logging.*\n" +
91109
"@Log4j2\n" +
92-
"class Log4j2Example {\n" +
93-
" def meth() {\n" +
110+
"class C {\n" +
111+
" void test() {\n" +
94112
" log.info('yay!')\n" +
95113
" }\n" +
114+
"}\n" +
115+
"new C().test()\n",
116+
117+
"T.groovy",
118+
"class T implements org.apache.logging.log4j.core.util.Clock {\n" +
119+
" long currentTimeMillis() { 0 }\n" +
96120
"}\n",
97121
};
98122
//@formatter:on
99123

100-
runNegativeTest(sources, "");
124+
addRuntimeLibrary("org.apache.logging.log4j:log4j-api:2.17.0", "org.apache.logging.log4j:log4j-core:2.17.0");
125+
vmArguments = new String[] {"-Dorg.apache.logging.log4j.level=INFO", "-Dlog4j2.clock=T"};
126+
runConformTest(sources, "[main] INFO C - yay!");
101127
}
102128

103129
@Test
104130
public void testSlf4j() {
131+
assumeTrue(Boolean.getBoolean("eclipse.pde.launch"));
132+
105133
//@formatter:off
106134
String[] sources = {
107135
"Slf4jExample.groovy",
108136
"import groovy.util.logging.*\n" +
109137
"@Slf4j\n" +
110-
"class Slf4jExample {\n" +
111-
" def meth() {\n" +
138+
"class C {\n" +
139+
" void test() {\n" +
112140
" log.info('yay!')\n" +
113141
" }\n" +
142+
"}\n" +
143+
"new C().test()\n",
144+
};
145+
//@formatter:on
146+
147+
addRuntimeLibrary("org.slf4j:slf4j-simple:1.7.32");
148+
runConformTest(sources, "", "[Thread-0] INFO C - yay!");
149+
}
150+
151+
@Test
152+
public void testSlf4j_5736() {
153+
assumeTrue(Boolean.getBoolean("eclipse.pde.launch"));
154+
155+
//@formatter:off
156+
String[] sources = {
157+
"Groovy5736.groovy",
158+
"import groovy.transform.CompileStatic\n" +
159+
"import groovy.util.logging.Slf4j\n" +
160+
"@CompileStatic @Slf4j('LOG')\n" +
161+
"class C {\n" +
162+
" void test() {\n" +
163+
" LOG.info('yay!')\n" +
164+
" }\n" +
165+
"}\n" +
166+
"new C().test()\n",
167+
};
168+
//@formatter:on
169+
170+
addRuntimeLibrary("org.slf4j:slf4j-simple:1.7.32");
171+
runConformTest(sources, "", "[Thread-0] INFO C - yay!");
172+
}
173+
174+
@Test
175+
public void testSlf4j_7439() {
176+
assumeTrue(Boolean.getBoolean("eclipse.pde.launch") && isAtLeastGroovy(40));
177+
178+
//@formatter:off
179+
String[] sources = {
180+
"Groovy7439.groovy",
181+
"import groovy.transform.CompileStatic\n" +
182+
"import groovy.util.logging.Slf4j\n" +
183+
"@CompileStatic @Slf4j('LOG')\n" +
184+
"trait T {\n" +
185+
" void test() {\n" +
186+
" LOG.info('yay!')\n" +
187+
" }\n" +
188+
"}\n" +
189+
"class C implements T {\n" +
190+
"}\n" +
191+
"new C().test()\n",
192+
};
193+
//@formatter:on
194+
195+
addRuntimeLibrary("org.slf4j:slf4j-simple:1.7.32");
196+
runConformTest(sources, "", "[Thread-0] INFO T$Trait$Helper - yay!");
197+
}
198+
199+
@Test // GROOVY-5736
200+
public void testUnresolved() {
201+
//@formatter:off
202+
String[] sources = {
203+
"Groovy5736.groovy",
204+
"@groovy.util.logging.Slf4j()\n" +
205+
"class Groovy5736 {\n" +
114206
"}\n",
115207
};
116208
//@formatter:on
117209

118-
runNegativeTest(sources, "");
210+
runNegativeTest(sources,
211+
"----------\n" +
212+
"1. WARNING in Groovy5736.groovy (at line 1)\n" +
213+
"\t@groovy.util.logging.Slf4j()\n" +
214+
"\t^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
215+
"Groovy:Unable to resolve class: org.slf4j.Logger\n" +
216+
"----------\n");
217+
}
218+
219+
//--------------------------------------------------------------------------
220+
221+
private void addRuntimeLibrary(String... spec) {
222+
java.util.Map<String, Object> args = new java.util.HashMap<>();
223+
args.put("classLoader", new groovy.lang.GroovyClassLoader());
224+
225+
java.util.Map<String, String>[] deps = java.util.Arrays.stream(spec).map(this::toMap).toArray(java.util.Map[]::new);
226+
227+
cpAdditions = java.util.Arrays.stream(groovy.grape.Grape.resolve(args, deps)).map(uri -> uri.getPath()).toArray(String[]::new);
228+
}
229+
230+
private java.util.Map<String, String> toMap(String spec) {
231+
String[] tokens = spec.split(":");
232+
233+
java.util.Map<String, String> map = new java.util.HashMap<>();
234+
map.put("group", tokens[0]);
235+
map.put("module", tokens[1]);
236+
map.put("version", tokens[2]);
237+
return map;
119238
}
120239
}

base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/LogASTTransformation.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.codehaus.groovy.control.CompilePhase;
4242
import org.codehaus.groovy.control.SourceUnit;
4343
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
44+
import org.codehaus.groovy.syntax.Token;
4445

4546
import java.lang.reflect.Method;
4647
import java.lang.reflect.Modifier;
@@ -108,6 +109,13 @@ public void visitClass(ClassNode node) {
108109
} else {
109110
logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName);
110111
}
112+
// GRECLIPSE add -- GROOVY-5736
113+
if (!logNode.getType().hasClass()) {
114+
String span = String.valueOf(new char[nodes[0].getLength()]);
115+
Token token = new Token(0, span, nodes[0].getLineNumber(), nodes[0].getColumnNumber());
116+
sourceUnit.getErrorCollector().addWarning(1, "Unable to resolve class: " + logNode.getType(), token, null);
117+
}
118+
// GRECLIPSE end
111119
super.visitClass(node);
112120
}
113121

base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4443,7 +4443,7 @@ && isNumberType(getType(argumentList.getExpression(0)))) {
44434443
//addStaticTypeError("Closure parameter with resolve strategy " + incomingStrategy + " passed to method with resolve strategy " + outgoingStrategy, argument);
44444444
if (argument.getLineNumber() > 0 && typeCheckingContext.reportedErrors.add(((long) argument.getLineNumber()) << 16 + argument.getColumnNumber())) {
44454445
String warning = StaticTypesTransformation.STATIC_ERROR_PREFIX + "Closure parameter with resolve strategy " + incomingStrategy + " passed to method with resolve strategy " + outgoingStrategy;
4446-
typeCheckingContext.getErrorCollector().addWarning(0, warning, new org.codehaus.groovy.syntax.Token(0, argument.getText(), argument.getLineNumber(), argument.getColumnNumber()), getSourceUnit());
4446+
typeCheckingContext.getErrorCollector().addWarning(1, warning, new org.codehaus.groovy.syntax.Token(0, argument.getText(), argument.getLineNumber(), argument.getColumnNumber()), getSourceUnit());
44474447
}
44484448
}
44494449
}

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/LogASTTransformation.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.codehaus.groovy.control.CompilePhase;
4242
import org.codehaus.groovy.control.SourceUnit;
4343
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
44+
import org.codehaus.groovy.syntax.Token;
4445

4546
import java.lang.reflect.Method;
4647
import java.lang.reflect.Modifier;
@@ -121,6 +122,13 @@ public void visitClass(ClassNode node) {
121122
// support the old style but they won't be as configurable
122123
logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName);
123124
}
125+
// GRECLIPSE add -- GROOVY-5736
126+
if (!logNode.getType().hasClass()) {
127+
String span = String.valueOf(new char[nodes[0].getLength()]);
128+
Token token = new Token(0, span, nodes[0].getLineNumber(), nodes[0].getColumnNumber());
129+
sourceUnit.getErrorCollector().addWarning(1, "Unable to resolve class: " + logNode.getType(), token, null);
130+
}
131+
// GRECLIPSE end
124132
}
125133
super.visitClass(node);
126134
}

base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4085,7 +4085,7 @@ && isNumberType(getType(argumentList.getExpression(0)))) {
40854085
*/
40864086
if (argument.getLineNumber() > 0 && typeCheckingContext.reportedErrors.add(((long) argument.getLineNumber()) << 16 + argument.getColumnNumber())) {
40874087
String warning = "Closure parameter with resolve strategy " + getResolveStrategyName(incomingStrategy) + " passed to method with resolve strategy " + getResolveStrategyName(outgoingStrategy);
4088-
typeCheckingContext.getErrorCollector().addWarning(0, StaticTypesTransformation.STATIC_ERROR_PREFIX + warning, new org.codehaus.groovy.syntax.Token(0, argument.getText(), argument.getLineNumber(), argument.getColumnNumber()), getSourceUnit());
4088+
typeCheckingContext.getErrorCollector().addWarning(1, StaticTypesTransformation.STATIC_ERROR_PREFIX + warning, new org.codehaus.groovy.syntax.Token(0, argument.getText(), argument.getLineNumber(), argument.getColumnNumber()), getSourceUnit());
40894089
}
40904090
// GRECLIPSE end
40914091
}

0 commit comments

Comments
 (0)