You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/01/25 16:43:56 UTC
[groovy] branch master updated: GROOVY-4287: CLONE - import of
static nested classes in external groovy files is broken(closes #858)
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 9942c2b GROOVY-4287: CLONE - import of static nested classes in external groovy files is broken(closes #858)
9942c2b is described below
commit 9942c2b252845aa557f58850185b68c70fb7936e
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Jan 26 00:43:46 2019 +0800
GROOVY-4287: CLONE - import of static nested classes in external groovy files is broken(closes #858)
---
.../codehaus/groovy/control/ResolveVisitor.java | 56 +++++++++++++++++-----
.../groovy/bugs/groovy4287/Main.groovy | 27 +++++++++++
.../groovy/bugs/groovy4287/Main2.groovy | 24 ++++++++++
.../groovy/bugs/groovy4287/Outer.groovy | 25 ++++++++++
.../groovy/bugs/groovy4287/Outer2.groovy | 25 ++++++++++
.../groovy/bugs/groovy4287/Outer3.groovy | 25 ++++++++++
src/test/groovy/bugs/Groovy4287Bug.groovy | 37 ++++++++++++++
7 files changed, 208 insertions(+), 11 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index c6bd079..ff3f55f 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -354,27 +354,61 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
// 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(ClassNode type) {
CompileUnit compileUnit = currentClass.getCompileUnit();
- Map<String, ClassNode> classesToCompile = compileUnit.getClassesToCompile();
+ String typeName = type.getName();
+
+ ModuleNode module = currentClass.getModule();
+ for (ImportNode importNode : module.getStaticImports().values()) {
+ String importFieldName = importNode.getFieldName();
+ String importAlias = importNode.getAlias();
- for (Map.Entry<String, ClassNode> entry : classesToCompile.entrySet()) {
- String enclosingClassName = entry.getKey();
- ClassNode enclosingClassNode = entry.getValue();
+ if (!typeName.equals(importAlias)) continue;
- String outerNestedClassName = tryToConstructOuterNestedClassName(type, enclosingClassName);
- if (null != outerNestedClassName) {
- compileUnit.addClassNodeToResolve(new ConstructedOuterNestedClassNode(enclosingClassNode, outerNestedClassName));
+ ConstructedOuterNestedClassNode constructedOuterNestedClassNode = tryToConstructOuterNestedClassNodeViaStaticImport(compileUnit, importNode, importFieldName);
+ if (null != constructedOuterNestedClassNode) {
+ compileUnit.addClassNodeToResolve(constructedOuterNestedClassNode);
return true;
}
}
- return false;
+ for (Map.Entry<String, ClassNode> entry : compileUnit.getClassesToCompile().entrySet()) {
+ ClassNode outerClassNode = entry.getValue();
+ ConstructedOuterNestedClassNode constructedOuterNestedClassNode = tryToConstructOuterNestedClassNode(type, outerClassNode);
+ if (null != constructedOuterNestedClassNode) {
+ compileUnit.addClassNodeToResolve(constructedOuterNestedClassNode);
+ return true;
+ }
+ }
+
+ boolean toResolveFurther = false;
+ for (ImportNode importNode : module.getStaticStarImports().values()) {
+ ConstructedOuterNestedClassNode constructedOuterNestedClassNode = tryToConstructOuterNestedClassNodeViaStaticImport(compileUnit, importNode, typeName);
+ if (null != constructedOuterNestedClassNode) {
+ compileUnit.addClassNodeToResolve(constructedOuterNestedClassNode);
+ toResolveFurther = true; // do not return here and try all static star imports because currently we do not know which outer class the class to resolve is declared in
+ }
+ }
+
+ return toResolveFurther;
+ }
+
+ private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNodeViaStaticImport(CompileUnit compileUnit, ImportNode importNode, String typeName) {
+ String importClassName = importNode.getClassName();
+ ClassNode outerClassNode = compileUnit.getClass(importClassName);
+
+ if (null == outerClassNode) return null;
+
+ String outerNestedClassName = importClassName + "$" + typeName.replace(".", "$");
+ return new ConstructedOuterNestedClassNode(outerClassNode, outerNestedClassName);
}
- private String tryToConstructOuterNestedClassName(ClassNode type, String enclosingClassName) {
+ private ConstructedOuterNestedClassNode tryToConstructOuterNestedClassNode(ClassNode type, ClassNode outerClassNode) {
+ String outerClassName = outerClassNode.getName();
+
for (String typeName = type.getName(), ident = typeName; ident.contains("."); ) {
ident = ident.substring(0, ident.lastIndexOf("."));
- if (enclosingClassName.endsWith(ident)) {
- return enclosingClassName + typeName.substring(ident.length()).replace(".", "$");
+ if (outerClassName.endsWith(ident)) {
+ String outerNestedClassName = outerClassName + typeName.substring(ident.length()).replace(".", "$");
+ return new ConstructedOuterNestedClassNode(outerClassNode, outerNestedClassName);
}
}
diff --git a/src/test-resources/groovy/bugs/groovy4287/Main.groovy b/src/test-resources/groovy/bugs/groovy4287/Main.groovy
new file mode 100644
index 0000000..a04077a
--- /dev/null
+++ b/src/test-resources/groovy/bugs/groovy4287/Main.groovy
@@ -0,0 +1,27 @@
+/*
+ * 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.groovy4287
+
+import static groovy.bugs.groovy4287.Outer.Inner
+import static groovy.bugs.groovy4287.Outer3.* // the static star import is used to test resolving, don't remove it
+import static groovy.bugs.groovy4287.Outer2.*
+
+assert "outer.inner" == new Inner().innerName
+assert "outer2.inner2" == new Inner2().innerName
+assert Inner2.class.name != null
diff --git a/src/test-resources/groovy/bugs/groovy4287/Main2.groovy b/src/test-resources/groovy/bugs/groovy4287/Main2.groovy
new file mode 100644
index 0000000..4f9feb8
--- /dev/null
+++ b/src/test-resources/groovy/bugs/groovy4287/Main2.groovy
@@ -0,0 +1,24 @@
+/*
+ * 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.groovy4287
+
+import static groovy.bugs.groovy4287.Outer.Inner as OIC
+
+assert "outer.inner" == new OIC().innerName
+
diff --git a/src/test-resources/groovy/bugs/groovy4287/Outer.groovy b/src/test-resources/groovy/bugs/groovy4287/Outer.groovy
new file mode 100644
index 0000000..6659f12
--- /dev/null
+++ b/src/test-resources/groovy/bugs/groovy4287/Outer.groovy
@@ -0,0 +1,25 @@
+/*
+ * 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.groovy4287
+
+class Outer {
+ static class Inner {
+ def innerName = "outer.inner"
+ }
+}
diff --git a/src/test-resources/groovy/bugs/groovy4287/Outer2.groovy b/src/test-resources/groovy/bugs/groovy4287/Outer2.groovy
new file mode 100644
index 0000000..0c0bf64
--- /dev/null
+++ b/src/test-resources/groovy/bugs/groovy4287/Outer2.groovy
@@ -0,0 +1,25 @@
+/*
+ * 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.groovy4287
+
+class Outer2 {
+ static class Inner2 {
+ def innerName = "outer2.inner2"
+ }
+}
diff --git a/src/test-resources/groovy/bugs/groovy4287/Outer3.groovy b/src/test-resources/groovy/bugs/groovy4287/Outer3.groovy
new file mode 100644
index 0000000..58732a3
--- /dev/null
+++ b/src/test-resources/groovy/bugs/groovy4287/Outer3.groovy
@@ -0,0 +1,25 @@
+/*
+ * 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.groovy4287
+
+class Outer3 {
+ static class Inner3 {
+ def innerName = "outer3.inner3"
+ }
+}
diff --git a/src/test/groovy/bugs/Groovy4287Bug.groovy b/src/test/groovy/bugs/Groovy4287Bug.groovy
new file mode 100644
index 0000000..9f3e79c
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy4287Bug.groovy
@@ -0,0 +1,37 @@
+/*
+ * 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.codehaus.groovy.tools.GroovyStarter
+
+class Groovy4287Bug extends GroovyTestCase {
+ void testResolvingOuterStaticNestedClass() {
+ def mainScriptPath = new File(this.getClass().getResource('/groovy/bugs/groovy4287/Main.groovy').toURI()).absolutePath
+ runScript(mainScriptPath)
+ }
+
+ void testResolvingOuterStaticNestedClassAlias() {
+ def mainScriptPath = new File(this.getClass().getResource('/groovy/bugs/groovy4287/Main2.groovy').toURI()).absolutePath
+ runScript(mainScriptPath)
+ }
+
+ static void runScript(String path) {
+ GroovyStarter.main(new String[] { "--main", "groovy.ui.GroovyMain", path })
+ }
+}