Skip to content

Commit 23a8af4

Browse files
committed
GROOVY-10166
1 parent 29ebe97 commit 23a8af4

4 files changed

Lines changed: 120 additions & 8 deletions

File tree

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,24 @@ public void testTypeChecked7363() {
794794
runNegativeTest(sources, "");
795795
}
796796

797+
@Test
798+
public void testTypeChecked7753() {
799+
//@formatter:off
800+
String[] sources = {
801+
"Main.groovy",
802+
"@groovy.transform.Field\n" +
803+
"String x = 'X'\n" +
804+
"@groovy.transform.TypeChecked\n" +
805+
"public List<String> getStrings() {\n" +
806+
" x ? [x] : Collections.emptyList()\n" +
807+
"}\n" +
808+
"print strings\n",
809+
};
810+
//@formatter:on
811+
812+
runConformTest(sources, "[X]");
813+
}
814+
797815
@Test
798816
public void testTypeChecked7804() {
799817
//@formatter:off
@@ -3100,6 +3118,45 @@ public void testTypeChecked10111a() {
31003118
runConformTest(sources);
31013119
}
31023120

3121+
@Test
3122+
public void testTypeChecked10166() {
3123+
//@formatter:off
3124+
String[] sources = {
3125+
"Main.groovy",
3126+
"@groovy.transform.TypeChecked\n" +
3127+
"@SuppressWarnings('rawtypes')\n" +
3128+
"abstract class A<T extends C> {\n" +
3129+
" T getC() {\n" +
3130+
" }\n" +
3131+
" Map toMap() {\n" +
3132+
" c.getMap(this)\n" +
3133+
" }\n" +
3134+
"}\n" +
3135+
"@groovy.transform.TypeChecked\n" +
3136+
"@SuppressWarnings('rawtypes')\n" +
3137+
"class C<T extends A> {\n" +
3138+
" Map getMap(T a) {\n" +
3139+
" }\n" +
3140+
" T getObj(Map m) {\n" +
3141+
" A a = null\n" +
3142+
" a.c.get(1)\n" +
3143+
" }\n" +
3144+
" T get(int i) {\n" +
3145+
" }\n" +
3146+
"}\n" +
3147+
"new C()\n",
3148+
};
3149+
//@formatter:on
3150+
3151+
runNegativeTest(sources,
3152+
"----------\n" +
3153+
"1. ERROR in Main.groovy (at line 17)\n" +
3154+
"\ta.c.get(1)\n" +
3155+
"\t^^^^^^^^^^\n" +
3156+
"Groovy:[Static type checking] - Cannot find matching method A#get(int). Please check if the declared type is correct and if the method exists.\n" +
3157+
"----------\n");
3158+
}
3159+
31033160
@Test
31043161
public void testTypeChecked10179() {
31053162
//@formatter:off

base/org.codehaus.groovy25/src/org/codehaus/groovy/ast/tools/GenericsUtils.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
import java.util.Objects;
5555
import java.util.concurrent.atomic.AtomicReference;
5656

57-
import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName;
5857
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.plus;
5958
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCorrectedClassNode;
6059
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf;
@@ -142,8 +141,8 @@ public static GenericsType buildWildcardType(final ClassNode... types) {
142141
return gt;
143142
}
144143

145-
public static Map<GenericsTypeName, GenericsType> extractPlaceholders(ClassNode cn) {
146-
Map<GenericsTypeName, GenericsType> ret = new HashMap<GenericsTypeName, GenericsType>();
144+
public static Map<GenericsType.GenericsTypeName, GenericsType> extractPlaceholders(ClassNode cn) {
145+
Map<GenericsType.GenericsTypeName, GenericsType> ret = new HashMap<>();
147146
extractPlaceholders(cn, ret);
148147
return ret;
149148
}
@@ -155,7 +154,7 @@ public static Map<GenericsTypeName, GenericsType> extractPlaceholders(ClassNode
155154
* @param node the class node to check
156155
* @param map the generics type information collector
157156
*/
158-
public static void extractPlaceholders(ClassNode node, Map<GenericsTypeName, GenericsType> map) {
157+
public static void extractPlaceholders(ClassNode node, Map<GenericsType.GenericsTypeName, GenericsType> map) {
159158
if (node == null) return;
160159

161160
if (node.isArray()) {
@@ -198,7 +197,7 @@ public static void extractPlaceholders(ClassNode node, Map<GenericsTypeName, Gen
198197
for (int i = 0; i < redirectGenericsTypes.length; i++) {
199198
GenericsType redirectType = redirectGenericsTypes[i];
200199
if (redirectType.isPlaceholder()) {
201-
GenericsTypeName name = new GenericsTypeName(redirectType.getName());
200+
GenericsType.GenericsTypeName name = new GenericsType.GenericsTypeName(redirectType.getName());
202201
if (!map.containsKey(name)) {
203202
GenericsType value = parameterized[i];
204203
map.put(name, value);
@@ -941,7 +940,7 @@ private static Map<GenericsType, GenericsType> makeDeclaringAndActualGenericsTyp
941940

942941
private static Tuple2<Map<GenericsType, GenericsType>, ClassNode> doMakeDeclaringAndActualGenericsTypeMap(ClassNode declaringClass, ClassNode actualReceiver, boolean tryToFindExactType) {
943942
ClassNode parameterizedType = findParameterizedTypeFromCache(declaringClass, actualReceiver, tryToFindExactType);
944-
943+
/* GRECLIPSE edit -- GROOVY-10166
945944
if (parameterizedType == null) {
946945
return new Tuple2<>(Collections.<GenericsType,GenericsType>emptyMap(), parameterizedType);
947946
}
@@ -953,6 +952,22 @@ private static Tuple2<Map<GenericsType, GenericsType>, ClassNode> doMakeDeclarin
953952
result = connectGenericsTypes(result);
954953
955954
return new Tuple2<>(result, parameterizedType);
955+
*/
956+
if (parameterizedType != null && parameterizedType.isRedirectNode() && !parameterizedType.isGenericsPlaceHolder()) {
957+
// declaringClass may be "List<T> -> List<E>" and parameterizedType may be "List<String> -> List<E>"
958+
GenericsType[] targetGenericsTypes = parameterizedType.redirect().getGenericsTypes();
959+
if (targetGenericsTypes != null) {
960+
GenericsType[] sourceGenericsTypes = parameterizedType.getGenericsTypes();
961+
if (sourceGenericsTypes == null) sourceGenericsTypes = EMPTY_GENERICS_ARRAY;
962+
Map<GenericsType, GenericsType> map = new LinkedHashMap<>();
963+
for (int i = 0, m = sourceGenericsTypes.length, n = targetGenericsTypes.length; i < n; i += 1) {
964+
map.put(targetGenericsTypes[i], i < m ? sourceGenericsTypes[i] : targetGenericsTypes[i]);
965+
}
966+
return new Tuple2<>(map, parameterizedType);
967+
}
968+
}
969+
return new Tuple2<>(Collections.emptyMap(), parameterizedType);
970+
// GRECLIPSE end
956971
}
957972

958973
private static Map<GenericsType, GenericsType> connectGenericsTypes(Map<GenericsType, GenericsType> genericsTypeMap) {
@@ -999,6 +1014,7 @@ private static boolean checkPlaceHolders(final ClassNode parameterizedType, fina
9991014
return false;
10001015
}
10011016

1017+
/* GRECLIPSE edit
10021018
private static Map<GenericsType, GenericsType> makePlaceholderAndParameterizedTypeMap(ClassNode declaringClass) {
10031019
if (declaringClass == null) {
10041020
return Collections.emptyMap();
@@ -1016,6 +1032,7 @@ private static Map<GenericsType, GenericsType> makePlaceholderAndParameterizedTy
10161032
}
10171033
return result;
10181034
}
1035+
*/
10191036

10201037
/**
10211038
* Get the actual type according to the placeholder name

base/org.codehaus.groovy30/src/org/codehaus/groovy/ast/tools/GenericsUtils.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@ private static Map<GenericsType, GenericsType> makeDeclaringAndActualGenericsTyp
866866

867867
private static Tuple2<Map<GenericsType, GenericsType>, ClassNode> doMakeDeclaringAndActualGenericsTypeMap(final ClassNode declaringClass, final ClassNode actualReceiver, final boolean tryToFindExactType) {
868868
ClassNode parameterizedType = findParameterizedTypeFromCache(declaringClass, actualReceiver, tryToFindExactType);
869+
/* GRECLIPSE edit -- GROOVY-10166
869870
if (parameterizedType == null) {
870871
return tuple(Collections.emptyMap(), parameterizedType);
871872
}
@@ -877,8 +878,25 @@ private static Tuple2<Map<GenericsType, GenericsType>, ClassNode> doMakeDeclarin
877878
result = connectGenericsTypes(result);
878879
879880
return tuple(result, parameterizedType);
881+
*/
882+
if (parameterizedType != null && parameterizedType.isRedirectNode() && !parameterizedType.isGenericsPlaceHolder()) {
883+
// declaringClass may be "List<T> -> List<E>" and parameterizedType may be "List<String> -> List<E>"
884+
GenericsType[] targetGenericsTypes = parameterizedType.redirect().getGenericsTypes();
885+
if (targetGenericsTypes != null) {
886+
GenericsType[] sourceGenericsTypes = parameterizedType.getGenericsTypes();
887+
if (sourceGenericsTypes == null) sourceGenericsTypes = EMPTY_GENERICS_ARRAY;
888+
Map<GenericsType, GenericsType> map = new LinkedHashMap<>();
889+
for (int i = 0, m = sourceGenericsTypes.length, n = targetGenericsTypes.length; i < n; i += 1) {
890+
map.put(targetGenericsTypes[i], i < m ? sourceGenericsTypes[i] : targetGenericsTypes[i]);
891+
}
892+
return tuple(map, parameterizedType);
893+
}
894+
}
895+
return tuple(Collections.emptyMap(), parameterizedType);
896+
// GRECLIPSE end
880897
}
881898

899+
/* GRECLIPSE edit
882900
private static Map<GenericsType, GenericsType> makePlaceholderAndParameterizedTypeMap(final ClassNode declaringClass) {
883901
if (null == declaringClass) {
884902
return Collections.emptyMap();
@@ -898,6 +916,7 @@ private static Map<GenericsType, GenericsType> makePlaceholderAndParameterizedTy
898916
899917
return result;
900918
}
919+
*/
901920

902921
private static Map<GenericsType, GenericsType> connectGenericsTypes(final Map<GenericsType, GenericsType> genericsTypeMap) {
903922
Map<GenericsType, GenericsType> result = new LinkedHashMap<>();

base/org.codehaus.groovy40/src/org/codehaus/groovy/ast/tools/GenericsUtils.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,19 +865,36 @@ private static Map<GenericsType, GenericsType> makeDeclaringAndActualGenericsTyp
865865

866866
private static Tuple2<Map<GenericsType, GenericsType>, ClassNode> doMakeDeclaringAndActualGenericsTypeMap(final ClassNode declaringClass, final ClassNode actualReceiver, final boolean tryToFindExactType) {
867867
ClassNode parameterizedType = findParameterizedTypeFromCache(declaringClass, actualReceiver, tryToFindExactType);
868+
/* GRECLIPSE edit -- GROOVY-10166
868869
if (parameterizedType == null) {
869870
return tuple(Collections.emptyMap(), parameterizedType);
870871
}
871-
872872
Map<GenericsType, GenericsType> result = new LinkedHashMap<>();
873873
result.putAll(makePlaceholderAndParameterizedTypeMap(declaringClass));
874874
result.putAll(makePlaceholderAndParameterizedTypeMap(parameterizedType));
875875
876876
result = connectGenericsTypes(result);
877877
878878
return tuple(result, parameterizedType);
879+
*/
880+
if (parameterizedType != null && parameterizedType.isRedirectNode() && !parameterizedType.isGenericsPlaceHolder()) {
881+
// declaringClass may be "List<T> -> List<E>" and parameterizedType may be "List<String> -> List<E>"
882+
GenericsType[] targetGenericsTypes = parameterizedType.redirect().getGenericsTypes();
883+
if (targetGenericsTypes != null) {
884+
GenericsType[] sourceGenericsTypes = parameterizedType.getGenericsTypes();
885+
if (sourceGenericsTypes == null) sourceGenericsTypes = EMPTY_GENERICS_ARRAY;
886+
Map<GenericsType, GenericsType> map = new LinkedHashMap<>();
887+
for (int i = 0, m = sourceGenericsTypes.length, n = targetGenericsTypes.length; i < n; i += 1) {
888+
map.put(targetGenericsTypes[i], i < m ? sourceGenericsTypes[i] : targetGenericsTypes[i]);
889+
}
890+
return tuple(map, parameterizedType);
891+
}
892+
}
893+
return tuple(Collections.emptyMap(), parameterizedType);
894+
// GRECLIPSE end
879895
}
880896

897+
/* GRECLIPSE edit
881898
private static Map<GenericsType, GenericsType> makePlaceholderAndParameterizedTypeMap(final ClassNode declaringClass) {
882899
if (null == declaringClass) {
883900
return Collections.emptyMap();
@@ -897,6 +914,7 @@ private static Map<GenericsType, GenericsType> makePlaceholderAndParameterizedTy
897914
898915
return result;
899916
}
917+
*/
900918

901919
private static Map<GenericsType, GenericsType> connectGenericsTypes(final Map<GenericsType, GenericsType> genericsTypeMap) {
902920
Map<GenericsType, GenericsType> result = new LinkedHashMap<>();
@@ -1010,7 +1028,8 @@ public static Tuple2<ClassNode[], ClassNode> parameterizeSAM(final ClassNode sam
10101028
Map<GenericsType, GenericsType> generics = makeDeclaringAndActualGenericsTypeMapOfExactType(abstractMethod.getDeclaringClass(), samType);
10111029
Function<ClassNode, ClassNode> resolver = t -> {
10121030
if (t.isGenericsPlaceHolder()) {
1013-
return findActualTypeByGenericsPlaceholderName(t.getUnresolvedName(), generics);
1031+
ClassNode type = findActualTypeByGenericsPlaceholderName(t.getUnresolvedName(), generics);
1032+
return type;
10141033
}
10151034
return t;
10161035
};

0 commit comments

Comments
 (0)