diff --git a/plugins/devkit/devkit-core/resources/inspectionDescriptions/UseIntelliJVirtualThreads.html b/plugins/devkit/devkit-core/resources/inspectionDescriptions/UseIntelliJVirtualThreads.html
new file mode 100644
index 000000000000..b4d4bc3aaa8c
--- /dev/null
+++ b/plugins/devkit/devkit-core/resources/inspectionDescriptions/UseIntelliJVirtualThreads.html
@@ -0,0 +1,21 @@
+
+
+Reports usages of Thread.ofVirtual instead of IntelliJVirtualThreads.ofVirtual.
+
+ Thread.ofVirtual is a generic Java API for creation of virtual threads that is not suitable for IntelliJ Platform needs.
+
+
+ Quick fix performs replacement with IntelliJVirtualThreads.ofVirtual.
+
+
+ Example:
+
+
+// bad:
+Thread thread = Thread.ofVirtual().start();
+
+//good
+Thread thread = IntelliJVirtualThreads.ofVirtual().start();
+
+
+
\ No newline at end of file
diff --git a/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties b/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties
index da4ced62ffae..3aeae681c044 100644
--- a/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties
+++ b/plugins/devkit/devkit-core/resources/messages/DevKitBundle.properties
@@ -784,6 +784,6 @@ compose.hot.reload.hot.reload.agent.has.been.saved=Restart your run configuratio
usage.type.module.in.content=In content
usage.type.module.in.dependencies=In dependencies
-inspection.use.intellij.virtual.threads.display.name=Use IntelliJVirtualThreads.ofVirtual
+inspection.use.intellij.virtual.threads.display.name=Use 'IntelliJVirtualThreads.ofVirtual'
inspection.use.intellij.virtual.threads.message=Use 'IntelliJVirtualThreads.ofVirtual()' instead of 'Thread.ofVirtual()'
inspection.use.intellij.virtual.threads.fix.family.name=Replace with 'IntelliJVirtualThreads.ofVirtual()'
diff --git a/plugins/devkit/devkit-core/src/inspections/UseIntelliJVirtualThreadsInspection.kt b/plugins/devkit/devkit-core/src/inspections/UseIntelliJVirtualThreadsInspection.kt
index 370bd0f66851..8ce91df64f70 100644
--- a/plugins/devkit/devkit-core/src/inspections/UseIntelliJVirtualThreadsInspection.kt
+++ b/plugins/devkit/devkit-core/src/inspections/UseIntelliJVirtualThreadsInspection.kt
@@ -1,102 +1,84 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package org.jetbrains.idea.devkit.inspections;
+package org.jetbrains.idea.devkit.inspections
-import com.intellij.codeInspection.CleanupLocalInspectionTool;
-import com.intellij.codeInspection.LocalQuickFix;
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.codeInspection.ProblemsHolder;
-import com.intellij.codeInspection.util.IntentionFamilyName;
-import com.intellij.lang.java.JavaLanguage;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.uast.UastHintedVisitorAdapter;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.idea.devkit.DevKitBundle;
-import org.jetbrains.uast.UCallExpression;
-import org.jetbrains.uast.UElement;
-import org.jetbrains.uast.UastContextKt;
-import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor;
+import com.intellij.codeInspection.LocalQuickFix
+import com.intellij.codeInspection.ProblemDescriptor
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.codeInspection.util.IntentionFamilyName
+import com.intellij.lang.java.JavaLanguage
+import com.intellij.openapi.project.Project
+import com.intellij.psi.PsiElementVisitor
+import com.intellij.uast.UastHintedVisitorAdapter
+import org.jetbrains.idea.devkit.DevKitBundle
+import org.jetbrains.uast.*
+import org.jetbrains.uast.generate.getUastElementFactory
+import org.jetbrains.uast.generate.replace
+import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
/**
* Suggest using IntelliJVirtualThreads.ofVirtual instead of Thread.ofVirtual
*/
-public final class UseIntelliJVirtualThreadsInspection extends DevKitUastInspectionBase implements CleanupLocalInspectionTool {
-
- private static final String THREAD_CLASS = "java.lang.Thread";
- private static final String INTELLIJ_VIRTUAL_THREADS_FQN = "com.intellij.virtualThreads.IntelliJVirtualThreads";
-
- @SuppressWarnings("unchecked")
- private static final Class extends UElement>[] HINTS = new Class[]{UCallExpression.class};
-
- @Override
- protected boolean isAllowed(@NotNull ProblemsHolder holder) {
- return DevKitInspectionUtil.isAllowed(holder.getFile()) &&
- DevKitInspectionUtil.isClassAvailable(holder, INTELLIJ_VIRTUAL_THREADS_FQN);
+class UseIntelliJVirtualThreadsInspection : DevKitUastInspectionBase() {
+ override fun isAllowed(holder: ProblemsHolder): Boolean {
+ return DevKitInspectionUtil.isAllowed(holder.file) &&
+ DevKitInspectionUtil.isClassAvailable(holder, INTELLIJ_VIRTUAL_THREADS_FQN)
}
- @Override
- public @NotNull PsiElementVisitor buildInternalVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
- return UastHintedVisitorAdapter.create(holder.getFile().getLanguage(), new AbstractUastNonRecursiveVisitor() {
- @Override
- public boolean visitCallExpression(@NotNull UCallExpression node) {
- if (!"ofVirtual".equals(node.getMethodName())) return super.visitCallExpression(node);
- PsiMethod method = node.resolve();
- boolean isThreadOfVirtual = false;
- if (method != null) {
- if (!method.hasModifierProperty(PsiModifier.STATIC)) return super.visitCallExpression(node);
- PsiClass containingClass = method.getContainingClass();
- if (containingClass == null) return super.visitCallExpression(node);
- String qName = containingClass.getQualifiedName();
- isThreadOfVirtual = THREAD_CLASS.equals(qName) || "Thread".equals(containingClass.getName());
+ public override fun buildInternalVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+ return UastHintedVisitorAdapter.create(holder.file.getLanguage(), object : AbstractUastNonRecursiveVisitor() {
+ override fun visitCallExpression(node: UCallExpression): Boolean {
+ val method = node.takeIf {
+ it.methodName == "ofVirtual"
+ }?.resolve() ?: return super.visitCallExpression(node)
+ val clazz = method.containingClass ?: return super.visitCallExpression(node)
+ if (clazz.qualifiedName != THREAD_FQN) {
+ return super.visitCallExpression(node)
}
- else {
- // Fallback for environments where JDK doesn't provide Thread.ofVirtual (e.g., tests on older JDK):
- PsiElement sp = node.getSourcePsi();
- if (sp instanceof PsiMethodCallExpression) {
- PsiExpression qualifier = ((PsiMethodCallExpression)sp).getMethodExpression().getQualifierExpression();
- String qualifierText = qualifier == null ? null : qualifier.getText();
- isThreadOfVirtual = THREAD_CLASS.equals(qualifierText) || "Thread".equals(qualifierText);
- }
- }
- if (!isThreadOfVirtual) return super.visitCallExpression(node);
- PsiElement psi = node.getSourcePsi();
+ val psi = node.sourcePsi
if (psi != null) {
- LocalQuickFix[] fixes = psi.getLanguage().is(JavaLanguage.INSTANCE)
- ? new LocalQuickFix[]{new ReplaceWithIntelliJVirtualThreadsFix()}
- : LocalQuickFix.EMPTY_ARRAY;
- holder.registerProblem(psi, DevKitBundle.message("inspection.use.intellij.virtual.threads.message"), fixes);
+ val fixes: Array = if (psi.getLanguage().`is`(JavaLanguage.INSTANCE) || psi.language.id == "kotlin") {
+ arrayOf(ReplaceWithIntelliJVirtualThreadsFix())
+ }
+ else {
+ LocalQuickFix.EMPTY_ARRAY
+ }
+ holder.registerProblem(psi, DevKitBundle.message("inspection.use.intellij.virtual.threads.message"), *fixes)
}
- return super.visitCallExpression(node);
+ return super.visitCallExpression(node)
}
- }, HINTS);
+ }, HINTS)
}
- private static class ReplaceWithIntelliJVirtualThreadsFix implements LocalQuickFix {
-
- @Override
- public @IntentionFamilyName @NotNull String getFamilyName() {
- return DevKitBundle.message("inspection.use.intellij.virtual.threads.fix.family.name");
+ private class ReplaceWithIntelliJVirtualThreadsFix : LocalQuickFix {
+ @IntentionFamilyName
+ override fun getFamilyName(): @IntentionFamilyName String {
+ return DevKitBundle.message("inspection.use.intellij.virtual.threads.fix.family.name")
}
- @Override
- public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
- PsiElement element = descriptor.getPsiElement();
- PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class, false);
- if (call == null && element instanceof PsiMethodCallExpression) {
- call = (PsiMethodCallExpression) element;
- }
- if (call == null) return;
-
- PsiReferenceExpression methodExpression = call.getMethodExpression();
- PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
- PsiExpression newMethodRef = factory.createExpressionFromText(
- INTELLIJ_VIRTUAL_THREADS_FQN + ".ofVirtual", call
- );
- PsiElement replaced = methodExpression.replace(newMethodRef);
- JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced);
+ override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
+ val element = descriptor.psiElement
+ val uCall = element.toUElement() ?: return
+ val factory = uCall.getUastElementFactory(project) ?: return
+ val newReceiver = factory.createQualifiedReference(INTELLIJ_VIRTUAL_THREADS_FQN, uCall.sourcePsi) ?: return
+ val newCall = factory.createCallExpression(
+ receiver = newReceiver,
+ methodName = "ofVirtual",
+ parameters = emptyList(),
+ expectedReturnType = null,
+ kind = UastCallKind.METHOD_CALL,
+ context = uCall.sourcePsi
+ ) ?: return
+ val parent = uCall.uastParent
+ // we check for parent in case of `Thread.ofVirtual()` calls in Kotlin
+ val replacementUastElement = parent as? UQualifiedReferenceExpression ?: uCall
+ replacementUastElement.replace(newCall)
}
}
}
+
+private const val THREAD_FQN = "java.lang.Thread"
+private const val INTELLIJ_VIRTUAL_THREADS_FQN = "com.intellij.concurrency.virtualThreads.IntelliJVirtualThreads"
+
+private val HINTS: Array> = arrayOf(UCallExpression::class.java)
+
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads.java b/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads.java
index a572de3427f4..391da2c7e0ca 100644
--- a/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads.java
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads.java
@@ -1,11 +1,7 @@
-import com.intellij.virtualThreads.IntelliJVirtualThreads;
import java.lang.Thread;
class UseIntelliJVirtualThreads {
- java.lang.Thread.Builder m() {
- return java.lang.Thread.ofVirtual();
- }
- void ok() {
- IntelliJVirtualThreads.ofVirtual();
+ public static void main(String[] args) {
+ Thread.ofVirtual();
}
}
diff --git a/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_after.java b/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_after.java
index 88e2baff4835..f58409c8aa71 100644
--- a/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_after.java
+++ b/plugins/devkit/devkit-java-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_after.java
@@ -1,11 +1,9 @@
-import com.intellij.virtualThreads.IntelliJVirtualThreads;
+import com.intellij.concurrency.virtualThreads.IntelliJVirtualThreads;
+
import java.lang.Thread;
class UseIntelliJVirtualThreads {
- java.lang.Thread.Builder m() {
- return IntelliJVirtualThreads.ofVirtual();
- }
- void ok() {
- IntelliJVirtualThreads.ofVirtual();
+ public static void main(String[] args) {
+ IntelliJVirtualThreads.ofVirtual();
}
}
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java
index 23a3d491b341..c4f8152152d5 100644
--- a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java
+++ b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/DevkitInspectionsRegistrationCheckTest.java
@@ -12,7 +12,7 @@ import java.util.stream.Stream;
public class DevkitInspectionsRegistrationCheckTest extends BasePlatformTestCase {
- private static final int EXPECTED_INSPECTIONS_NUMBER = 83;
+ private static final int EXPECTED_INSPECTIONS_NUMBER = 84;
/**
* Inspections that are finished and intentionally disabled.
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/UseIntelliJVirtualThreadsInspectionFixTest.java b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/UseIntelliJVirtualThreadsInspectionFixTest.java
deleted file mode 100644
index c080b5cbe2a8..000000000000
--- a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/UseIntelliJVirtualThreadsInspectionFixTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package org.jetbrains.idea.devkit.inspections;
-
-import com.intellij.testFramework.TestDataPath;
-import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor;
-import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
-import com.intellij.testFramework.IdeaTestUtil;
-import com.intellij.util.lang.JavaVersion;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.idea.devkit.DevkitJavaTestsUtil;
-
-@TestDataPath("$CONTENT_ROOT/testData/inspections/useIntelliJVirtualThreads")
-public class UseIntelliJVirtualThreadsInspectionFixTest extends org.jetbrains.idea.devkit.inspections.quickfix.LightDevKitInspectionFixTestBase {
-
- @Override
- protected String getBasePath() {
- return DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/useIntelliJVirtualThreads";
- }
-
- @Override
- protected @NotNull String getFileExtension() {
- return "java";
- }
-
- @Override
- protected com.intellij.testFramework.LightProjectDescriptor getProjectDescriptor() {
- return new DefaultLightProjectDescriptor(() -> IdeaTestUtil.getMockJdk(JavaVersion.compose(21)));
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- myFixture.enableInspections(new UseIntelliJVirtualThreadsInspection());
-
- // Provide IntelliJVirtualThreads class used by the inspection
- myFixture.addClass(
- "package com.intellij.virtualThreads;" +
- "public final class IntelliJVirtualThreads {" +
- " private IntelliJVirtualThreads() {}" +
- " public static java.lang.Thread.Builder ofVirtual() { return null; }" +
- "}"
- );
- }
-
- public void testUseIntelliJVirtualThreads() {
- doTest(org.jetbrains.idea.devkit.DevKitBundle.message("inspection.use.intellij.virtual.threads.fix.family.name"));
- }
-}
diff --git a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/UseIntelliJVirtualThreadsInspectionTest.kt b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/UseIntelliJVirtualThreadsInspectionTest.kt
index 61547c7ac12c..0614544ff659 100644
--- a/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/UseIntelliJVirtualThreadsInspectionTest.kt
+++ b/plugins/devkit/devkit-java-tests/testSrc/org/jetbrains/idea/devkit/inspections/UseIntelliJVirtualThreadsInspectionTest.kt
@@ -1,41 +1,25 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package org.jetbrains.idea.devkit.inspections;
+package org.jetbrains.idea.devkit.inspections
-import com.intellij.testFramework.TestDataPath;
-import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
-import org.jetbrains.idea.devkit.DevkitJavaTestsUtil;
+import com.intellij.testFramework.IdeaTestUtil
+import com.intellij.testFramework.LightProjectDescriptor
+import com.intellij.testFramework.TestDataPath
+import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor
+import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
+import org.jetbrains.idea.devkit.DevkitJavaTestsUtil
+import org.jetbrains.idea.devkit.inspections.quickfix.LightDevKitInspectionFixTestBase
+import org.jetbrains.idea.devkit.inspections.quickfix.UseIntelliJVirtualThreadsInspectionTestBase
+import java.util.function.Supplier
-@TestDataPath("$CONTENT_ROOT/testData/inspections/useIntelliJVirtualThreads")
-public class UseIntelliJVirtualThreadsInspectionTest extends LightJavaCodeInsightFixtureTestCase {
-
- @Override
- protected String getBasePath() {
- return DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/useIntelliJVirtualThreads";
- }
-
- @Override
- protected com.intellij.testFramework.LightProjectDescriptor getProjectDescriptor() {
- return new com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor(() ->
- com.intellij.testFramework.IdeaTestUtil.getMockJdk(com.intellij.util.lang.JavaVersion.compose(21))
- );
+@TestDataPath($$"$CONTENT_ROOT/testData/inspections/useIntelliJVirtualThreads")
+class UseIntelliJVirtualThreadsInspectionTest : UseIntelliJVirtualThreadsInspectionTestBase() {
+ override fun getBasePath(): String {
+ return DevkitJavaTestsUtil.TESTDATA_PATH + "inspections/useIntelliJVirtualThreads"
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- myFixture.enableInspections(new UseIntelliJVirtualThreadsInspection());
-
- // Provide IntelliJVirtualThreads class used by the inspection
- myFixture.addClass(
- "package com.intellij.virtualThreads;" +
- "public final class IntelliJVirtualThreads {" +
- " private IntelliJVirtualThreads() {}" +
- " public static java.lang.Thread.Builder ofVirtual() { return null; }" +
- "}"
- );
+ fun testUseIntelliJVirtualThreads() {
+ doTest("Replace with 'IntelliJVirtualThreads.ofVirtual()'")
}
- public void testUseIntelliJVirtualThreads() {
- myFixture.testHighlighting(getTestName(false) + ".java");
- }
+ override fun getFileExtension(): String = "java"
}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads.kt
new file mode 100644
index 000000000000..01445bf4483b
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads.kt
@@ -0,0 +1,7 @@
+import java.lang.Thread
+
+class UseIntelliJVirtualThreadsKotlin {
+ fun foo() {
+ Thread.ofVirtual()
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreadsKotlin.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreadsKotlin.kt
deleted file mode 100644
index c8a273b3bc5b..000000000000
--- a/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreadsKotlin.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-import com.intellij.virtualThreads.IntelliJVirtualThreads
-
-class UseIntelliJVirtualThreadsKotlin {
- fun m(): Thread.Builder {
- return java.lang.Thread.ofVirtual()
- }
- fun ok() {
- IntelliJVirtualThreads.ofVirtual()
- }
-}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_after.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_after.kt
new file mode 100644
index 000000000000..1c7ad05c70ed
--- /dev/null
+++ b/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_after.kt
@@ -0,0 +1,8 @@
+import com.intellij.concurrency.virtualThreads.IntelliJVirtualThreads
+import java.lang.Thread
+
+class UseIntelliJVirtualThreadsKotlin {
+ fun foo() {
+ IntelliJVirtualThreads.ofVirtual()
+ }
+}
diff --git a/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_kotlin.kt b/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_kotlin.kt
deleted file mode 100644
index c8a273b3bc5b..000000000000
--- a/plugins/devkit/devkit-kotlin-tests/testData/inspections/useIntelliJVirtualThreads/UseIntelliJVirtualThreads_kotlin.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-import com.intellij.virtualThreads.IntelliJVirtualThreads
-
-class UseIntelliJVirtualThreadsKotlin {
- fun m(): Thread.Builder {
- return java.lang.Thread.ofVirtual()
- }
- fun ok() {
- IntelliJVirtualThreads.ofVirtual()
- }
-}
diff --git a/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtUseIntelliJVirtualThreadsInspectionTest.kt b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtUseIntelliJVirtualThreadsInspectionTest.kt
index 58efa7e48bc3..2afa08d30ea5 100644
--- a/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtUseIntelliJVirtualThreadsInspectionTest.kt
+++ b/plugins/devkit/devkit-kotlin-tests/testSrc/org/jetbrains/idea/devkit/kotlin/inspections/KtUseIntelliJVirtualThreadsInspectionTest.kt
@@ -1,50 +1,19 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
-package org.jetbrains.idea.devkit.kotlin.inspections;
+package org.jetbrains.idea.devkit.kotlin.inspections
-import com.intellij.testFramework.TestDataPath;
-import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor;
-import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
-import com.intellij.testFramework.IdeaTestUtil;
-import com.intellij.util.lang.JavaVersion;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.idea.devkit.kotlin.DevkitKtTestsUtil;
-import org.jetbrains.idea.devkit.inspections.UseIntelliJVirtualThreadsInspection;
+import com.intellij.testFramework.TestDataPath
+import org.jetbrains.idea.devkit.inspections.quickfix.UseIntelliJVirtualThreadsInspectionTestBase
+import org.jetbrains.idea.devkit.kotlin.DevkitKtTestsUtil
-@TestDataPath("$CONTENT_ROOT/testData/inspections/useIntelliJVirtualThreads")
-public class KtUseIntelliJVirtualThreadsInspectionTest extends LightJavaCodeInsightFixtureTestCase {
-
- @Override
- protected String getBasePath() {
- return DevkitKtTestsUtil.TESTDATA_PATH + "inspections/useIntelliJVirtualThreads";
+@TestDataPath($$"$CONTENT_ROOT/testData/inspections/useIntelliJVirtualThreads")
+class KtUseIntelliJVirtualThreadsInspectionTest : UseIntelliJVirtualThreadsInspectionTestBase() {
+ override fun getBasePath(): String {
+ return DevkitKtTestsUtil.TESTDATA_PATH + "inspections/useIntelliJVirtualThreads"
}
- @Override
- protected com.intellij.testFramework.LightProjectDescriptor getProjectDescriptor() {
- return new DefaultLightProjectDescriptor(() -> IdeaTestUtil.getMockJdk(JavaVersion.compose(21)));
+ fun testUseIntelliJVirtualThreads() {
+ doTest("Replace with 'IntelliJVirtualThreads.ofVirtual()'")
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- myFixture.enableInspections(new UseIntelliJVirtualThreadsInspection());
-
- // Provide IntelliJVirtualThreads class used by the inspection
- myFixture.addClass(
- "package com.intellij.virtualThreads;" +
- "public final class IntelliJVirtualThreads {" +
- " private IntelliJVirtualThreads() {}" +
- " public static java.lang.Thread.Builder ofVirtual() { return null; }" +
- "}"
- );
- }
-
- @NotNull
- @Override
- protected String getTestName(boolean lowercaseFirstLetter) {
- return super.getTestName(lowercaseFirstLetter).replace("_", "");
- }
-
- public void testUseIntelliJVirtualThreadsKotlin() {
- myFixture.testHighlighting(getTestName(false) + ".kt");
- }
+ override fun getFileExtension(): String = "kt"
}
diff --git a/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/UseIntelliJVirtualThreadsInspectionTestBase.kt b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/UseIntelliJVirtualThreadsInspectionTestBase.kt
new file mode 100644
index 000000000000..67889dd1b930
--- /dev/null
+++ b/plugins/devkit/devkit-tests/testSrc/org/jetbrains/idea/devkit/inspections/quickfix/UseIntelliJVirtualThreadsInspectionTestBase.kt
@@ -0,0 +1,30 @@
+// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.idea.devkit.inspections.quickfix
+
+import com.intellij.testFramework.IdeaTestUtil
+import com.intellij.testFramework.LightProjectDescriptor
+import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor
+import org.jetbrains.idea.devkit.inspections.UseIntelliJVirtualThreadsInspection
+import java.util.function.Supplier
+
+abstract class UseIntelliJVirtualThreadsInspectionTestBase : LightDevKitInspectionFixTestBase() {
+
+ override fun getProjectDescriptor(): LightProjectDescriptor {
+ return DefaultLightProjectDescriptor(Supplier { IdeaTestUtil.getMockJdk21() })
+ }
+
+ @Throws(Exception::class)
+ override fun setUp() {
+ super.setUp()
+ myFixture.enableInspections(UseIntelliJVirtualThreadsInspection())
+ myFixture.addClass(
+ """package com.intellij.concurrency.virtualThreads;
+ |public final class IntelliJVirtualThreads {
+ | private IntelliJVirtualThreads() {}
+ | public static java.lang.Thread.Builder ofVirtual() {
+ | return null;
+ | }
+ |}""".trimMargin()
+ )
+ }
+}
\ No newline at end of file