diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java index 380a7cb06..552733913 100644 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java +++ b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/validation/WurstValidator.java @@ -1742,7 +1742,7 @@ private void checkParams(Element where, String preMsg, List args, List paramTypes = Lists.newArrayList(); + // Build expected param types in the subclass binding context + List expected = Lists.newArrayList(); + + // The binding that maps the superclass type params to the subclass type args + VariableBinding binding = extendedClass.getTypeArgBinding(); + for (WParameter p : sc.getParameters()) { - paramTypes.add(p.attrTyp()); + WurstType t = p.attrTyp(); + t = t.setTypeArgs(binding); + + expected.add(t); } + if (d.getSuperConstructorCall() instanceof NoSuperConstructorCall - && paramTypes.size() > 0) { + && !expected.isEmpty()) { c.addError("The extended class <" + extendedClass.getName() + "> does not expose a no-arg constructor. " + - "You must define a constructor that calls super(..) appropriately, in this class."); + "You must define a constructor that calls super(..) appropriately, in this class."); } else { - checkParams(d, "Incorrect call to super constructor: ", superArgs(d), paramTypes); + checkParams(d, "Incorrect call to super constructor: ", superArgs(d), expected); } } } @@ -2390,6 +2398,7 @@ private void checkConstructor(ConstructorDef d) { } + private void checkArrayAccess(ExprVarArrayAccess ea) { checkNameRefDeprecated(ea, ea.tryGetNameDef()); for (Expr index : ea.getIndexes()) { diff --git a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java index af0ec3d4e..458a1074d 100644 --- a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java +++ b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java @@ -1472,5 +1472,41 @@ public void callingDestroyThisInConstructor() { " testSuccess()", "endpackage"); } + @Test + public void derivedGenericClassConstructor() { + testAssertOkLinesWithStdLib(true, + "package test", + "import LinkedList", + "public class ListIterator extends LLIterator", + " construct(LinkedList parent)", + " super(parent)", + "init", + " let b = new ListIterator(new LinkedList())", + " if b != null", + " testSuccess()", + "endpackage"); + } + + @Test + public void derivedGenericClassConstructorNewGenerics() { + testAssertOkLines(true, + "package test", + "native testSuccess()", + "class A", + " T value", + "class B", + " A a", + " construct(A a)", + " this.a = a", + "public class C extends B", + " construct(A parent)", + " super(parent)", + "init", + " let b = new C(new A())", + " if b != null", + " testSuccess()", + "endpackage"); + } + }