Skip to content

Commit

Permalink
GROOVY-9074, GROOVY-10651: STC: propagate generics to super class
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Nov 18, 2024
1 parent 0e6ccef commit 9435d96
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
import static org.codehaus.groovy.ast.ClassHelper.double_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.findSAM;
import static org.codehaus.groovy.ast.ClassHelper.float_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.getNextSuperClass;
import static org.codehaus.groovy.ast.ClassHelper.getUnwrapper;
import static org.codehaus.groovy.ast.ClassHelper.getWrapper;
import static org.codehaus.groovy.ast.ClassHelper.int_TYPE;
Expand Down Expand Up @@ -1753,8 +1754,20 @@ static void extractGenericsConnections(final Map<GenericsTypeName, GenericsType>
extractGenericsConnections(connections, type.getNodeMetaData("outer.class"), target.getOuterClass()); //GROOVY-10646

} else if (implementsInterfaceOrIsSubclassOf(type, target)) {
ClassNode goal = GenericsUtils.parameterizeType(type, target);
extractGenericsConnections(connections, goal.getGenericsTypes(), target.getGenericsTypes());
ClassNode superClass = getNextSuperClass(type, target);
if (GenericsUtils.hasUnresolvedGenerics(superClass)) {
// propagate type arguments to the super class or interface
Map<GenericsTypeName, GenericsType> spec = new HashMap<>();
if (type.getGenericsTypes() != null) {
extractGenericsConnections(spec, type, type.redirect());
} else if (type.redirect().getGenericsTypes() != null) {
for (GenericsType tp : type.redirect().getGenericsTypes()) {
spec.put(new GenericsTypeName(tp.getName()), new GenericsType(getCombinedBoundType(tp))); //GROOVY-10651
}
}
superClass = applyGenericsContext(spec, superClass);
}
extractGenericsConnections(connections, superClass, target);
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/codehaus/groovy/vmplugin/v8/Java8.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@ private ClassNode configureWildcardType(final WildcardType wildcardType) {
private ClassNode configureParameterizedType(final ParameterizedType parameterizedType) {
ClassNode base = configureType(parameterizedType.getRawType());
GenericsType[] gts = configureTypeArguments(parameterizedType.getActualTypeArguments());
// fix erasure : ResolveVisitor#resolveWildcardBounding
final int n; if (gts != null && (n = gts.length) > 0) {
for (int i = 0; i < n; i += 1) { GenericsType gt = gts[i];
if (!gt.isWildcard() || gt.getUpperBounds() != null) continue;
ClassNode[] ubs = base.redirect().getGenericsTypes()[i].getUpperBounds();
if (ubs != null && !ClassHelper.OBJECT_TYPE.equals(ubs[0])) gt.getType().setRedirect(ubs[0]);
}
}
base.setGenericsTypes(gts);
return base;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -946,11 +946,11 @@ class ArraysAndCollectionsSTCTest extends StaticTypeCheckingTestCase {
}

// GROOVY-6266
void testMapKeyGenerics() {
void testMapGenerics() {
assertScript '''
Map<String, ? extends List<? extends List>> map = new HashMap<>()
map.get('key',[['val1'],['val2']])
assert map.'key'[0] == ['val1']
Map<String, List<List>> map = new HashMap<>()
map.get('key', [(List)['val1'],['val2']])
assert map.key[0] == ['val1']
'''
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1264,7 +1264,7 @@ class ClosureParamTypeInferenceSTCTest extends StaticTypeCheckingTestCase {
'''
}
void testDGM_eachWithIndexOnRecursiveIterable() { // GROOVY-10651
['', '<?>'].each { args ->
for (args in ['','<?>']) {
assertScript """
void proc(groovy.transform.stc.TreeNode$args node) {
node.eachWithIndex { child, index ->
Expand Down
4 changes: 2 additions & 2 deletions src/test/groovy/transform/stc/GenericsSTCTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {

void testAddOnListUsingLeftShift3() {
shouldFailWithMessages '''
def list = (List<? extends Number>) []
List<? extends Number> list = []
list << 1
''',
'Cannot call <T> org.codehaus.groovy.runtime.DefaultGroovyMethods#leftShift(java.util.List<T>, T) with arguments [java.util.List<? extends java.lang.Number>, int]'
'Cannot call <T> org.codehaus.groovy.runtime.DefaultGroovyMethods#leftShift(java.util.List<T>, T) with arguments [java.util.ArrayList<? extends java.lang.Number>, int]'
}

void testAddOnListWithDiamondUsingLeftShift() {
Expand Down

0 comments on commit 9435d96

Please sign in to comment.