Skip to content

Commit

Permalink
WIP sequential type queries
Browse files Browse the repository at this point in the history
  • Loading branch information
Damtev committed Jun 26, 2023
1 parent bfdd0e2 commit 5c9dbf9
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import org.jooq.SelectConditionStep
import java.util.concurrent.Future

@Suppress("SqlResolve")
class HierarchyExtensionImpl(private val cp: JcClasspath) : HierarchyExtension {
class HierarchyExtensionImpl(val cp: JcClasspath) : HierarchyExtension {

companion object {
private fun allHierarchyQuery(locationIds: String, sinceId: Long?) = """
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.jacodb.api.JcClassType
import org.jacodb.api.JcClasspath
import org.jacodb.api.ext.HierarchyExtension
import org.jacodb.classtable.extractClassesTable
import org.jacodb.impl.features.HierarchyExtensionImpl
import org.jacodb.impl.features.hierarchyExt
import org.jacodb.impl.types.JcClassTypeImpl
import org.jacodb.typesolver.createGsonBuilder
Expand All @@ -44,7 +45,7 @@ abstract class AbstractTypeQuery {

protected lateinit var classes: List<JcClassOrInterface>
protected lateinit var jcClasspath: JcClasspath
protected lateinit var hierarchy: HierarchyExtension
protected lateinit var hierarchy: HierarchyExtensionImpl

@BeforeEach
fun setupHierarchy() {
Expand All @@ -57,11 +58,17 @@ abstract class AbstractTypeQuery {
hierarchy = runBlocking { jcClasspath.hierarchyExt() }
}

protected data class TypeQueryWithUpperBound(
protected data class SingleTypeQueryWithUpperBound(
val upperBound: JvmType,
val expectedAnswersNumber: Int,
val rawExpectedAnswers: List<JvmType>
)

protected data class SequentialTypeQueryWithUpperBound(
val upperBounds: List<JvmType>,
val expectedAnswersNumber: Int,
val rawExpectedAnswers: List<JvmType>
)
}

internal val JcClassType.allSuperHierarchySequence: Sequence<JcClassTypeImpl>
Expand All @@ -80,3 +87,8 @@ internal val JcClassType.allSuperHierarchySequence: Sequence<JcClassTypeImpl>

internal val JcClassType.allSuperHierarchy: Set<JcClassTypeImpl>
get() = allSuperHierarchySequence.toSet()

internal fun HierarchyExtensionImpl.findSubClassesIncluding(
name: String,
allHierarchy: Boolean
): Sequence<JcClassOrInterface> = findSubClasses(name, allHierarchy) + cp.findClassOrNull(name)!!
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ class BoundedTypeQueries : AbstractTypeQuery() {
for (upperBoundName in upperBoundNames) {
val upperBound = classes.single { it.name == upperBoundName }.toJvmTypeWithTypeArguments()
val expectedAnswers = hierarchy
.findSubClasses(upperBoundName, allHierarchy = true)
.findSubClassesIncluding(upperBoundName, allHierarchy = true)
.filter {
if (it.name == upperBoundName) {
return@filter true
}

val superHierarchy = it
.toType()
.allSuperHierarchy
Expand All @@ -73,7 +77,7 @@ class BoundedTypeQueries : AbstractTypeQuery() {
.map { it.toJvmType(jcClasspath) }
.toList()

val query = TypeQueryWithUpperBound(upperBound, expectedAnswers.size, expectedAnswers)
val query = SingleTypeQueryWithUpperBound(upperBound, expectedAnswers.size, expectedAnswers)
val json = gson.toJson(query)

Path("only_type_queries", "single_queries", "extends_${wildcardClass.simpleName.toLowerCase()}_type_variables").let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.jacodb.typesolver.table

import org.jacodb.api.JcClassOrInterface
import org.junit.jupiter.api.Test
import kotlin.io.path.Path

Expand All @@ -26,12 +27,12 @@ class UnboundedTypeQueries : AbstractTypeQuery() {
for (upperBoundName in upperBoundNames) {
val upperBound = classes.single { it.name == upperBoundName }.toJvmType(jcClasspath)
val expectedAnswers = hierarchy
.findSubClasses(upperBoundName, allHierarchy = true)
.findSubClassesIncluding(upperBoundName, allHierarchy = true)
.sortedBy { it.name }
.map { it.toJvmType(jcClasspath) }
.toList()

val query = TypeQueryWithUpperBound(upperBound, expectedAnswers.size, expectedAnswers)
val query = SingleTypeQueryWithUpperBound(upperBound, expectedAnswers.size, expectedAnswers)
val json = gson.toJson(query)

Path("only_type_queries", "single_queries", "unbound_type_variables").let {
Expand All @@ -43,4 +44,52 @@ class UnboundedTypeQueries : AbstractTypeQuery() {
}
}
}

@Test
fun foo() {
// TODO soot is missed in the classpath
val loop = classes.filter { it.name == "soot.toolkits.graph.LoopNestTree" }
println(loop.joinToString())

println(jcClasspath.findClassOrNull("soot.toolkits.graph.LoopNestTree"))
}

@Test
fun writeArtificialSequentialUnboundedTypeQueries() {
val upperBoundGroups = mapOf(
arrayOf("java.lang.Iterable", "java.util.Collection", "java.util.List", "java.util.ArrayList") to hierarchy.findSubClassesIncluding("java.util.ArrayList", allHierarchy = true).toSortedList(),
arrayOf("java.lang.Iterable", "java.util.Collection", "java.util.List") to hierarchy.findSubClassesIncluding("java.util.List", allHierarchy = true).toSortedList(),
arrayOf("java.lang.Iterable", "java.util.List") to hierarchy.findSubClassesIncluding("java.util.List", allHierarchy = true).toSortedList(),
arrayOf("java.util.Set", "java.lang.Iterable") to hierarchy.findSubClassesIncluding("java.util.Set", allHierarchy = true).toSortedList(),
arrayOf("java.lang.Iterable", "java.util.Collection", "java.util.Set", "java.util.SortedSet", "java.util.NavigableSet", "java.util.TreeSet") to hierarchy.findSubClassesIncluding("java.util.TreeSet", allHierarchy = true).toSortedList(),
arrayOf("java.lang.Iterable", "java.util.Collection", "java.util.Set", "java.util.NavigableSet", "java.util.SortedSet") to hierarchy.findSubClassesIncluding("java.util.NavigableSet", allHierarchy = true).toSortedList(),
arrayOf("java.lang.Iterable", "java.util.Collection", "java.util.Set", "java.util.NavigableSet") to hierarchy.findSubClassesIncluding("java.util.NavigableSet", allHierarchy = true).toSortedList(),
arrayOf("java.util.Set", "java.util.List") to run {
val setSubclasses = hierarchy.findSubClassesIncluding("java.util.Set", allHierarchy = true).toSet()
val listSubclasses = hierarchy.findSubClassesIncluding("java.util.List", allHierarchy = true).toSet()

setSubclasses.filter { it in listSubclasses }
}.toSortedList(),
)

for ((group, answers) in upperBoundGroups) {
val testName = group.joinToString(separator = "_", postfix = ".json")
val bounds = group.map { jcClasspath.findClassOrNull(it)!!.toJvmType(jcClasspath) }

val query = SequentialTypeQueryWithUpperBound(bounds, answers.size, answers.map { it.toJvmType(jcClasspath) })

val json = gson.toJson(query)

Path("only_type_queries", "sequential_queries", "unbound_type_variables").let {
it.toFile().mkdirs()

Path(it.toString(), testName).toFile().bufferedWriter().use { writer ->
writer.write(json)
}
}
}
}
}

private fun Sequence<JcClassOrInterface>.toSortedList(): List<JcClassOrInterface> = sortedBy { it.name }.toList()
private fun Iterable<JcClassOrInterface>.toSortedList(): List<JcClassOrInterface> = sortedBy { it.name }.toList()

0 comments on commit 5c9dbf9

Please sign in to comment.