Skip to content

Commit ca15457

Browse files
committed
Correctly set type args binding for derived classes, fixes #871
1 parent 7588a14 commit ca15457

File tree

2 files changed

+53
-8
lines changed

2 files changed

+53
-8
lines changed

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,7 +1742,7 @@ private void checkParams(Element where, String preMsg, List<Expr> args, List<Wur
17421742
// if (expected instanceof AstElementWithTypeArgs)
17431743
if (!actual.isSubtypeOf(expected, where)) {
17441744
args.get(i).addError(
1745-
preMsg + "Expected " + expected + " as parameter " + (i + 1) + " but found " + actual);
1745+
preMsg + "Expected " + expected + " as parameter " + (i + 1) + " but found " + actual);
17461746
}
17471747
}
17481748
}
@@ -2356,22 +2356,30 @@ private void checkConstructor(ConstructorDef d) {
23562356
WurstTypeClass ct = c.attrTypC();
23572357
WurstTypeClass extendedClass = ct.extendedClass();
23582358
if (extendedClass != null) {
2359-
// check if super constructor is called correctly...
2360-
// TODO check constr: get it from ct so that it has the correct type binding
2359+
// Use the *bound* super-constructor signature
23612360
ConstructorDef sc = d.attrSuperConstructor();
23622361
if (sc == null) {
23632362
d.addError("No super constructor found.");
23642363
} else {
2365-
List<WurstType> paramTypes = Lists.newArrayList();
2364+
// Build expected param types in the subclass binding context
2365+
List<WurstType> expected = Lists.newArrayList();
2366+
2367+
// The binding that maps the superclass type params to the subclass type args
2368+
VariableBinding binding = extendedClass.getTypeArgBinding();
2369+
23662370
for (WParameter p : sc.getParameters()) {
2367-
paramTypes.add(p.attrTyp());
2371+
WurstType t = p.attrTyp();
2372+
t = t.setTypeArgs(binding);
2373+
2374+
expected.add(t);
23682375
}
2376+
23692377
if (d.getSuperConstructorCall() instanceof NoSuperConstructorCall
2370-
&& paramTypes.size() > 0) {
2378+
&& !expected.isEmpty()) {
23712379
c.addError("The extended class <" + extendedClass.getName() + "> does not expose a no-arg constructor. " +
2372-
"You must define a constructor that calls super(..) appropriately, in this class.");
2380+
"You must define a constructor that calls super(..) appropriately, in this class.");
23732381
} else {
2374-
checkParams(d, "Incorrect call to super constructor: ", superArgs(d), paramTypes);
2382+
checkParams(d, "Incorrect call to super constructor: ", superArgs(d), expected);
23752383
}
23762384
}
23772385
}
@@ -2383,6 +2391,7 @@ private void checkConstructor(ConstructorDef d) {
23832391
}
23842392

23852393

2394+
23862395
private void checkArrayAccess(ExprVarArrayAccess ea) {
23872396
checkNameRefDeprecated(ea, ea.tryGetNameDef());
23882397
for (Expr index : ea.getIndexes()) {

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,5 +1459,41 @@ public void duplicateNameInClassHierachy() {
14591459
"endpackage");
14601460
}
14611461

1462+
@Test
1463+
public void derivedGenericClassConstructor() {
1464+
testAssertOkLinesWithStdLib(true,
1465+
"package test",
1466+
"import LinkedList",
1467+
"public class ListIterator<T> extends LLIterator<T>",
1468+
" construct(LinkedList<T> parent)",
1469+
" super(parent)",
1470+
"init",
1471+
" let b = new ListIterator<int>(new LinkedList<int>())",
1472+
" if b != null",
1473+
" testSuccess()",
1474+
"endpackage");
1475+
}
1476+
1477+
@Test
1478+
public void derivedGenericClassConstructorNewGenerics() {
1479+
testAssertOkLines(true,
1480+
"package test",
1481+
"native testSuccess()",
1482+
"class A<T:>",
1483+
" T value",
1484+
"class B<X:>",
1485+
" A<X> a",
1486+
" construct(A<X> a)",
1487+
" this.a = a",
1488+
"public class C<T:> extends B<T>",
1489+
" construct(A<T> parent)",
1490+
" super(parent)",
1491+
"init",
1492+
" let b = new C<int>(new A<int>())",
1493+
" if b != null",
1494+
" testSuccess()",
1495+
"endpackage");
1496+
}
1497+
14621498

14631499
}

0 commit comments

Comments
 (0)