Skip to content

Commit

Permalink
GROOVY-11274: STC: check implicit super class constrctor call
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-milles committed Sep 30, 2024
1 parent c6d0cb5 commit aa29833
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@
import static org.codehaus.groovy.ast.tools.GeneralUtils.castX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorSuperX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.defaultValueX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.elvisX;
Expand Down Expand Up @@ -2840,6 +2841,12 @@ protected void visitConstructorOrMethod(final MethodNode node, final boolean isC
}
if (!isConstructor) {
returnAdder.visitMethod(node); // GROOVY-7753: we cannot count these auto-generated return statements, see `typeCheckingContext.pushEnclosingReturnStatement`
} else if (!((ConstructorNode) node).firstStatementIsSpecialConstructorCall()) {
ClassNode superClass = node.getDeclaringClass().getSuperClass(); // GROOVY-11274: check implicit "super()"
boolean isInnerClass = superClass.getOuterClass() != null && !Modifier.isStatic(superClass.getModifiers());
Expression superCall = ctorSuperX(args(isInnerClass ? List.of(castX(superClass.getOuterClass(), nullX())) : List.of()));
if (node.getCode() != null) superCall.setSourcePosition(node.getCode());
superCall.visit(this);
}
typeCheckingContext.popEnclosingMethod();
}
Expand Down
33 changes: 28 additions & 5 deletions src/test/groovy/transform/stc/ConstructorsSTCTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ class ConstructorsSTCTest extends StaticTypeCheckingTestCase {
int y
}
A a = [x:100, y:200, z: 300]
''', 'No such property: z for class: A'
''',
'No such property: z for class: A'
}

void testConstructWithNamedParamsAndMissingProperty() {
Expand All @@ -255,7 +256,8 @@ class ConstructorsSTCTest extends StaticTypeCheckingTestCase {
int y
}
A a = new A(x:100, y:200, z: 300)
''', 'No such property: z for class: A'
''',
'No such property: z for class: A'
}

void testConstructFromValuedMapAndIncorrectTypes() {
Expand All @@ -265,7 +267,8 @@ class ConstructorsSTCTest extends StaticTypeCheckingTestCase {
int y
}
A a = [x:'100', y:200]
''', 'Cannot assign value of type java.lang.String to variable of type int'
''',
'Cannot assign value of type java.lang.String to variable of type int'
}

void testConstructFromValuedMapAndDynamicKey() {
Expand All @@ -275,7 +278,8 @@ class ConstructorsSTCTest extends StaticTypeCheckingTestCase {
int y
}
A a = ["${'x'}":'100']
''', 'Dynamic keys in map-style constructors are unsupported'
''',
'Dynamic keys in map-style constructors are unsupported'
}

void testConstructWithMapAndInheritance() {
Expand Down Expand Up @@ -434,7 +438,8 @@ class ConstructorsSTCTest extends StaticTypeCheckingTestCase {
ByteArrayOutputStream out
}
void m(OutputStream o) { new Foo(out:o) }
''', 'Cannot assign value of type java.io.OutputStream to variable of type java.io.ByteArrayOutputStream'
''',
'Cannot assign value of type java.io.OutputStream to variable of type java.io.ByteArrayOutputStream'
}

void testTypeCheckingInfoShouldNotBeAddedToConstructor() {
Expand Down Expand Up @@ -590,4 +595,22 @@ class ConstructorsSTCTest extends StaticTypeCheckingTestCase {
assert new A().test() == ['value']
'''
}

// GROOVY-11274
void testPrivateDefaultConstructor() {
shouldFailWithMessages '''
class C {
private C() {
}
C(String s) {
}
}
class D extends C {
D() {
//super()
}
}
''',
'Cannot find matching constructor C()'
}
}

0 comments on commit aa29833

Please sign in to comment.