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 2021/10/07 18:06:22 UTC
[groovy] 01/02: GROOVY-4287, GROOVY-4386, GROOVY-7812,
GROOVY-9243: runtime resolve test
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-10248
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit a8f38a4e58e35e180056f10baea157f339e8961c
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu Oct 7 11:42:25 2021 -0500
GROOVY-4287, GROOVY-4386, GROOVY-7812, GROOVY-9243: runtime resolve test
---
.../java/org/codehaus/groovy/ast/CompileUnit.java | 227 ++++++++-------------
.../codehaus/groovy/control/CompilationUnit.java | 8 +-
.../codehaus/groovy/control/ResolveVisitor.java | 143 +------------
.../groovy/bugs/groovy4386/Constants.groovy} | 17 +-
.../groovy/bugs/groovy4386/StaticField.groovy} | 18 +-
.../groovy/bugs/groovy4386/StaticProperty.groovy} | 17 +-
.../bugs/groovy4386/StaticStarImport.groovy} | 18 +-
src/test/groovy/bugs/Groovy4386_Bug.groovy | 90 --------
src/test/groovy/bugs/Groovy7812Bug.groovy | 48 -----
src/test/groovy/bugs/Groovy9236.groovy | 125 ++++++++++++
.../groovy/bugs/groovy9236/Groovy9236Bug.groovy | 115 -----------
src/test/groovy/script/RuntimeResolveTests.groovy | 77 +++++++
12 files changed, 321 insertions(+), 582 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/CompileUnit.java b/src/main/java/org/codehaus/groovy/ast/CompileUnit.java
index 082252c..ed856c6 100644
--- a/src/main/java/org/codehaus/groovy/ast/CompileUnit.java
+++ b/src/main/java/org/codehaus/groovy/ast/CompileUnit.java
@@ -19,10 +19,8 @@
package org.codehaus.groovy.ast;
import groovy.lang.GroovyClassLoader;
-import groovy.transform.Internal;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
import org.codehaus.groovy.syntax.SyntaxException;
import java.security.CodeSource;
@@ -32,94 +30,132 @@ import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import java.util.function.BiConsumer;
-
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
/**
- * Represents the entire contents of a compilation step which consists of one or more
- * {@link ModuleNode} instances. There's one instance of this that's shared by all modules and
- * classes compiled during a single invocation of the compiler.
+ * Represents the entire contents of a compilation step which consists of one or
+ * more {@link ModuleNode} instances. There's one instance of this that's shared
+ * by all modules and classes compiled during a single invocation of the compiler.
* <p>
- * It's attached to MethodNodes and ClassNodes and is used to find fully qualified names of classes,
- * resolve imports, and that sort of thing.
+ * It's attached to MethodNodes and ClassNodes and is used to find fully qualified
+ * names of classes, resolve imports, and that sort of thing.
*/
public class CompileUnit implements NodeMetaDataHandler {
- private final List<ModuleNode> modules = new ArrayList<>();
- private final Map<String, ClassNode> classes = new LinkedHashMap<>();
private final CompilerConfiguration config;
- private final GroovyClassLoader classLoader;
+ private final GroovyClassLoader loader;
private final CodeSource codeSource;
+ private Map<?, ?> metaDataMap;
+
+ private final List<ModuleNode> modules = new ArrayList<>();
+ private final Map<String, ClassNode> classes = new LinkedHashMap<>();
private final Map<String, ClassNode> classesToCompile = new LinkedHashMap<>();
private final Map<String, SourceUnit> classNameToSource = new LinkedHashMap<>();
private final Map<String, InnerClassNode> generatedInnerClasses = new LinkedHashMap<>();
- private final Map<String, ConstructedOuterNestedClassNode> classesToResolve = new LinkedHashMap<>();
- private Map metaDataMap;
- public CompileUnit(GroovyClassLoader classLoader, CompilerConfiguration config) {
+ public CompileUnit(final GroovyClassLoader classLoader, final CompilerConfiguration config) {
this(classLoader, null, config);
}
- public CompileUnit(GroovyClassLoader classLoader, CodeSource codeSource, CompilerConfiguration config) {
- this.classLoader = classLoader;
- this.config = config;
+ public CompileUnit(final GroovyClassLoader classLoader, final CodeSource codeSource, final CompilerConfiguration config) {
+ this.loader = classLoader;
this.codeSource = codeSource;
+ this.config = config;
}
- public List<ModuleNode> getModules() {
- return modules;
+ public CompilerConfiguration getConfig() {
+ return config;
}
- public void addModule(ModuleNode node) {
- // node==null means a compilation error prevented
- // groovy from building an ast
- if (node == null) return;
- modules.add(node);
- node.setUnit(this);
- addClasses(node.getClasses());
+ public GroovyClassLoader getClassLoader() {
+ return loader;
}
- /**
- * @return the ClassNode for the given qualified name or returns null if
- * the name does not exist in the current compilation unit
- * (ignoring the .class files on the classpath)
- */
- public ClassNode getClass(String name) {
- ClassNode cn = classes.get(name);
- if (cn != null) return cn;
- return classesToCompile.get(name);
+ public CodeSource getCodeSource() {
+ return codeSource;
+ }
+
+ @Override
+ public Map<?, ?> getMetaDataMap() {
+ return metaDataMap;
+ }
+
+ @Override
+ public void setMetaDataMap(final Map<?, ?> metaDataMap) {
+ this.metaDataMap = metaDataMap;
+ }
+
+ public List<ModuleNode> getModules() {
+ return modules;
}
/**
* @return a list of all the classes in each module in the compilation unit
*/
public List<ClassNode> getClasses() {
- List<ClassNode> answer = new ArrayList<ClassNode>();
+ List<ClassNode> answer = new ArrayList<>();
for (ModuleNode module : modules) {
answer.addAll(module.getClasses());
}
return answer;
}
- public CompilerConfiguration getConfig() {
- return config;
+ /**
+ * @return the ClassNode for the given qualified name or returns null if
+ * the name does not exist in the current compilation unit
+ * (ignoring the .class files on the classpath)
+ */
+ public ClassNode getClass(final String name) {
+ ClassNode cn = classes.get(name);
+ if (cn == null)
+ cn = classesToCompile.get(name);
+ return cn;
}
- public GroovyClassLoader getClassLoader() {
- return classLoader;
+ public Map<String, ClassNode> getClassesToCompile() {
+ return classesToCompile;
}
- public CodeSource getCodeSource() {
- return codeSource;
+ public SourceUnit getScriptSourceLocation(final String className) {
+ return classNameToSource.get(className);
+ }
+
+ public Map<String, InnerClassNode> getGeneratedInnerClasses() {
+ return Collections.unmodifiableMap(generatedInnerClasses);
+ }
+
+ public InnerClassNode getGeneratedInnerClass(final String name) {
+ return generatedInnerClasses.get(name);
+ }
+
+ //--------------------------------------------------------------------------
+
+ @Deprecated
+ public boolean hasClassNodeToCompile() {
+ return !classesToCompile.isEmpty();
+ }
+
+ @Deprecated
+ public Iterator<String> iterateClassNodeToCompile() {
+ return classesToCompile.keySet().iterator();
+ }
+
+ //--------------------------------------------------------------------------
+
+ public void addModule(final ModuleNode node) {
+ // null means a compilation error prevented groovy from building an AST
+ if (node != null) {
+ modules.add(node);
+ node.setUnit(this);
+ addClasses(node.getClasses());
+ }
}
/**
- * Appends all of the fully qualified class names in this
- * module into the given map
+ * Appends all of the fully-qualified class names in this
+ * module into the given map.
*/
- void addClasses(List<ClassNode> classList) {
- for (ClassNode node : classList) {
+ public void addClasses(final List<ClassNode> list) {
+ for (ClassNode node : list) {
addClass(node);
}
}
@@ -148,17 +184,12 @@ public class CompileUnit implements NodeMetaDataHandler {
} else {
txt += "The sources " + nodeSource.getName() + " and " + storedSource.getName() + " each contain a class with the name " + node.getName() + ".\n";
}
- nodeSource.getErrorCollector().addErrorAndContinue(
- new SyntaxErrorMessage(new SyntaxException(txt, node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), nodeSource)
- );
+ nodeSource.addErrorAndContinue(new SyntaxException(txt, node));
}
classes.put(name, node);
- ClassNode cn = classesToCompile.get(name);
- if (null != cn) {
- cn.setRedirect(node);
- classesToCompile.remove(name);
- }
+ ClassNode cn = classesToCompile.remove(name);
+ if (cn != null) cn.setRedirect(node);
}
/**
@@ -166,93 +197,13 @@ public class CompileUnit implements NodeMetaDataHandler {
* a marker that this type has to be compiled by the CompilationUnit
* at the end of a parse step no node should be be left.
*/
- public void addClassNodeToCompile(ClassNode node, SourceUnit location) {
+ public void addClassNodeToCompile(final ClassNode node, final SourceUnit location) {
String nodeName = node.getName();
classesToCompile.put(nodeName, node);
classNameToSource.put(nodeName, location);
}
- public SourceUnit getScriptSourceLocation(String className) {
- return classNameToSource.get(className);
- }
-
- public boolean hasClassNodeToCompile() {
- return !classesToCompile.isEmpty();
- }
-
- public Iterator<String> iterateClassNodeToCompile() {
- return classesToCompile.keySet().iterator();
- }
-
- public InnerClassNode getGeneratedInnerClass(String name) {
- return generatedInnerClasses.get(name);
- }
-
- public void addGeneratedInnerClass(InnerClassNode icn) {
+ public void addGeneratedInnerClass(final InnerClassNode icn) {
generatedInnerClasses.put(icn.getName(), icn);
}
-
- public Map<String, InnerClassNode> getGeneratedInnerClasses() {
- return Collections.unmodifiableMap(generatedInnerClasses);
- }
-
- public Map<String, ClassNode> getClassesToCompile() {
- return classesToCompile;
- }
-
- public Map<String, ConstructedOuterNestedClassNode> getClassesToResolve() {
- return classesToResolve;
- }
-
- /**
- * Add a constructed class node as a placeholder to resolve outer nested class further.
- *
- * @param cn the constructed class node
- */
- public void addClassNodeToResolve(ConstructedOuterNestedClassNode cn) {
- classesToResolve.put(cn.getUnresolvedName(), cn);
- }
-
- @Override
- public Map<?, ?> getMetaDataMap() {
- return metaDataMap;
- }
-
- @Override
- public void setMetaDataMap(Map<?, ?> metaDataMap) {
- this.metaDataMap = metaDataMap;
- }
-
- /**
- * Represents a resolved type as a placeholder.
- *
- * @see <a href="https://issues.apache.org/jira/browse/GROOVY-7812">GROOVY-7812</a>
- */
- @Internal
- public static class ConstructedOuterNestedClassNode extends ClassNode {
- private final ClassNode enclosingClassNode;
- private final List<BiConsumer<ConstructedOuterNestedClassNode, ClassNode>> setRedirectListenerList = new ArrayList<>();
-
- public ConstructedOuterNestedClassNode(ClassNode outer, String innerClassName) {
- super(innerClassName, ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
- this.enclosingClassNode = outer;
- this.isPrimaryNode = false;
- }
-
- public ClassNode getEnclosingClassNode() {
- return enclosingClassNode;
- }
-
- @Override
- public void setRedirect(ClassNode cn) {
- for (BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener : setRedirectListenerList) {
- setRedirectListener.accept(this, cn);
- }
- super.setRedirect(cn);
- }
-
- public void addSetRedirectListener(BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
- setRedirectListenerList.add(setRedirectListener);
- }
- }
}
diff --git a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
index af48d23..4de5ae8 100644
--- a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
@@ -46,7 +46,6 @@ import org.codehaus.groovy.control.io.InputStreamReaderSource;
import org.codehaus.groovy.control.io.ReaderSource;
import org.codehaus.groovy.control.messages.ExceptionMessage;
import org.codehaus.groovy.control.messages.Message;
-import org.codehaus.groovy.control.messages.SimpleMessage;
import org.codehaus.groovy.syntax.RuntimeParserException;
import org.codehaus.groovy.syntax.SyntaxException;
import org.codehaus.groovy.tools.GroovyClass;
@@ -227,7 +226,7 @@ public class CompilationUnit extends ProcessingUnit {
List<ClassNode> classes = source.getAST().getClasses();
for (ClassNode node : classes) {
CompileUnit cu = node.getCompileUnit();
- for (Iterator<String> it = cu.iterateClassNodeToCompile(); it.hasNext(); ) {
+ for (Iterator<String> it = cu.getClassesToCompile().keySet().iterator(); it.hasNext(); ) {
String name = it.next();
StringBuilder message = new StringBuilder();
message
@@ -250,9 +249,8 @@ public class CompilationUnit extends ProcessingUnit {
}
}
- getErrorCollector().addErrorAndContinue(
- new SimpleMessage(message.toString(), this)
- );
+ getErrorCollector().addErrorAndContinue(Message.create(message.toString(), this));
+
it.remove();
}
}
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index d4ce72e..9b17df7 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -27,7 +27,6 @@ import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.CompileUnit;
-import org.codehaus.groovy.ast.CompileUnit.ConstructedOuterNestedClassNode;
import org.codehaus.groovy.ast.DynamicVariable;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.GenericsType;
@@ -60,7 +59,6 @@ import org.codehaus.groovy.ast.stmt.BlockStatement;
import org.codehaus.groovy.ast.stmt.CatchStatement;
import org.codehaus.groovy.ast.stmt.ForStatement;
import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.control.ClassNodeResolver.LookupResult;
import org.codehaus.groovy.runtime.memoize.UnlimitedConcurrentCache;
import org.codehaus.groovy.syntax.Types;
import org.codehaus.groovy.transform.trait.Traits;
@@ -77,7 +75,6 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.BiConsumer;
import java.util.function.Predicate;
import static groovy.lang.Tuple.tuple;
@@ -340,7 +337,6 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
}
if (resolve(type)) return;
if (resolveToInner(type)) return;
- if (resolveToOuterNested(type)) return;
addError("unable to resolve class " + type.toString(false) + msg, node);
}
@@ -370,107 +366,6 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
return false;
}
- // GROOVY-7812(#1): Static inner classes cannot be accessed from other files
- // when running by 'groovy' command if the type to resolve is an inner class
- // and it is in an outer class which is not resolved, we set resolved type to
- // a placeholder class node, i.e. a ConstructedOuterNestedClass instance when
- // resolving the outer class later, we set the resolved type of ConstructedOuterNestedClass
- // instance to the actual inner class node (see GROOVY-7812(#2))
- private boolean resolveToOuterNested(final ClassNode type) {
- CompileUnit compileUnit = currentClass.getCompileUnit();
- if (compileUnit == null) return false;
- String typeName = type.getName();
-
- BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener = (s, c) -> type.setRedirect(s);
-
- ModuleNode module = currentClass.getModule();
- for (ImportNode importNode : module.getStaticImports().values()) {
- String importFieldName = importNode.getFieldName();
- String importAlias = importNode.getAlias();
-
- if (!typeName.equals(importAlias)) continue;
-
- ConstructedOuterNestedClassNode constructedOuterNestedClassNode =
- tryToConstructOuterNestedClassNodeViaStaticImport(compileUnit, importNode, importFieldName, setRedirectListener);
- if (constructedOuterNestedClassNode != null) {
- compileUnit.addClassNodeToResolve(constructedOuterNestedClassNode);
- return true;
- }
- }
-
- for (ClassNode outerClassNode : compileUnit.getClassesToCompile().values()) {
- ConstructedOuterNestedClassNode constructedOuterNestedClassNode =
- tryToConstructOuterNestedClassNode(type, outerClassNode, setRedirectListener);
- if (constructedOuterNestedClassNode != null) {
- compileUnit.addClassNodeToResolve(constructedOuterNestedClassNode);
- return true;
- }
- }
-
- boolean toResolveFurther = false;
- for (ImportNode importNode : module.getStaticStarImports().values()) {
- ConstructedOuterNestedClassNode constructedOuterNestedClassNode =
- tryToConstructOuterNestedClassNodeViaStaticImport(compileUnit, importNode, typeName, setRedirectListener);
- if (constructedOuterNestedClassNode != null) {
- compileUnit.addClassNodeToResolve(constructedOuterNestedClassNode);
- toResolveFurther = true; // try all static star imports because we do not know which outer class the class is declared in
- }
- }
- if (toResolveFurther) return true;
-
- // GROOVY-9243
- toResolveFurther = false;
- if (typeName.indexOf('.') == -1) {
- for (ClassNode cn = currentClass; cn != null && !isObjectType(cn); cn = cn.getSuperClass()) {
- ConstructedOuterNestedClassNode constructedOuterNestedClassNode =
- tryToConstructOuterNestedClassNodeForBaseType(compileUnit, typeName, cn, setRedirectListener);
- if (constructedOuterNestedClassNode != null) {
- compileUnit.addClassNodeToResolve(constructedOuterNestedClassNode);
- toResolveFurther = true;
- }
- }
- }
-
- return toResolveFurther;
- }
-
- private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNodeViaStaticImport(final CompileUnit compileUnit, final ImportNode importNode, final String typeName, final BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
- String importClassName = importNode.getClassName();
- ClassNode outerClassNode = compileUnit.getClass(importClassName);
-
- if (null == outerClassNode) return null;
-
- String outerNestedClassName = importClassName + "$" + typeName.replace('.', '$');
- ConstructedOuterNestedClassNode constructedOuterNestedClassNode = new ConstructedOuterNestedClassNode(outerClassNode, outerNestedClassName);
- constructedOuterNestedClassNode.addSetRedirectListener(setRedirectListener);
- return constructedOuterNestedClassNode;
- }
-
- private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNode(final ClassNode type, final ClassNode outerClassNode, final BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
- String outerClassName = outerClassNode.getName();
-
- for (String typeName = type.getName(), ident = typeName; ident.indexOf('.') != -1; ) {
- ident = ident.substring(0, ident.lastIndexOf('.'));
- if (outerClassName.endsWith(ident)) {
- String outerNestedClassName = outerClassName + typeName.substring(ident.length()).replace('.', '$');
- ConstructedOuterNestedClassNode constructedOuterNestedClassNode = new ConstructedOuterNestedClassNode(outerClassNode, outerNestedClassName);
- constructedOuterNestedClassNode.addSetRedirectListener(setRedirectListener);
- return constructedOuterNestedClassNode;
- }
- }
-
- return null;
- }
-
- private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNodeForBaseType(final CompileUnit compileUnit, final String typeName, final ClassNode cn, final BiConsumer<ConstructedOuterNestedClassNode, ClassNode> setRedirectListener) {
- if (!compileUnit.getClassesToCompile().containsValue(cn)) return null;
-
- String outerNestedClassName = cn.getName() + "$" + typeName;
- ConstructedOuterNestedClassNode constructedOuterNestedClassNode = new ConstructedOuterNestedClassNode(cn, outerNestedClassName);
- constructedOuterNestedClassNode.addSetRedirectListener(setRedirectListener);
- return constructedOuterNestedClassNode;
- }
-
protected boolean resolve(final ClassNode type) {
return resolve(type, true, true, true);
}
@@ -867,11 +762,10 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
if (currentClass.getModule().hasPackageName() && name.indexOf('.') == -1) return false;
- LookupResult lr = classNodeResolver.resolveName(name, compilationUnit);
+ ClassNodeResolver.LookupResult lr = classNodeResolver.resolveName(name, compilationUnit);
if (lr != null) {
if (lr.isSourceUnit()) {
- SourceUnit su = lr.getSourceUnit();
- currentClass.getCompileUnit().addClassNodeToCompile(type, su);
+ currentClass.getCompileUnit().addClassNodeToCompile(type, lr.getSourceUnit());
} else {
type.setRedirect(lr.getClassNode());
}
@@ -1456,8 +1350,6 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
super.visitClass(node);
- resolveOuterNestedClassFurther(node);
-
currentClass = oldNode;
}
@@ -1488,37 +1380,6 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
}
}
- // GROOVY-7812(#2): Static inner classes cannot be accessed from other files when running by 'groovy' command
- private void resolveOuterNestedClassFurther(final ClassNode node) {
- CompileUnit compileUnit = currentClass.getCompileUnit();
-
- if (null == compileUnit) return;
-
- Map<String, ConstructedOuterNestedClassNode> classesToResolve = compileUnit.getClassesToResolve();
- List<String> resolvedInnerClassNameList = new LinkedList<>();
-
- for (Map.Entry<String, ConstructedOuterNestedClassNode> entry : classesToResolve.entrySet()) {
- String innerClassName = entry.getKey();
- ConstructedOuterNestedClassNode constructedOuterNestedClass = entry.getValue();
-
- // When the outer class is resolved, all inner classes are resolved too
- if (node.getName().equals(constructedOuterNestedClass.getEnclosingClassNode().getName())) {
- ClassNode innerClassNode = compileUnit.getClass(innerClassName); // find the resolved inner class
-
- if (null == innerClassNode) {
- return; // "unable to resolve class" error can be thrown already, no need to `addError`, so just return
- }
-
- constructedOuterNestedClass.setRedirect(innerClassNode);
- resolvedInnerClassNameList.add(innerClassName);
- }
- }
-
- for (String innerClassName : resolvedInnerClassNameList) {
- classesToResolve.remove(innerClassName);
- }
- }
-
@Override
public void visitCatchStatement(final CatchStatement cs) {
resolveOrFail(cs.getExceptionType(), cs);
diff --git a/src/test/groovy/bugs/Groovy9243.groovy b/src/test-resources/groovy/bugs/groovy4386/Constants.groovy
similarity index 71%
copy from src/test/groovy/bugs/Groovy9243.groovy
copy to src/test-resources/groovy/bugs/groovy4386/Constants.groovy
index 51014ee..2d7ac2f 100644
--- a/src/test/groovy/bugs/Groovy9243.groovy
+++ b/src/test-resources/groovy/bugs/groovy4386/Constants.groovy
@@ -16,18 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-package groovy.bugs
+package groovy.bugs.groovy4386
-
-import groovy.transform.CompileStatic
-import org.apache.groovy.util.ScriptRunner
-import org.junit.Ignore
-import org.junit.Test
-
-@CompileStatic
-final class Groovy9243 {
- @Ignore @Test
- void testResolveNestedClassFromBaseType() {
- ScriptRunner.runScript('/groovy/bugs/groovy9243/Main.groovy')
- }
+class Constants {
+ public static final PI = 3.14
+ static final TWOPI = 6.28
}
diff --git a/src/test/groovy/bugs/Groovy9243.groovy b/src/test-resources/groovy/bugs/groovy4386/StaticField.groovy
similarity index 72%
rename from src/test/groovy/bugs/Groovy9243.groovy
rename to src/test-resources/groovy/bugs/groovy4386/StaticField.groovy
index 51014ee..b2c2966 100644
--- a/src/test/groovy/bugs/Groovy9243.groovy
+++ b/src/test-resources/groovy/bugs/groovy4386/StaticField.groovy
@@ -16,18 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package groovy.bugs
+package groovy.bugs.groovy4386
+import static groovy.bugs.groovy4386.Constants.PI
-import groovy.transform.CompileStatic
-import org.apache.groovy.util.ScriptRunner
-import org.junit.Ignore
-import org.junit.Test
-
-@CompileStatic
-final class Groovy9243 {
- @Ignore @Test
- void testResolveNestedClassFromBaseType() {
- ScriptRunner.runScript('/groovy/bugs/groovy9243/Main.groovy')
+class Test {
+ static test() {
+ assert PI == 3.14
}
}
+
+Test.test()
diff --git a/src/test/groovy/bugs/Groovy4287Bug.groovy b/src/test-resources/groovy/bugs/groovy4386/StaticProperty.groovy
similarity index 68%
rename from src/test/groovy/bugs/Groovy4287Bug.groovy
rename to src/test-resources/groovy/bugs/groovy4386/StaticProperty.groovy
index e881e19..856aaea 100644
--- a/src/test/groovy/bugs/Groovy4287Bug.groovy
+++ b/src/test-resources/groovy/bugs/groovy4386/StaticProperty.groovy
@@ -16,17 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package groovy.bugs
+package groovy.bugs.groovy4386
-import groovy.test.GroovyTestCase
-import org.apache.groovy.util.ScriptRunner
+import static groovy.bugs.groovy4386.Constants.TWOPI
-class Groovy4287Bug extends GroovyTestCase {
- void testResolvingOuterStaticNestedClass() {
- ScriptRunner.runScript('/groovy/bugs/groovy4287/Main.groovy')
- }
-
- void testResolvingOuterStaticNestedClassAlias() {
- ScriptRunner.runScript('/groovy/bugs/groovy4287/Main2.groovy')
+class Test {
+ static test() {
+ assert TWOPI == 6.28
}
}
+
+Test.test()
diff --git a/src/test/groovy/bugs/groovy9236/Groovy9236ClassLoader.java b/src/test-resources/groovy/bugs/groovy4386/StaticStarImport.groovy
similarity index 67%
rename from src/test/groovy/bugs/groovy9236/Groovy9236ClassLoader.java
rename to src/test-resources/groovy/bugs/groovy4386/StaticStarImport.groovy
index 8a430b1..14c361a 100644
--- a/src/test/groovy/bugs/groovy9236/Groovy9236ClassLoader.java
+++ b/src/test-resources/groovy/bugs/groovy4386/StaticStarImport.groovy
@@ -16,18 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package bugs.groovy9236;
+package groovy.bugs.groovy4386
-import groovy.lang.GroovyClassLoader;
+import static groovy.bugs.groovy4386.Constants.*
-import java.util.ArrayList;
-import java.util.List;
-
-public class Groovy9236ClassLoader extends GroovyClassLoader {
- final List<String> guessedClassNameList = new ArrayList<>();
-
- protected Class<?> findClass(final String name) throws ClassNotFoundException {
- guessedClassNameList.add(name);
- return super.findClass(name);
+class Test {
+ static test() {
+ assert TWOPI == PI + PI
}
}
+
+Test.test()
diff --git a/src/test/groovy/bugs/Groovy4386_Bug.groovy b/src/test/groovy/bugs/Groovy4386_Bug.groovy
deleted file mode 100644
index ffe084d..0000000
--- a/src/test/groovy/bugs/Groovy4386_Bug.groovy
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package groovy.bugs
-
-import groovy.test.GroovyTestCase
-import org.codehaus.groovy.control.CompilerConfiguration
-import org.codehaus.groovy.runtime.ResourceGroovyMethods
-
-/**
- * Test for GROOVY-4386: Using static imports to a script on the classpath.
- */
-class Groovy4386_Bug extends GroovyTestCase {
- private static final scriptSource = """
- package foo
- class Constants {
- public static final PI = 3.14
- static final TWOPI = 6.28
- }
- """
- File tmpDir
-
- @Override protected void setUp() {
- tmpDir = File.createTempDir()
- File dir = new File(tmpDir, 'foo')
- dir.mkdir()
- File file = new File(dir, "Constants.groovy")
- ResourceGroovyMethods.setText(file, scriptSource);
- }
-
- @Override protected void tearDown() {
- tmpDir.deleteDir()
- }
-
- void testAccessPublicStaticField() {
- assertScript """
- import static foo.Constants.PI
- class Test {
- static test() {
- assert PI == 3.14
- }
- }
- Test.test()
- """
- }
-
- void testAccessStaticProperty() {
- assertScript """
- import static foo.Constants.TWOPI
- class Test {
- static test() {
- assert TWOPI == 6.28
- }
- }
- Test.test()
- """
- }
-
- void testStarImport() {
- assertScript """
- import static foo.Constants.*
- class Test {
- static test() {
- assert TWOPI == PI + PI
- }
- }
- Test.test()
- """
- }
-
- void assertScript(String script) {
- GroovyShell shell = new GroovyShell(new CompilerConfiguration(classpath: tmpDir.path))
- shell.evaluate(script, getTestClassName())
- }
-}
diff --git a/src/test/groovy/bugs/Groovy7812Bug.groovy b/src/test/groovy/bugs/Groovy7812Bug.groovy
deleted file mode 100644
index 6055402..0000000
--- a/src/test/groovy/bugs/Groovy7812Bug.groovy
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package groovy.bugs
-
-import groovy.test.GroovyTestCase
-import org.apache.groovy.util.ScriptRunner
-
-class Groovy7812Bug extends GroovyTestCase {
- void testResolvingOuterNestedClass() {
- ScriptRunner.runScript('/groovy/bugs/groovy7812/Main.groovy')
- }
-
-// Even if try to catch `Throwable`, the expected error is thrown all the same..., as a result, the test fails due to the weired problem...
-//
-// org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
-//D:\_APPS\git_apps\groovy\out\test\resources\groovy\bugs\groovy7812\MainWithErrors.groovy: 22: unable to resolve class Outer.Inner123
-// @ line 22, column 8.
-// assert new Outer.Inner123()
-// ^
-//
-//1 error
-//
-// void testUnexistingInnerClass() {
-// try {
-// def mainScriptPath = new File(this.getClass().getResource('/groovy/bugs/groovy7812/MainWithErrors.groovy').toURI()).absolutePath
-// runScript(mainScriptPath)
-// } catch (Throwable t) {
-// assert t.getMessage().contains('unable to resolve class Outer.Inner123')
-// }
-// }
-
-}
diff --git a/src/test/groovy/bugs/Groovy9236.groovy b/src/test/groovy/bugs/Groovy9236.groovy
new file mode 100644
index 0000000..8493952
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9236.groovy
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.bugs
+
+import org.junit.Test
+
+final class Groovy9236 {
+
+ /**
+ * groovy-3.0.0-beta-3 will try to guess and load the following classes:
+ * <pre>
+ * Script1$_p_lambda1BeanInfo
+ * Script1$_p_lambda1Customizer
+ * Script1BeanInfo
+ * Script1Customizer
+ * groovy$transform$CompileStatic
+ * groovy.lang.GroovyObject$Collectors
+ * groovy.lang.GroovyObject$CompileStatic
+ * groovy.lang.GroovyObject$groovy$transform$CompileStatic
+ * groovy.lang.GroovyObject$java$util$stream$Collectors
+ * groovy.lang.GroovyObject$java$util$stream$Stream
+ * groovy.lang.groovy$transform$CompileStatic
+ * groovy.lang.java$util$stream$Collectors
+ * groovy.lang.java$util$stream$Stream
+ * groovy.transform$CompileStatic
+ * groovy.util.groovy$transform$CompileStatic
+ * groovy.util.java$util$stream$Collectors
+ * groovy.util.java$util$stream$Stream
+ * java$util$stream$Collectors
+ * java$util$stream$Stream
+ * java.io.groovy$transform$CompileStatic
+ * java.io.java$util$stream$Collectors
+ * java.io.java$util$stream$Stream
+ * java.lang.groovy$transform$CompileStatic
+ * java.lang.java$util$stream$Collectors
+ * java.lang.java$util$stream$Stream
+ * java.net.groovy$transform$CompileStatic
+ * java.net.java$util$stream$Collectors
+ * java.net.java$util$stream$Stream
+ * java.util$stream$Collectors
+ * java.util$stream$Stream
+ * java.util.groovy$transform$CompileStatic
+ * java.util.java$util$stream$Collectors
+ * java.util.java$util$stream$Stream
+ * java.util.stream$Collectors
+ * java.util.stream$Stream
+ * </pre>
+ */
+ @Test
+ void testAvoidUnnecessaryResolving() {
+ def guessedClassNameList = []
+
+ def loader = new GroovyClassLoader() {
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ guessedClassNameList.add(name)
+ return super.findClass(name)
+ }
+ }
+
+ new GroovyShell(loader).evaluate('''
+ import groovy.transform.CompileStatic
+ import java.util.stream.Collectors
+ import java.util.stream.Stream
+
+ @CompileStatic
+ void p() {
+ assert [2, 3, 4] == [1, 2, 3].stream().map(e -> e.plus(1)).collect(Collectors.toList())
+ }
+
+ p()
+ ''')
+
+ Set<String> classNamesShouldAvoidToGuess = [
+ 'java.lang.java$util$stream$Collectors',
+ 'java.util.java$util$stream$Collectors',
+ 'java.io.java$util$stream$Collectors',
+ 'java.net.java$util$stream$Collectors',
+ 'groovy.lang.java$util$stream$Collectors',
+ 'groovy.util.java$util$stream$Collectors',
+ 'java$util$stream$Collectors',
+ 'java.util$stream$Collectors',
+ 'java.util.stream$Collectors',
+ 'java.lang.groovy$transform$CompileStatic',
+ 'java.util.groovy$transform$CompileStatic',
+ 'java.io.groovy$transform$CompileStatic',
+ 'java.net.groovy$transform$CompileStatic',
+ 'groovy.lang.groovy$transform$CompileStatic',
+ 'groovy.util.groovy$transform$CompileStatic',
+ 'groovy$transform$CompileStatic',
+ 'groovy.transform$CompileStatic',
+ 'java.lang.java$util$stream$Stream',
+ 'java.util.java$util$stream$Stream',
+ 'java.io.java$util$stream$Stream',
+ 'java.net.java$util$stream$Stream',
+ 'groovy.lang.java$util$stream$Stream',
+ 'groovy.util.java$util$stream$Stream',
+ 'java$util$stream$Stream',
+ 'java.util$stream$Stream',
+ 'java.util.stream$Stream',
+ 'groovy.lang.GroovyObject$java$util$stream$Collectors',
+ 'groovy.lang.GroovyObject$groovy$transform$CompileStatic',
+ 'groovy.lang.GroovyObject$java$util$stream$Stream'
+ ]
+
+ assert !guessedClassNameList.isEmpty()
+ assert guessedClassNameList.every(n -> !classNamesShouldAvoidToGuess.contains(n))
+ }
+}
diff --git a/src/test/groovy/bugs/groovy9236/Groovy9236Bug.groovy b/src/test/groovy/bugs/groovy9236/Groovy9236Bug.groovy
deleted file mode 100644
index 093eed4..0000000
--- a/src/test/groovy/bugs/groovy9236/Groovy9236Bug.groovy
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package bugs.groovy9236
-
-import groovy.test.GroovyTestCase
-import org.apache.groovy.util.ScriptRunner
-
-class Groovy9236Bug extends GroovyTestCase {
- /* groovy-3.0.0-beta-3 will try to guess and load the following classes:
-Script1$_p_lambda1BeanInfo
-Script1$_p_lambda1Customizer
-Script1BeanInfo
-Script1Customizer
-groovy$transform$CompileStatic
-groovy.lang.GroovyObject$Collectors
-groovy.lang.GroovyObject$CompileStatic
-groovy.lang.GroovyObject$groovy$transform$CompileStatic
-groovy.lang.GroovyObject$java$util$stream$Collectors
-groovy.lang.GroovyObject$java$util$stream$Stream
-groovy.lang.groovy$transform$CompileStatic
-groovy.lang.java$util$stream$Collectors
-groovy.lang.java$util$stream$Stream
-groovy.transform$CompileStatic
-groovy.util.groovy$transform$CompileStatic
-groovy.util.java$util$stream$Collectors
-groovy.util.java$util$stream$Stream
-java$util$stream$Collectors
-java$util$stream$Stream
-java.io.groovy$transform$CompileStatic
-java.io.java$util$stream$Collectors
-java.io.java$util$stream$Stream
-java.lang.groovy$transform$CompileStatic
-java.lang.java$util$stream$Collectors
-java.lang.java$util$stream$Stream
-java.net.groovy$transform$CompileStatic
-java.net.java$util$stream$Collectors
-java.net.java$util$stream$Stream
-java.util$stream$Collectors
-java.util$stream$Stream
-java.util.groovy$transform$CompileStatic
-java.util.java$util$stream$Collectors
-java.util.java$util$stream$Stream
-java.util.stream$Collectors
-java.util.stream$Stream
- */
- void testAvoidUnnecessaryResolving() {
- def cl = new Groovy9236ClassLoader()
- def gs = new GroovyShell(cl)
- gs.evaluate('''
- import groovy.transform.CompileStatic
- import java.util.stream.Collectors
- import java.util.stream.Stream
-
- @CompileStatic
- void p() {
- assert [2, 3, 4] == [1, 2, 3].stream().map(e -> e.plus(1)).collect(Collectors.toList())
- }
-
- p()
- ''')
-
- final classNamesShouldAvoidToGuess = ['java.lang.java$util$stream$Collectors',
- 'java.util.java$util$stream$Collectors',
- 'java.io.java$util$stream$Collectors',
- 'java.net.java$util$stream$Collectors',
- 'groovy.lang.java$util$stream$Collectors',
- 'groovy.util.java$util$stream$Collectors',
- 'java$util$stream$Collectors',
- 'java.util$stream$Collectors',
- 'java.util.stream$Collectors',
- 'java.lang.groovy$transform$CompileStatic',
- 'java.util.groovy$transform$CompileStatic',
- 'java.io.groovy$transform$CompileStatic',
- 'java.net.groovy$transform$CompileStatic',
- 'groovy.lang.groovy$transform$CompileStatic',
- 'groovy.util.groovy$transform$CompileStatic',
- 'groovy$transform$CompileStatic',
- 'groovy.transform$CompileStatic',
- 'java.lang.java$util$stream$Stream',
- 'java.util.java$util$stream$Stream',
- 'java.io.java$util$stream$Stream',
- 'java.net.java$util$stream$Stream',
- 'groovy.lang.java$util$stream$Stream',
- 'groovy.util.java$util$stream$Stream',
- 'java$util$stream$Stream',
- 'java.util$stream$Stream',
- 'java.util.stream$Stream',
- 'groovy.lang.GroovyObject$java$util$stream$Collectors',
- 'groovy.lang.GroovyObject$groovy$transform$CompileStatic',
- 'groovy.lang.GroovyObject$java$util$stream$Stream']
-
- assert !cl.guessedClassNameList.isEmpty()
- assert cl.guessedClassNameList.every(n -> !classNamesShouldAvoidToGuess.contains(n))
- }
-
- void testResolvingPrecedence() {
- ScriptRunner.runScript('/groovy/bugs/groovy9236/Main.groovy')
- }
-}
diff --git a/src/test/groovy/script/RuntimeResolveTests.groovy b/src/test/groovy/script/RuntimeResolveTests.groovy
new file mode 100644
index 0000000..922bdbf
--- /dev/null
+++ b/src/test/groovy/script/RuntimeResolveTests.groovy
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.script
+
+import org.junit.Ignore
+import org.junit.Test
+
+import static org.apache.groovy.util.ScriptRunner.runScript
+
+@Ignore('disabled pending rework')
+final class RuntimeResolveTests {
+
+ @Test
+ void testResolveOuterStaticNestedClass() {
+ runScript('/groovy/bugs/groovy4287/Main.groovy')
+ }
+
+ @Test
+ void testResolveOuterStaticNestedClassAlias() {
+ runScript('/groovy/bugs/groovy4287/Main2.groovy')
+ }
+
+ @Test
+ void testResolvePublicStaticField() {
+ runScript('/groovy/bugs/groovy4386/StaticField.groovy')
+ }
+
+ @Test
+ void testResolveStaticProperty() {
+ runScript('/groovy/bugs/groovy4386/StaticProperty.groovy')
+ }
+
+ @Test
+ void testResolveStaticMembers() {
+ runScript('/groovy/bugs/groovy4386/StaticStarImport.groovy')
+ }
+
+ @Test
+ void testResolveOuterNestedClass() {
+ runScript('/groovy/bugs/groovy7812/Main.groovy')
+ }
+
+ @Test @Ignore('exception in script causes problem for build')
+ void testUnexistingInnerClass() {
+ try {
+ runScript('/groovy/bugs/groovy7812/MainWithErrors.groovy')
+ } catch (Throwable t) {
+ assert t.getMessage().contains('unable to resolve class Outer.Inner123')
+ }
+ }
+
+ @Test
+ void testResolvePrecedence() {
+ runScript('/groovy/bugs/groovy9236/Main.groovy')
+ }
+
+ @Test
+ void testResolveNestedClassFromBaseType() {
+ runScript('/groovy/bugs/groovy9243/Main.groovy')
+ }
+}