diff --git a/detekt-parser/build.gradle.kts b/detekt-parser/build.gradle.kts index 67b2978c8421..e06bde35407f 100644 --- a/detekt-parser/build.gradle.kts +++ b/detekt-parser/build.gradle.kts @@ -7,6 +7,8 @@ plugins { dependencies { api(libs.kotlin.compilerEmbeddable) implementation(projects.detektPsiUtils) + implementation(libs.contester.breakpoint) + testImplementation(libs.contester.driver) testImplementation(projects.detektTestUtils) testImplementation(libs.assertj) } diff --git a/detekt-parser/src/main/kotlin/io/github/detekt/parser/DetektPomModel.kt b/detekt-parser/src/main/kotlin/io/github/detekt/parser/DetektPomModel.kt index 17a13f02ccde..3a0722ca4fd6 100644 --- a/detekt-parser/src/main/kotlin/io/github/detekt/parser/DetektPomModel.kt +++ b/detekt-parser/src/main/kotlin/io/github/detekt/parser/DetektPomModel.kt @@ -1,5 +1,6 @@ package io.github.detekt.parser +import io.github.davidburstrom.contester.ConTesterBreakpoint import org.jetbrains.kotlin.com.intellij.openapi.extensions.ExtensionPoint import org.jetbrains.kotlin.com.intellij.openapi.extensions.Extensions.getRootArea import org.jetbrains.kotlin.com.intellij.openapi.project.Project @@ -26,6 +27,9 @@ class DetektPomModel(project: Project) : UserDataHolderBase(), PomModel { // Addresses https://github.com/detekt/detekt/issues/4609 synchronized(extensionArea) { if (!extensionArea.hasExtensionPoint(extension)) { + ConTesterBreakpoint.defineBreakpoint("DetektPomModel.registerExtensionPoint") { + extensionArea == getRootArea() + } extensionArea.registerExtensionPoint( extension, extensionClass, diff --git a/detekt-parser/src/test/kotlin/io/github/detekt/parser/KtCompilerSpec.kt b/detekt-parser/src/test/kotlin/io/github/detekt/parser/KtCompilerSpec.kt index 994ba8a684f0..a29b29313640 100644 --- a/detekt-parser/src/test/kotlin/io/github/detekt/parser/KtCompilerSpec.kt +++ b/detekt-parser/src/test/kotlin/io/github/detekt/parser/KtCompilerSpec.kt @@ -1,5 +1,6 @@ package io.github.detekt.parser +import io.github.davidburstrom.contester.ConTesterDriver import io.github.detekt.psi.BASE_PATH import io.github.detekt.psi.LINE_SEPARATOR import io.github.detekt.psi.RELATIVE_PATH @@ -8,10 +9,24 @@ import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatIllegalArgumentException import org.jetbrains.kotlin.com.intellij.psi.PsiErrorElement import org.jetbrains.kotlin.psi.KtTreeVisitorVoid +import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test class KtCompilerSpec { + @AfterEach + internal fun tearDown() { + ConTesterDriver.cleanUp() + } + + @Test + fun `parallel construction of KtCompilers should be thread safe`() { + val thread1 = ConTesterDriver.thread { KtCompiler() } + val thread2 = ConTesterDriver.thread { KtCompiler() } + ConTesterDriver.runToBreakpoint(thread1, "DetektPomModel.registerExtensionPoint") + ConTesterDriver.runUntilBlockedOrTerminated(thread2) + ConTesterDriver.join(thread1) + } @Nested inner class `Kotlin Compiler` { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 116ebc799bf6..2647203eb123 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -5,6 +5,7 @@ kotlin = "1.6.10" ktlint = "0.45.1" spek = "2.0.18" junit = "5.8.2" +contester = "0.1.0" [libraries] githubRelease-gradle = "com.github.breadmoirai:github-release:2.2.12" @@ -40,6 +41,8 @@ reflections = "org.reflections:reflections:0.10.2" mockk = "io.mockk:mockk:1.12.3" snakeyaml = "org.yaml:snakeyaml:1.30" jcommander = "com.beust:jcommander:1.82" +contester-breakpoint = { module = "io.github.davidburstrom.contester:contester-breakpoint", version.ref = "contester" } +contester-driver = { module = "io.github.davidburstrom.contester:contester-driver", version.ref = "contester" } [plugins] binaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.8.0" }