-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Kotlin: Avoid infinite recursion when extracting recursive interfaces #20726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,47 @@ | ||||||
| package com.github.codeql.utils | ||||||
|
|
||||||
| import java.util.Stack | ||||||
| import org.jetbrains.kotlin.ir.declarations.IrClass | ||||||
| import org.jetbrains.kotlin.ir.symbols.IrClassSymbol | ||||||
| import org.jetbrains.kotlin.ir.types.* | ||||||
|
|
||||||
| class ClassInstanceStack { | ||||||
| private val stack: Stack<IrClass> = Stack() | ||||||
|
|
||||||
| fun push(c: IrClass) = stack.push(c) | ||||||
| fun pop() = stack.pop() | ||||||
|
||||||
| fun pop() = stack.pop() | |
| fun pop() { stack.pop() } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
|
|
||
| package somepkg; | ||
|
|
||
| public interface IfaceA<T> extends IfaceB<T> {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
|
|
||
| package somepkg; | ||
|
|
||
| public interface IfaceB<T> extends IfaceC<IfaceA<IfaceB<T>>> {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
|
|
||
| package somepkg; | ||
|
|
||
| public interface IfaceC<T> {} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
|
|
||
| package somepkg; | ||
|
|
||
| public interface IfaceZ { | ||
| public <T> IfaceA<String> someFun(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package mypkg | ||
|
|
||
| import somepkg.IfaceZ | ||
|
|
||
| class SomeClass(private val myVal: IfaceZ) { } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| import commands | ||
|
|
||
| def test(codeql, java_full): | ||
| codeql.database.create( | ||
| command=["kotlinc somepkg/IfaceA.java somepkg/IfaceB.java somepkg/IfaceC.java somepkg/IfaceZ.java test.kt"] | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| | file:///!unknown-binary-location/somepkg/IfaceA.class:0:0:0:0 | IfaceA | | ||
| | file:///!unknown-binary-location/somepkg/IfaceA.class:0:0:0:0 | IfaceA<> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceA.class:0:0:0:0 | IfaceA<IfaceB<>> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceA.class:0:0:0:0 | IfaceA<IfaceB<String>> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceA.class:0:0:0:0 | IfaceA<IfaceB<T>> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceA.class:0:0:0:0 | IfaceA<IfaceB> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceA.class:0:0:0:0 | IfaceA<String> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceB.class:0:0:0:0 | IfaceB | | ||
| | file:///!unknown-binary-location/somepkg/IfaceB.class:0:0:0:0 | IfaceB<> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceB.class:0:0:0:0 | IfaceB<IfaceB> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceB.class:0:0:0:0 | IfaceB<String> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceB.class:0:0:0:0 | IfaceB<T> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceC.class:0:0:0:0 | IfaceC | | ||
| | file:///!unknown-binary-location/somepkg/IfaceC.class:0:0:0:0 | IfaceC<> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceC.class:0:0:0:0 | IfaceC<IfaceA<IfaceB<>>> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceC.class:0:0:0:0 | IfaceC<IfaceA<IfaceB<String>>> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceC.class:0:0:0:0 | IfaceC<IfaceA<IfaceB<T>>> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceC.class:0:0:0:0 | IfaceC<IfaceA<IfaceB>> | | ||
| | file:///!unknown-binary-location/somepkg/IfaceZ.class:0:0:0:0 | IfaceZ | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| import java | ||
|
|
||
| from Type t | ||
| where t.getName().matches("Iface%") | ||
| select t |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
|
|
||
| import java.util.Stack; | ||
|
|
||
| // Diagnostic Matches: %Making use of Stack a raw type to avoid infinite recursion% | ||
|
|
||
| class MyType | ||
|
|
||
| fun foo1(x: List<List<List<List<MyType>>>>) { } | ||
|
|
||
| fun foo2(x: Stack<Stack<Stack<Stack<MyType>>>>) { } | ||
|
|
||
| class MkT<T> { } | ||
|
|
||
| fun foo3(x: MkT<MkT<MkT<MkT<MyType>>>>) { } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| | file:///!unknown-binary-location/MkT.class:0:0:0:0 | MkT<MkT<MkT<MkT<MyType>>>> | | ||
| | file:///!unknown-binary-location/MkT.class:0:0:0:0 | MkT<MkT<MkT<MyType>>> | | ||
| | file:///!unknown-binary-location/MkT.class:0:0:0:0 | MkT<MkT<MyType>> | | ||
| | file:///!unknown-binary-location/MkT.class:0:0:0:0 | MkT<MyType> | | ||
| | file:///modules/java.base/java/util/List.class:0:0:0:0 | List<? extends List<? extends List<? extends List<MyType>>>> | | ||
| | file:///modules/java.base/java/util/List.class:0:0:0:0 | List<? extends List<? extends List<MyType>>> | | ||
| | file:///modules/java.base/java/util/List.class:0:0:0:0 | List<? extends List<MyType>> | | ||
| | file:///modules/java.base/java/util/List.class:0:0:0:0 | List<MyType> | | ||
| | file:///modules/java.base/java/util/List.class:0:0:0:0 | List<Stack<MyType>> | | ||
| | file:///modules/java.base/java/util/Stack.class:0:0:0:0 | Stack<MyType> | | ||
| | file:///modules/java.base/java/util/Stack.class:0:0:0:0 | Stack<Stack<MyType>> | | ||
| | file:///modules/java.base/java/util/Stack.class:0:0:0:0 | Stack<Stack<Stack<MyType>>> | | ||
| | file:///modules/java.base/java/util/Stack.class:0:0:0:0 | Stack<Stack<Stack<Stack<MyType>>>> | |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,7 @@ | ||||
| import java | ||||
|
|
||||
| from Type t | ||||
| where | ||||
| t.getName().matches("%MyType%") and | ||||
|
||||
| t.getName().matches("%MyType%") and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The else clause is unnecessary here since the if block returns. Remove the
elsekeyword and unindent line 552 to reduce nesting and improve readability.