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 2022/11/03 18:44:46 UTC
[groovy] branch GROOVY_2_5_X updated: GROOVY-7025: cannot refer to non-constant static field in `enum` init
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new 9e62ab73ee GROOVY-7025: cannot refer to non-constant static field in `enum` init
9e62ab73ee is described below
commit 9e62ab73ee36110745a5f76b066fe5d4eedeedd0
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Nov 3 12:12:40 2022 -0500
GROOVY-7025: cannot refer to non-constant static field in `enum` init
---
.../groovy/classgen/VariableScopeVisitor.java | 23 +++++++----
src/test/gls/CompilableTestSupport.groovy | 31 +++++++++-----
src/test/gls/enums/EnumTest.groovy | 47 +++++++++++++++++++++-
3 files changed, 81 insertions(+), 20 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index 5c8a0b774a..f66d3535aa 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -296,17 +296,24 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
checkVariableContextAccess(member, pe);
}
- private void checkVariableContextAccess(Variable v, Expression expr) {
- if (v.isInStaticContext() || !currentScope.isInStaticContext()) return;
+ private void checkVariableContextAccess(final Variable variable, final Expression expression) {
+ if (variable.isInStaticContext()) {
+ if (inConstructor && currentClass.isEnum() && variable instanceof FieldNode
+ && currentClass.equals(((FieldNode) variable).getDeclaringClass())) { // GROOVY-7025
+ if (!isFinal(variable.getModifiers()) || !(ClassHelper.isStaticConstantInitializerType(variable.getOriginType())
+ || "String".equals(variable.getOriginType().getName()))) { // TODO: String requires constant initializer
+ addError("Cannot refer to the static enum field '" + variable.getName() + "' within an initializer", expression);
+ }
+ }
+ return;
+ }
+
+ if (!currentScope.isInStaticContext()) return;
- String msg = v.getName() +
- " is declared in a dynamic context, but you tried to" +
- " access it from a static context.";
- addError(msg, expr);
+ addError(variable.getName() + " is declared in a dynamic context, but you tried to access it from a static context.", expression);
// declare a static variable to be able to continue the check
- DynamicVariable v2 = new DynamicVariable(v.getName(), currentScope.isInStaticContext());
- currentScope.putDeclaredVariable(v2);
+ currentScope.putDeclaredVariable(new DynamicVariable(variable.getName(), currentScope.isInStaticContext()));
}
// ------------------------------
diff --git a/src/test/gls/CompilableTestSupport.groovy b/src/test/gls/CompilableTestSupport.groovy
index eed62a5190..de6eaa93f9 100644
--- a/src/test/gls/CompilableTestSupport.groovy
+++ b/src/test/gls/CompilableTestSupport.groovy
@@ -18,24 +18,33 @@
*/
package gls
+import groovy.transform.AutoFinal
import groovy.transform.CompileStatic
import org.codehaus.groovy.control.CompilationFailedException
-@CompileStatic
+import static org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport.closeQuietly
+
+@AutoFinal @CompileStatic
abstract class CompilableTestSupport extends GroovyTestCase {
- protected shouldNotCompile(String script) {
+
+ protected String shouldNotCompile(String script) {
+ def gcl = new GroovyClassLoader()
try {
- GroovyClassLoader gcl = new GroovyClassLoader()
- gcl.parseClass(script, getTestClassName())
- } catch (CompilationFailedException cfe) {
- return cfe.message
+ gcl.parseClass(script, testClassName)
+ } catch (CompilationFailedException ex) {
+ return ex.message
+ } finally {
+ closeQuietly(gcl)
}
- fail("the compilation succeeded but should have failed")
+ fail('the compilation succeeded but should have failed')
}
protected void shouldCompile(String script) {
- GroovyClassLoader gcl = new GroovyClassLoader()
- gcl.parseClass(script, getTestClassName())
- assert true
+ def gcl = new GroovyClassLoader()
+ try {
+ gcl.parseClass(script, testClassName)
+ } finally {
+ closeQuietly(gcl)
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/test/gls/enums/EnumTest.groovy b/src/test/gls/enums/EnumTest.groovy
index 79da52fa0f..30965021fe 100644
--- a/src/test/gls/enums/EnumTest.groovy
+++ b/src/test/gls/enums/EnumTest.groovy
@@ -187,7 +187,52 @@ class EnumTest extends CompilableTestSupport {
assert allColors[2] == GroovyColors3161.green
}
- // the fix for GROOVY-3283
+ // GROOVY-7025
+ void testStaticEnumFieldFromInit() {
+ def err = shouldNotCompile '''
+ enum E {
+ FOO('bar');
+ private static final Set<String> names = []
+ E(String name) {
+ names.add(name)
+ }
+ }
+ '''
+ assert err =~ /Cannot refer to the static enum field 'names' within an initializer/
+
+ shouldCompile '''
+ enum E {
+ FOO;
+ private static final String ONE = 1
+ private final value
+ E() {
+ value = 1 + ONE
+ }
+ }
+ '''
+ shouldCompile '''
+ enum E {
+ FOO;
+ private static final int ONE = 1
+ private final value
+ E() {
+ value = 1 + ONE
+ }
+ }
+ '''
+ shouldNotCompile '''
+ enum E {
+ FOO;
+ private static int ONE = 1
+ private final value
+ E() {
+ value = 1 + ONE
+ }
+ }
+ '''
+ }
+
+ // GROOVY-3283
void testImportStaticMoreThanOneEnum() {
assertScript """
enum Foo3283 { A,B }