diff --git a/java/ql/test/library-tests/flexible-constructors/CONSISTENCY/diags.expected b/java/ql/test/library-tests/flexible-constructors/CONSISTENCY/diags.expected new file mode 100644 index 000000000000..14bea2604819 --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/CONSISTENCY/diags.expected @@ -0,0 +1,2 @@ +unexpectedDiagnostic +| | -1 | 0 | file://:0:0:0:0 | Unknown location for jdk.internal.RequiresIdentity+Annotation | Unknown location for jdk.internal.RequiresIdentity+Annotation | diff --git a/java/ql/test/library-tests/flexible-constructors/FlexibleConstructors.java b/java/ql/test/library-tests/flexible-constructors/FlexibleConstructors.java new file mode 100644 index 000000000000..bcd9a26f7b12 --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/FlexibleConstructors.java @@ -0,0 +1,95 @@ +class A { + A(String msg) { + System.out.println("A: " + msg); + } +} + +class B extends A { + B(String input) { + var msg = input.trim().toUpperCase(); + super(msg); + } +} + +class C { + private final int x; + + C(int x) { + if (x < 0) throw new IllegalArgumentException(); + super(); + this.x = x; + } +} + +record R(String name, int score) { + public R(String name) { + var score = name.length(); + this(name, score); + } +} + +class Outer { + private final String prefix = "outer"; + + class Inner { + private String full; + + Inner(String suffix) { + var combined = prefix + "_" + suffix; + super(); + this.full = combined; + } + } +} + +class D { + private final String value; + private final int length; + + D(String input) { + var processed = input.toLowerCase(); + value = processed; + this.length = processed.length(); + super(); + } +} + +class E extends A { + private boolean isValid; + private String processed; + + E(String data) { + var temp = data != null ? data.trim() : ""; + this.processed = temp; + isValid = !temp.isEmpty(); + super(temp); + } +} + +class F { + private int x; + private final int y; + private int sum; + + F(int a, int b) { + x = a; + this.y = b; + this.sum = a + b; + super(); + } +} + +class G { + private String instance_val; + + { + instance_val = "instance"; + } + + G(String input) { + var tmp = input != null ? input : "default"; + var string = tmp + "_initialized"; + super(); + this.instance_val = string; + } +} diff --git a/java/ql/test/library-tests/flexible-constructors/InstanceInitializerCalls.expected b/java/ql/test/library-tests/flexible-constructors/InstanceInitializerCalls.expected new file mode 100644 index 000000000000..75a112fe2082 --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/InstanceInitializerCalls.expected @@ -0,0 +1,2 @@ +| FlexibleConstructors.java:31:7:31:11 | ; | 1 | | Instance initializer call at index 1 | +| FlexibleConstructors.java:89:5:89:5 | ; | 3 | | Instance initializer call at index 3 | diff --git a/java/ql/test/library-tests/flexible-constructors/InstanceInitializerCalls.ql b/java/ql/test/library-tests/flexible-constructors/InstanceInitializerCalls.ql new file mode 100644 index 000000000000..286137fc4524 --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/InstanceInitializerCalls.ql @@ -0,0 +1,8 @@ +import java + +from MethodCall call, Method m +where + call.getMethod() = m and + m.getName() = "" +select call.getEnclosingStmt(), call.getEnclosingStmt().getIndex(), call.getMethod().getName(), + "Instance initializer call at index " + call.getEnclosingStmt().getIndex() diff --git a/java/ql/test/library-tests/flexible-constructors/PrettyPrint.expected b/java/ql/test/library-tests/flexible-constructors/PrettyPrint.expected new file mode 100644 index 000000000000..d90e8b8f831f --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/PrettyPrint.expected @@ -0,0 +1,125 @@ +| FlexibleConstructors.java:1:7:1:7 | A | 0 | class A { | +| FlexibleConstructors.java:1:7:1:7 | A | 1 | A(String msg) { | +| FlexibleConstructors.java:1:7:1:7 | A | 2 | super(); | +| FlexibleConstructors.java:1:7:1:7 | A | 3 | System.out.println("A: " + msg); | +| FlexibleConstructors.java:1:7:1:7 | A | 4 | } | +| FlexibleConstructors.java:1:7:1:7 | A | 5 | } | +| FlexibleConstructors.java:7:7:7:7 | B | 0 | class B { | +| FlexibleConstructors.java:7:7:7:7 | B | 1 | B(String input) { | +| FlexibleConstructors.java:7:7:7:7 | B | 2 | var msg = input.trim().toUpperCase(); | +| FlexibleConstructors.java:7:7:7:7 | B | 3 | super(msg); | +| FlexibleConstructors.java:7:7:7:7 | B | 4 | } | +| FlexibleConstructors.java:7:7:7:7 | B | 5 | } | +| FlexibleConstructors.java:14:7:14:7 | C | 0 | class C { | +| FlexibleConstructors.java:14:7:14:7 | C | 1 | private final int x; | +| FlexibleConstructors.java:14:7:14:7 | C | 2 | | +| FlexibleConstructors.java:14:7:14:7 | C | 3 | C(int x) { | +| FlexibleConstructors.java:14:7:14:7 | C | 4 | if (x < 0) | +| FlexibleConstructors.java:14:7:14:7 | C | 5 | throw new IllegalArgumentException(); | +| FlexibleConstructors.java:14:7:14:7 | C | 6 | super(); | +| FlexibleConstructors.java:14:7:14:7 | C | 7 | this.x = x; | +| FlexibleConstructors.java:14:7:14:7 | C | 8 | } | +| FlexibleConstructors.java:14:7:14:7 | C | 9 | } | +| FlexibleConstructors.java:24:8:24:8 | R | 0 | final class R { | +| FlexibleConstructors.java:24:8:24:8 | R | 1 | public final boolean equals(Object p0) { } | +| FlexibleConstructors.java:24:8:24:8 | R | 2 | | +| FlexibleConstructors.java:24:8:24:8 | R | 3 | public final int hashCode() { } | +| FlexibleConstructors.java:24:8:24:8 | R | 4 | | +| FlexibleConstructors.java:24:8:24:8 | R | 5 | public String name() { } | +| FlexibleConstructors.java:24:8:24:8 | R | 6 | | +| FlexibleConstructors.java:24:8:24:8 | R | 7 | public int score() { } | +| FlexibleConstructors.java:24:8:24:8 | R | 8 | | +| FlexibleConstructors.java:24:8:24:8 | R | 9 | public final String toString() { } | +| FlexibleConstructors.java:24:8:24:8 | R | 10 | | +| FlexibleConstructors.java:24:8:24:8 | R | 11 | R(String name, int score) { | +| FlexibleConstructors.java:24:8:24:8 | R | 12 | super(); | +| FlexibleConstructors.java:24:8:24:8 | R | 13 | this.name = name; | +| FlexibleConstructors.java:24:8:24:8 | R | 14 | this.score = score; | +| FlexibleConstructors.java:24:8:24:8 | R | 15 | } | +| FlexibleConstructors.java:24:8:24:8 | R | 16 | | +| FlexibleConstructors.java:24:8:24:8 | R | 17 | private final String name; | +| FlexibleConstructors.java:24:8:24:8 | R | 18 | | +| FlexibleConstructors.java:24:8:24:8 | R | 19 | private final int score; | +| FlexibleConstructors.java:24:8:24:8 | R | 20 | | +| FlexibleConstructors.java:24:8:24:8 | R | 21 | public R(String name) { | +| FlexibleConstructors.java:24:8:24:8 | R | 22 | var score = name.length(); | +| FlexibleConstructors.java:24:8:24:8 | R | 23 | this(name, score); | +| FlexibleConstructors.java:24:8:24:8 | R | 24 | } | +| FlexibleConstructors.java:24:8:24:8 | R | 25 | } | +| FlexibleConstructors.java:31:7:31:11 | Outer | 0 | class Outer { | +| FlexibleConstructors.java:31:7:31:11 | Outer | 1 | private void () { | +| FlexibleConstructors.java:31:7:31:11 | Outer | 2 | prefix = "outer"; | +| FlexibleConstructors.java:31:7:31:11 | Outer | 3 | } | +| FlexibleConstructors.java:31:7:31:11 | Outer | 4 | | +| FlexibleConstructors.java:31:7:31:11 | Outer | 5 | Outer() { | +| FlexibleConstructors.java:31:7:31:11 | Outer | 6 | super(); | +| FlexibleConstructors.java:31:7:31:11 | Outer | 7 | (); | +| FlexibleConstructors.java:31:7:31:11 | Outer | 8 | } | +| FlexibleConstructors.java:31:7:31:11 | Outer | 9 | | +| FlexibleConstructors.java:31:7:31:11 | Outer | 10 | private final String prefix; | +| FlexibleConstructors.java:31:7:31:11 | Outer | 11 | | +| FlexibleConstructors.java:31:7:31:11 | Outer | 12 | class Inner { | +| FlexibleConstructors.java:31:7:31:11 | Outer | 13 | private String full; | +| FlexibleConstructors.java:31:7:31:11 | Outer | 14 | | +| FlexibleConstructors.java:31:7:31:11 | Outer | 15 | Inner(String suffix) { | +| FlexibleConstructors.java:31:7:31:11 | Outer | 16 | var combined = prefix + "_" + suffix; | +| FlexibleConstructors.java:31:7:31:11 | Outer | 17 | super(); | +| FlexibleConstructors.java:31:7:31:11 | Outer | 18 | this.full = combined; | +| FlexibleConstructors.java:31:7:31:11 | Outer | 19 | } | +| FlexibleConstructors.java:31:7:31:11 | Outer | 20 | } | +| FlexibleConstructors.java:31:7:31:11 | Outer | 21 | } | +| FlexibleConstructors.java:45:7:45:7 | D | 0 | class D { | +| FlexibleConstructors.java:45:7:45:7 | D | 1 | private final String value; | +| FlexibleConstructors.java:45:7:45:7 | D | 2 | | +| FlexibleConstructors.java:45:7:45:7 | D | 3 | private final int length; | +| FlexibleConstructors.java:45:7:45:7 | D | 4 | | +| FlexibleConstructors.java:45:7:45:7 | D | 5 | D(String input) { | +| FlexibleConstructors.java:45:7:45:7 | D | 6 | var processed = input.toLowerCase(); | +| FlexibleConstructors.java:45:7:45:7 | D | 7 | value = processed; | +| FlexibleConstructors.java:45:7:45:7 | D | 8 | this.length = processed.length(); | +| FlexibleConstructors.java:45:7:45:7 | D | 9 | super(); | +| FlexibleConstructors.java:45:7:45:7 | D | 10 | } | +| FlexibleConstructors.java:45:7:45:7 | D | 11 | } | +| FlexibleConstructors.java:57:7:57:7 | E | 0 | class E { | +| FlexibleConstructors.java:57:7:57:7 | E | 1 | private boolean isValid; | +| FlexibleConstructors.java:57:7:57:7 | E | 2 | | +| FlexibleConstructors.java:57:7:57:7 | E | 3 | private String processed; | +| FlexibleConstructors.java:57:7:57:7 | E | 4 | | +| FlexibleConstructors.java:57:7:57:7 | E | 5 | E(String data) { | +| FlexibleConstructors.java:57:7:57:7 | E | 6 | var temp = data != null ? data.trim() : ""; | +| FlexibleConstructors.java:57:7:57:7 | E | 7 | this.processed = temp; | +| FlexibleConstructors.java:57:7:57:7 | E | 8 | isValid = !temp.isEmpty(); | +| FlexibleConstructors.java:57:7:57:7 | E | 9 | super(temp); | +| FlexibleConstructors.java:57:7:57:7 | E | 10 | } | +| FlexibleConstructors.java:57:7:57:7 | E | 11 | } | +| FlexibleConstructors.java:69:7:69:7 | F | 0 | class F { | +| FlexibleConstructors.java:69:7:69:7 | F | 1 | private int x; | +| FlexibleConstructors.java:69:7:69:7 | F | 2 | | +| FlexibleConstructors.java:69:7:69:7 | F | 3 | private final int y; | +| FlexibleConstructors.java:69:7:69:7 | F | 4 | | +| FlexibleConstructors.java:69:7:69:7 | F | 5 | private int sum; | +| FlexibleConstructors.java:69:7:69:7 | F | 6 | | +| FlexibleConstructors.java:69:7:69:7 | F | 7 | F(int a, int b) { | +| FlexibleConstructors.java:69:7:69:7 | F | 8 | x = a; | +| FlexibleConstructors.java:69:7:69:7 | F | 9 | this.y = b; | +| FlexibleConstructors.java:69:7:69:7 | F | 10 | this.sum = a + b; | +| FlexibleConstructors.java:69:7:69:7 | F | 11 | super(); | +| FlexibleConstructors.java:69:7:69:7 | F | 12 | } | +| FlexibleConstructors.java:69:7:69:7 | F | 13 | } | +| FlexibleConstructors.java:82:7:82:7 | G | 0 | class G { | +| FlexibleConstructors.java:82:7:82:7 | G | 1 | private void () { | +| FlexibleConstructors.java:82:7:82:7 | G | 2 | { | +| FlexibleConstructors.java:82:7:82:7 | G | 3 | instance_val = "instance"; | +| FlexibleConstructors.java:82:7:82:7 | G | 4 | } | +| FlexibleConstructors.java:82:7:82:7 | G | 5 | } | +| FlexibleConstructors.java:82:7:82:7 | G | 6 | | +| FlexibleConstructors.java:82:7:82:7 | G | 7 | private String instance_val; | +| FlexibleConstructors.java:82:7:82:7 | G | 8 | | +| FlexibleConstructors.java:82:7:82:7 | G | 9 | G(String input) { | +| FlexibleConstructors.java:82:7:82:7 | G | 10 | var tmp = input != null ? input : "default"; | +| FlexibleConstructors.java:82:7:82:7 | G | 11 | var string = tmp + "_initialized"; | +| FlexibleConstructors.java:82:7:82:7 | G | 12 | super(); | +| FlexibleConstructors.java:82:7:82:7 | G | 13 | (); | +| FlexibleConstructors.java:82:7:82:7 | G | 14 | this.instance_val = string; | +| FlexibleConstructors.java:82:7:82:7 | G | 15 | } | +| FlexibleConstructors.java:82:7:82:7 | G | 16 | } | diff --git a/java/ql/test/library-tests/flexible-constructors/PrettyPrint.ql b/java/ql/test/library-tests/flexible-constructors/PrettyPrint.ql new file mode 100644 index 000000000000..59ae62effd1b --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/PrettyPrint.ql @@ -0,0 +1,5 @@ +import semmle.code.java.PrettyPrintAst + +from ClassOrInterface cori, string s, int line +where pp(cori, s, line) and cori.fromSource() +select cori, line, s diff --git a/java/ql/test/library-tests/flexible-constructors/PrintAst.expected b/java/ql/test/library-tests/flexible-constructors/PrintAst.expected new file mode 100644 index 000000000000..e8071db72f7d --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/PrintAst.expected @@ -0,0 +1,213 @@ +FlexibleConstructors.java: +# 0| [CompilationUnit] FlexibleConstructors +# 1| 1: [Class] A +# 2| 1: [Constructor] A +#-----| 4: (Parameters) +# 2| 0: [Parameter] msg +# 2| 0: [TypeAccess] String +# 2| 5: [BlockStmt] { ... } +# 3| 1: [ExprStmt] ; +# 3| 0: [MethodCall] println(...) +# 3| -1: [VarAccess] System.out +# 3| -1: [TypeAccess] System +# 3| 0: [AddExpr] ... + ... +# 3| 0: [StringLiteral] "A: " +# 3| 1: [VarAccess] msg +# 7| 2: [Class] B +#-----| -1: (Base Types) +# 7| -1: [TypeAccess] A +# 8| 1: [Constructor] B +#-----| 4: (Parameters) +# 8| 0: [Parameter] input +# 8| 0: [TypeAccess] String +# 8| 5: [BlockStmt] { ... } +# 9| 0: [LocalVariableDeclStmt] var ...; +# 9| 1: [LocalVariableDeclExpr] msg +# 9| 0: [MethodCall] toUpperCase(...) +# 9| -1: [MethodCall] trim(...) +# 9| -1: [VarAccess] input +# 10| 1: [SuperConstructorInvocationStmt] super(...) +# 10| 0: [VarAccess] msg +# 14| 3: [Class] C +# 15| 1: [FieldDeclaration] int x; +# 15| -1: [TypeAccess] int +# 17| 2: [Constructor] C +#-----| 4: (Parameters) +# 17| 0: [Parameter] x +# 17| 0: [TypeAccess] int +# 17| 5: [BlockStmt] { ... } +# 18| 0: [IfStmt] if (...) +# 18| 0: [LTExpr] ... < ... +# 18| 0: [VarAccess] x +# 18| 1: [IntegerLiteral] 0 +# 18| 1: [ThrowStmt] throw ... +# 18| 0: [ClassInstanceExpr] new IllegalArgumentException(...) +# 18| -3: [TypeAccess] IllegalArgumentException +# 19| 1: [SuperConstructorInvocationStmt] super(...) +# 20| 2: [ExprStmt] ; +# 20| 0: [AssignExpr] ...=... +# 20| 0: [VarAccess] this.x +# 20| -1: [ThisAccess] this +# 20| 1: [VarAccess] x +# 24| 4: [Class] R +# 24| 2: [FieldDeclaration] String name; +# 24| 3: [FieldDeclaration] int score; +# 25| 4: [Constructor] R +#-----| 4: (Parameters) +# 25| 0: [Parameter] name +# 25| 0: [TypeAccess] String +# 25| 5: [BlockStmt] { ... } +# 26| 0: [LocalVariableDeclStmt] var ...; +# 26| 1: [LocalVariableDeclExpr] score +# 26| 0: [MethodCall] length(...) +# 26| -1: [VarAccess] name +# 27| 1: [ThisConstructorInvocationStmt] this(...) +# 27| 0: [VarAccess] name +# 27| 1: [VarAccess] score +# 31| 5: [Class] Outer +# 32| 3: [FieldDeclaration] String prefix; +# 32| -1: [TypeAccess] String +# 32| 0: [StringLiteral] "outer" +# 34| 4: [Class] Inner +# 35| 1: [FieldDeclaration] String full; +# 35| -1: [TypeAccess] String +# 37| 2: [Constructor] Inner +#-----| 4: (Parameters) +# 37| 0: [Parameter] suffix +# 37| 0: [TypeAccess] String +# 37| 5: [BlockStmt] { ... } +# 38| 0: [LocalVariableDeclStmt] var ...; +# 38| 1: [LocalVariableDeclExpr] combined +# 38| 0: [AddExpr] ... + ... +# 38| 0: [AddExpr] ... + ... +# 38| 0: [VarAccess] prefix +# 38| 1: [StringLiteral] "_" +# 38| 1: [VarAccess] suffix +# 39| 1: [SuperConstructorInvocationStmt] super(...) +# 40| 2: [ExprStmt] ; +# 40| 0: [AssignExpr] ...=... +# 40| 0: [VarAccess] this.full +# 40| -1: [ThisAccess] this +# 40| 1: [VarAccess] combined +# 45| 6: [Class] D +# 46| 1: [FieldDeclaration] String value; +# 46| -1: [TypeAccess] String +# 47| 2: [FieldDeclaration] int length; +# 47| -1: [TypeAccess] int +# 49| 3: [Constructor] D +#-----| 4: (Parameters) +# 49| 0: [Parameter] input +# 49| 0: [TypeAccess] String +# 49| 5: [BlockStmt] { ... } +# 50| 0: [LocalVariableDeclStmt] var ...; +# 50| 1: [LocalVariableDeclExpr] processed +# 50| 0: [MethodCall] toLowerCase(...) +# 50| -1: [VarAccess] input +# 51| 1: [ExprStmt] ; +# 51| 0: [AssignExpr] ...=... +# 51| 0: [VarAccess] value +# 51| 1: [VarAccess] processed +# 52| 2: [ExprStmt] ; +# 52| 0: [AssignExpr] ...=... +# 52| 0: [VarAccess] this.length +# 52| -1: [ThisAccess] this +# 52| 1: [MethodCall] length(...) +# 52| -1: [VarAccess] processed +# 53| 3: [SuperConstructorInvocationStmt] super(...) +# 57| 7: [Class] E +#-----| -1: (Base Types) +# 57| -1: [TypeAccess] A +# 58| 1: [FieldDeclaration] boolean isValid; +# 58| -1: [TypeAccess] boolean +# 59| 2: [FieldDeclaration] String processed; +# 59| -1: [TypeAccess] String +# 61| 3: [Constructor] E +#-----| 4: (Parameters) +# 61| 0: [Parameter] data +# 61| 0: [TypeAccess] String +# 61| 5: [BlockStmt] { ... } +# 62| 0: [LocalVariableDeclStmt] var ...; +# 62| 1: [LocalVariableDeclExpr] temp +# 62| 0: [ConditionalExpr] ...?...:... +# 62| 0: [NEExpr] ... != ... +# 62| 0: [VarAccess] data +# 62| 1: [NullLiteral] null +# 62| 1: [MethodCall] trim(...) +# 62| -1: [VarAccess] data +# 62| 2: [StringLiteral] "" +# 63| 1: [ExprStmt] ; +# 63| 0: [AssignExpr] ...=... +# 63| 0: [VarAccess] this.processed +# 63| -1: [ThisAccess] this +# 63| 1: [VarAccess] temp +# 64| 2: [ExprStmt] ; +# 64| 0: [AssignExpr] ...=... +# 64| 0: [VarAccess] isValid +# 64| 1: [LogNotExpr] !... +# 64| 0: [MethodCall] isEmpty(...) +# 64| -1: [VarAccess] temp +# 65| 3: [SuperConstructorInvocationStmt] super(...) +# 65| 0: [VarAccess] temp +# 69| 8: [Class] F +# 70| 1: [FieldDeclaration] int x; +# 70| -1: [TypeAccess] int +# 71| 2: [FieldDeclaration] int y; +# 71| -1: [TypeAccess] int +# 72| 3: [FieldDeclaration] int sum; +# 72| -1: [TypeAccess] int +# 74| 4: [Constructor] F +#-----| 4: (Parameters) +# 74| 0: [Parameter] a +# 74| 0: [TypeAccess] int +# 74| 1: [Parameter] b +# 74| 0: [TypeAccess] int +# 74| 5: [BlockStmt] { ... } +# 75| 0: [ExprStmt] ; +# 75| 0: [AssignExpr] ...=... +# 75| 0: [VarAccess] x +# 75| 1: [VarAccess] a +# 76| 1: [ExprStmt] ; +# 76| 0: [AssignExpr] ...=... +# 76| 0: [VarAccess] this.y +# 76| -1: [ThisAccess] this +# 76| 1: [VarAccess] b +# 77| 2: [ExprStmt] ; +# 77| 0: [AssignExpr] ...=... +# 77| 0: [VarAccess] this.sum +# 77| -1: [ThisAccess] this +# 77| 1: [AddExpr] ... + ... +# 77| 0: [VarAccess] a +# 77| 1: [VarAccess] b +# 78| 3: [SuperConstructorInvocationStmt] super(...) +# 82| 9: [Class] G +# 83| 2: [FieldDeclaration] String instance_val; +# 83| -1: [TypeAccess] String +# 85| 3: [BlockStmt] { ... } +# 86| 0: [ExprStmt] ; +# 86| 0: [AssignExpr] ...=... +# 86| 0: [VarAccess] instance_val +# 86| 1: [StringLiteral] "instance" +# 89| 4: [Constructor] G +#-----| 4: (Parameters) +# 89| 0: [Parameter] input +# 89| 0: [TypeAccess] String +# 89| 5: [BlockStmt] { ... } +# 90| 0: [LocalVariableDeclStmt] var ...; +# 90| 1: [LocalVariableDeclExpr] tmp +# 90| 0: [ConditionalExpr] ...?...:... +# 90| 0: [NEExpr] ... != ... +# 90| 0: [VarAccess] input +# 90| 1: [NullLiteral] null +# 90| 1: [VarAccess] input +# 90| 2: [StringLiteral] "default" +# 91| 1: [LocalVariableDeclStmt] var ...; +# 91| 1: [LocalVariableDeclExpr] string +# 91| 0: [AddExpr] ... + ... +# 91| 0: [VarAccess] tmp +# 91| 1: [StringLiteral] "_initialized" +# 92| 2: [SuperConstructorInvocationStmt] super(...) +# 93| 4: [ExprStmt] ; +# 93| 0: [AssignExpr] ...=... +# 93| 0: [VarAccess] this.instance_val +# 93| -1: [ThisAccess] this +# 93| 1: [VarAccess] string diff --git a/java/ql/test/library-tests/flexible-constructors/PrintAst.qlref b/java/ql/test/library-tests/flexible-constructors/PrintAst.qlref new file mode 100644 index 000000000000..c7fd5faf239f --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/PrintAst.qlref @@ -0,0 +1 @@ +semmle/code/java/PrintAst.ql \ No newline at end of file diff --git a/java/ql/test/library-tests/flexible-constructors/SuperPredecessor.expected b/java/ql/test/library-tests/flexible-constructors/SuperPredecessor.expected new file mode 100644 index 000000000000..dba8b4acf988 --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/SuperPredecessor.expected @@ -0,0 +1,7 @@ +| FlexibleConstructors.java:10:15:10:17 | msg | FlexibleConstructors.java:10:9:10:19 | super(...) | predecessor of explicit super() | +| FlexibleConstructors.java:18:13:18:17 | ... < ... | FlexibleConstructors.java:19:9:19:16 | super(...) | predecessor of explicit super() | +| FlexibleConstructors.java:38:17:38:48 | combined | FlexibleConstructors.java:39:13:39:20 | super(...) | predecessor of explicit super() | +| FlexibleConstructors.java:52:9:52:40 | ...=... | FlexibleConstructors.java:53:9:53:16 | super(...) | predecessor of explicit super() | +| FlexibleConstructors.java:65:15:65:18 | temp | FlexibleConstructors.java:65:9:65:20 | super(...) | predecessor of explicit super() | +| FlexibleConstructors.java:77:9:77:24 | ...=... | FlexibleConstructors.java:78:9:78:16 | super(...) | predecessor of explicit super() | +| FlexibleConstructors.java:91:13:91:41 | string | FlexibleConstructors.java:92:9:92:16 | super(...) | predecessor of explicit super() | diff --git a/java/ql/test/library-tests/flexible-constructors/SuperPredecessor.ql b/java/ql/test/library-tests/flexible-constructors/SuperPredecessor.ql new file mode 100644 index 000000000000..2a291c5e82a3 --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/SuperPredecessor.ql @@ -0,0 +1,11 @@ +import java + +from ControlFlowNode pred, ControlFlowNode supNode, SuperConstructorInvocationStmt sc +where + supNode.asStmt() = sc and + pred.getASuccessor() = supNode and + pred != supNode and + not pred.asStmt() instanceof BlockStmt and + exists(sc.getEnclosingCallable().getFile().getRelativePath()) and + sc.getLocation().getEndColumn() > sc.getLocation().getStartColumn() +select pred, sc, "predecessor of explicit super()" diff --git a/java/ql/test/library-tests/flexible-constructors/options b/java/ql/test/library-tests/flexible-constructors/options new file mode 100644 index 000000000000..db1dc01e53b7 --- /dev/null +++ b/java/ql/test/library-tests/flexible-constructors/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args --release 25 --enable-preview