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 2020/06/10 17:23:13 UTC
[groovy] 01/01: GROOVY-7549: STC: if "=" RHS type is inaccessible,
revert to origin type
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY-7549
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 4a6d667d2ca6d15d06bbf62834a02a57b3fa5841
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Jun 10 12:22:45 2020 -0500
GROOVY-7549: STC: if "=" RHS type is inaccessible, revert to origin type
---
.../transform/stc/StaticTypeCheckingVisitor.java | 9 ++++
.../transform/stc/TypeInferenceSTCTest.groovy | 62 ++++++++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index a0b10eb..e2e85f9 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -843,6 +843,15 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
} else if (lType.isUsingGenerics() && !lType.isEnum() && hasRHSIncompleteGenericTypeInfo(resultType)) {
// for example, LHS is List<ConcreteClass> and RHS is List<T> where T is a placeholder
resultType = lType;
+ } else {
+ // GROOVY-7549: RHS type may not be accessible to enclosing class
+ int modifiers = resultType.getModifiers();
+ ClassNode enclosingType = typeCheckingContext.getEnclosingClassNode();
+ if (!Modifier.isPublic(modifiers) && !enclosingType.equals(resultType)
+ && !getOutermost(enclosingType).equals(getOutermost(resultType))
+ && (Modifier.isPrivate(modifiers) || !Objects.equals(enclosingType.getPackageName(), resultType.getPackageName()))) {
+ resultType = originType; // TODO: Find accesible type in hierarchy of resultType?
+ }
}
// make sure we keep primitive types
diff --git a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
index 93fadb4..a522fc6 100644
--- a/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
+++ b/src/test/groovy/transform/stc/TypeInferenceSTCTest.groovy
@@ -23,7 +23,9 @@ import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.ast.MethodNode
import org.codehaus.groovy.ast.tools.WideningCategories
import org.codehaus.groovy.classgen.GeneratorContext
+import org.codehaus.groovy.control.CompilationUnit
import org.codehaus.groovy.control.CompilePhase
+import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.control.customizers.CompilationCustomizer
import org.codehaus.groovy.transform.stc.StaticTypesMarker
@@ -930,6 +932,66 @@ class TypeInferenceSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-7549
+ void testShouldKeepDeclTypeWhenAssignedInaccessibleT() {
+ def cc = new CompilerConfiguration(config)
+ cc.addCompilationCustomizers(*config.compilationCustomizers) // GROOVY-9585: delete this line once fixed
+ cc.targetDirectory = File.createTempDir()
+ def parentDir = File.createTempDir()
+ try {
+ new File(parentDir, 'a').mkdir()
+ new File(parentDir, 'b').mkdir()
+
+ def a = new File(parentDir, 'a/Main.groovy')
+ a.write '''
+ package a
+ class Main {
+ static main(args) {
+ Face f = b.Maker.make() // returns b.Impl
+ assert f.meth() == 1234
+ }
+ }
+ '''
+ def b = new File(parentDir, 'a/Face.groovy')
+ b.write '''
+ package a
+ interface Face {
+ int meth()
+ }
+ '''
+ def c = new File(parentDir, 'b/Impl.groovy')
+ c.write '''
+ package b
+ @groovy.transform.PackageScope
+ class Impl implements a.Face {
+ int meth() {
+ 1234
+ }
+ }
+ '''
+ def d = new File(parentDir, 'b/Maker.groovy')
+ d.write '''
+ package b
+ class Maker {
+ static Impl make() { // probably should return a.Face
+ new Impl()
+ }
+ }
+ '''
+
+ def loader = new GroovyClassLoader(this.class.classLoader)
+ def cu = new CompilationUnit(cc, null, loader)
+ cu.addSources(a, b, c, d)
+ cu.compile()
+
+ loader.addClasspath(cc.targetDirectory.absolutePath)
+ loader.loadClass('a.Main', true).main()
+ } finally {
+ cc.targetDirectory.deleteDir()
+ parentDir.deleteDir()
+ }
+ }
+
// GROOVY-9077
void testInferredTypeForPropertyThatResolvesToMethod() {
assertScript '''