Skip to content

Commit 8cf63f5

Browse files
committed
GROOVY-10699, GROOVY-10700, GROOVY-10701
1 parent 6d80c05 commit 8cf63f5

File tree

6 files changed

+223
-165
lines changed

6 files changed

+223
-165
lines changed

base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java

+73
Original file line numberDiff line numberDiff line change
@@ -6021,4 +6021,77 @@ public void testTypeChecked10673() {
60216021

60226022
runConformTest(sources, "1");
60236023
}
6024+
6025+
@Test
6026+
public void testTypeChecked10699() {
6027+
for (String type : new String[] {"java.util.function.Function<T,T>", "java.util.function.UnaryOperator<T>"}) {
6028+
//@formatter:off
6029+
String[] sources = {
6030+
"Main.groovy",
6031+
"def <T> void m(" + type + " f) {\n" +
6032+
" print(f.apply(null))\n" +
6033+
"}\n" +
6034+
"@groovy.transform.TypeChecked\n" +
6035+
"void test() {\n" +
6036+
" m { Double d -> d }\n" +
6037+
"}\n" +
6038+
"test()\n",
6039+
};
6040+
//@formatter:on
6041+
6042+
runConformTest(sources, "null");
6043+
}
6044+
}
6045+
6046+
@Test
6047+
public void testTypeChecked10700() {
6048+
//@formatter:off
6049+
String[] sources = {
6050+
"Main.groovy",
6051+
"class D extends C {\n" + // implements A
6052+
" @groovy.transform.TypeChecked\n" +
6053+
" void test() {\n" +
6054+
" print(decode('works'))\n" +
6055+
" }\n" +
6056+
"}\n" +
6057+
"new D().test()\n",
6058+
6059+
"Peer.groovy",
6060+
"interface A {\n" +
6061+
" String decode(String s)\n" +
6062+
"}\n" +
6063+
"class B implements A {\n" +
6064+
" String decode(String s) { s }\n" +
6065+
"}\n" +
6066+
"class C implements A {\n" +
6067+
" @Delegate(interfaces=false)\n" +
6068+
" private final B b = new B()\n" +
6069+
"}\n",
6070+
};
6071+
//@formatter:on
6072+
6073+
runConformTest(sources, "works");
6074+
}
6075+
6076+
@Test
6077+
public void testTypeChecked10701() {
6078+
//@formatter:off
6079+
String[] sources = {
6080+
"Main.groovy",
6081+
"def <T> T m1(java.util.function.UnaryOperator<T> op) {\n" +
6082+
" return op.apply(null)\n" +
6083+
"}\n" +
6084+
"double m2(double d) {\n" +
6085+
" return Math.PI\n" +
6086+
"}\n" +
6087+
"@groovy.transform.TypeChecked\n" +
6088+
"void test() {\n" +
6089+
" print(m1(true ? { Double d -> 42.0d } : this.&m2))\n" +
6090+
"}\n" +
6091+
"test()\n",
6092+
};
6093+
//@formatter:on
6094+
6095+
runConformTest(sources, "42.0");
6096+
}
60246097
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -4840,13 +4840,14 @@ public void visitTernaryExpression(final TernaryExpression expression) {
48404840
falseExpression.visit(this);
48414841
ClassNode resultType;
48424842
ClassNode typeOfFalse = getType(falseExpression);
4843-
// handle instanceof cases
4843+
/* GRECLIPSE edit -- GROOVY-10701
48444844
if (hasInferredReturnType(falseExpression)) {
48454845
typeOfFalse = getInferredReturnType(falseExpression);
48464846
}
48474847
if (hasInferredReturnType(trueExpression)) {
48484848
typeOfTrue = getInferredReturnType(trueExpression);
48494849
}
4850+
*/
48504851
/* GRECLIPSE edit -- GROOVY-9972
48514852
typeOfFalse = checkForTargetType(falseExpression, typeOfFalse);
48524853
typeOfTrue = checkForTargetType(trueExpression, typeOfTrue);

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

+4-1
Original file line numberDiff line numberDiff line change
@@ -4654,8 +4654,11 @@ && isOrImplements(typeOfFalse, typeOfTrue))) { // List/Collection/Iterable : []
46544654
* @param type the inferred type of {@code expr}
46554655
*/
46564656
private ClassNode checkForTargetType(final Expression expr, final ClassNode type) {
4657+
/* GRECLIPSE edit -- GROOVY-10701
46574658
ClassNode sourceType = Optional.ofNullable(getInferredReturnType(expr)).orElse(type);
4658-
4659+
*/
4660+
ClassNode sourceType = type;
4661+
// GRECLIPSE end
46594662
ClassNode targetType = null;
46604663
MethodNode enclosingMethod = typeCheckingContext.getEnclosingMethod();
46614664
BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();

base/org.codehaus.groovy40/src/org/codehaus/groovy/ast/ClassHelper.java

+1
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ public static boolean isGeneratedFunction(final ClassNode type) {
610610
* @return the method node if type is a SAM type, null otherwise
611611
*/
612612
public static MethodNode findSAM(final ClassNode type) {
613+
if (type == null) return null;
613614
if (type.isInterface()) {
614615
MethodNode sam = null;
615616
for (MethodNode mn : type.getAbstractMethods()) {

base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1721,7 +1721,7 @@ private static boolean equalIncludingGenerics(final ClassNode one, final ClassNo
17211721
* Should the target not have any generics this method does nothing.
17221722
*/
17231723
static void extractGenericsConnections(final Map<GenericsTypeName, GenericsType> connections, final ClassNode type, final ClassNode target) {
1724-
if (target == null || target == type || !isUsingGenericsOrIsArrayUsingGenerics(target)) return;
1724+
if (target == null || target == type || (!target.isGenericsPlaceHolder() && !isUsingGenericsOrIsArrayUsingGenerics(target))) return;
17251725
if (type == null || type == UNKNOWN_PARAMETER_TYPE) return;
17261726

17271727
if (target.isGenericsPlaceHolder()) {

0 commit comments

Comments
 (0)