Skip to content

Add gRPC server for type inference #292

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -18,6 +18,13 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Checkout local jacodb
uses: actions/checkout@v4
with:
repository: UnitTestBot/jacodb
ref: lipen/grpc
path: jacodb

- name: Setup Java JDK
uses: actions/setup-java@v4
with:
@@ -45,6 +52,13 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Checkout local jacodb
uses: actions/checkout@v4
with:
repository: UnitTestBot/jacodb
ref: lipen/grpc
path: jacodb

- name: Setup Java JDK
uses: actions/setup-java@v4
with:
@@ -74,6 +88,13 @@ jobs:
# 'usvm-python/cpythonadapter/cpython' is a submodule
submodules: true

- name: Checkout local jacodb
uses: actions/checkout@v4
with:
repository: UnitTestBot/jacodb
ref: lipen/grpc
path: jacodb

- name: Setup Java JDK
uses: actions/setup-java@v4
with:
@@ -107,6 +128,16 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Checkout local jacodb
uses: actions/checkout@v4
with:
repository: UnitTestBot/jacodb
ref: lipen/grpc
path: jacodb

- name: Enable ETS modules in jacodb
run: echo "enableEts=true" >> jacodb/local.properties

- name: Setup Java JDK
uses: actions/setup-java@v4
with:
@@ -149,7 +180,7 @@ jobs:
npm run build

- name: Run TS tests
run: ./gradlew :usvm-ts:check :usvm-ts-dataflow:check
run: ./gradlew :usvm-ts:check :usvm-ts-dataflow:check :usvm-ts-service:check

- name: Upload Gradle reports
if: (!cancelled())
@@ -165,6 +196,16 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v4

- name: Checkout local jacodb
uses: actions/checkout@v4
with:
repository: UnitTestBot/jacodb
ref: lipen/grpc
path: jacodb

- name: Enable ETS modules in jacodb
run: echo "enableEts=true" >> jacodb/local.properties

- name: Setup Java JDK
uses: actions/setup-java@v4
with:
@@ -174,6 +215,9 @@ jobs:
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Show project list
run: ./gradlew projects

- name: Validate Project List
run: ./gradlew validateProjectList

1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ tasks.register("validateProjectList") {
project(":usvm-python"),
project(":usvm-ts"),
project(":usvm-ts-dataflow"),
project(":usvm-ts-service"),
)

// Gather the actual subprojects from the current root project.
2 changes: 2 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ plugins {
}

val kotlinVersion = "2.1.0"
val coroutinesVersion = "1.10.2"
val detektVersion = "1.23.5"
val gjavahVersion = "0.3.1"

@@ -14,6 +15,7 @@ repositories {

dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$detektVersion")
implementation("org.glavo:gjavah:$gjavahVersion")
}
76 changes: 71 additions & 5 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ import org.gradle.plugin.use.PluginDependenciesSpec
object Versions {
const val clikt = "5.0.0"
const val detekt = "1.23.7"
const val gradle_protobuf = "0.9.5"
const val grpc = "1.72.0"
const val grpc_kotlin = "1.4.3"
const val ini4j = "0.5.4"
const val jacodb = "5889d3c784"
const val juliet = "1.3.2"
@@ -15,12 +18,16 @@ object Versions {
const val kotlinx_coroutines = "1.10.0"
const val kotlinx_serialization = "1.7.3"
const val ksmt = "0.5.26"
const val ktor = "3.1.3"
const val logback = "1.4.8"
const val mockk = "1.13.4"
const val protobuf = "4.30.2"
const val rd = "2023.2.0"
const val sarif4k = "0.5.0"
const val shadow = "8.3.3"
const val slf4j = "1.6.1"
const val wire = "5.3.1"
const val wire_grpc_server = "1.0.0-alpha04"

// versions for jvm samples
object Samples {
@@ -116,7 +123,8 @@ object Libs {
)

// https://github.com/UnitTestBot/jacodb
private const val jacodbPackage = "com.github.UnitTestBot.jacodb" // use "org.jacodb" with includeBuild
// private const val jacodbPackage = "com.github.UnitTestBot.jacodb" // use "org.jacodb" with includeBuild
private const val jacodbPackage = "org.jacodb"
val jacodb_core = dep(
group = jacodbPackage,
name = "jacodb-core",
@@ -173,14 +181,14 @@ object Libs {
)

// https://github.com/Kotlin/kotlinx.serialization
val kotlinx_serialization_core = dep(
val kotlinx_serialization_json = dep(
group = "org.jetbrains.kotlinx",
name = "kotlinx-serialization-core",
name = "kotlinx-serialization-json",
version = Versions.kotlinx_serialization
)
val kotlinx_serialization_json = dep(
val kotlinx_serialization_protobuf = dep(
group = "org.jetbrains.kotlinx",
name = "kotlinx-serialization-json",
name = "kotlinx-serialization-protobuf",
version = Versions.kotlinx_serialization
)

@@ -248,6 +256,52 @@ object Libs {
name = "clikt",
version = Versions.clikt
)

// https://github.com/grpc/grpc-java
val grpc_api = dep(
group = "io.grpc",
name = "grpc-api",
version = Versions.grpc
)
val grpc_protobuf = dep(
group = "io.grpc",
name = "grpc-protobuf",
version = Versions.grpc
)
val grpc_stub = dep(
group = "io.grpc",
name = "grpc-stub",
version = Versions.grpc
)
val grpc_netty_shaded = dep(
group = "io.grpc",
name = "grpc-netty-shaded",
version = Versions.grpc
)

// https://github.com/square/wire
val wire_runtime = dep(
group = "com.squareup.wire",
name = "wire-runtime",
version = Versions.wire
)
val wire_grpc_client = dep(
group = "com.squareup.wire",
name = "wire-grpc-client",
version = Versions.wire
)

// https://github.com/square/wire-grpc-server
val wire_grpc_server = dep(
group = "com.squareup.wiregrpcserver",
name = "server",
version = Versions.wire_grpc_server
)
val wire_grpc_server_generator = dep(
group = "com.squareup.wiregrpcserver",
name = "server-generator",
version = Versions.wire_grpc_server
)
}

object Plugins {
@@ -271,6 +325,18 @@ object Plugins {
id = "com.gradleup.shadow",
version = Versions.shadow
)

// https://github.com/google/protobuf-gradle-plugin
object GradleProtobuf : ProjectPlugin(
id = "com.google.protobuf",
version = Versions.gradle_protobuf
)

// https://github.com/square/wire
object Wire : ProjectPlugin(
version = Versions.wire,
id = "com.squareup.wire"
)
}

fun PluginDependenciesSpec.id(plugin: Plugins.ProjectPlugin) {
77 changes: 77 additions & 0 deletions buildSrc/src/main/kotlin/ProcessUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.Reader
import kotlin.time.Duration
import java.util.concurrent.TimeUnit

object ProcessUtil {
data class Result(
val exitCode: Int,
val stdout: String,
val stderr: String,
val isTimeout: Boolean, // true if the process was terminated due to timeout
)

fun run(
command: List<String>,
input: Reader = "".reader(),
timeout: Duration? = null,
builder: ProcessBuilder.() -> Unit = {},
): Result {
val process = ProcessBuilder(command).apply(builder).start()
return communicate(process, input, timeout)
}

private fun communicate(
process: Process,
input: Reader,
timeout: Duration? = null,
): Result {
val stdout = StringBuilder()
val stderr = StringBuilder()

val scope = CoroutineScope(Dispatchers.IO)

// Handle process input
val stdinJob = scope.launch {
process.outputStream.bufferedWriter().use { writer ->
input.copyTo(writer)
}
}

// Launch output capture coroutines
val stdoutJob = scope.launch {
process.inputStream.bufferedReader().useLines { lines ->
lines.forEach { stdout.appendLine(it) }
}
}
val stderrJob = scope.launch {
process.errorStream.bufferedReader().useLines { lines ->
lines.forEach { stderr.appendLine(it) }
}
}

// Wait for completion
val isTimeout = if (timeout != null) {
!process.waitFor(timeout.inWholeNanoseconds, TimeUnit.NANOSECONDS)
} else {
process.waitFor()
false
}

// Wait for all coroutines to finish
runBlocking {
joinAll(stdinJob, stdoutJob, stderrJob)
}

return Result(
exitCode = process.exitValue(),
stdout = stdout.toString(),
stderr = stderr.toString(),
isTimeout = isTimeout,
)
}
}
Loading