From dd8a002d26ba8343b481a3d9a09905826f1df876 Mon Sep 17 00:00:00 2001 From: Madis Pink Date: Wed, 5 Apr 2023 13:40:19 +0300 Subject: [PATCH 1/7] Fix accessing KotlinFindUsagesHandlerFactory on newer IDEA --- .../SqlDelightFindUsagesHandlerFactory.kt | 2 +- .../usages/KotlinFindUsagesHandlerFactory.kt | 22 +++++++++++++++++++ .../usages/LegacyKotlinFindUsagesFactory.kt | 14 ++++++++++++ .../ReflectiveKotlinFindUsagesFactory.kt | 21 ++++++++++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt create mode 100644 sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt create mode 100644 sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt index 96eec44a332..c78b1a15909 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt @@ -5,6 +5,7 @@ import app.cash.sqldelight.core.lang.SqlDelightFile import app.cash.sqldelight.core.lang.psi.StmtIdentifierMixin import app.cash.sqldelight.core.lang.queriesName import app.cash.sqldelight.core.psi.SqlDelightStmtIdentifier +import app.cash.sqldelight.intellij.usages.KotlinFindUsagesHandlerFactory import com.alecstrong.sql.psi.core.psi.SqlColumnName import com.intellij.find.findUsages.FindUsagesHandler import com.intellij.find.findUsages.FindUsagesHandlerFactory @@ -20,7 +21,6 @@ import com.intellij.psi.PsiManager import com.intellij.psi.util.PsiTreeUtil import com.intellij.usageView.UsageInfo import com.intellij.util.Processor -import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory import org.jetbrains.kotlin.idea.findUsages.KotlinReferenceUsageInfo import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt new file mode 100644 index 00000000000..a918f6cbd1e --- /dev/null +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt @@ -0,0 +1,22 @@ +package app.cash.sqldelight.intellij.usages + +import com.intellij.find.findUsages.FindUsagesHandler +import com.intellij.find.findUsages.FindUsagesHandlerFactory +import com.intellij.find.findUsages.FindUsagesOptions +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement + +interface KotlinFindUsagesHandlerFactory { + fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler + val findFunctionOptions: FindUsagesOptions + val findPropertyOptions: FindUsagesOptions +} + +fun KotlinFindUsagesHandlerFactory(project: Project): KotlinFindUsagesHandlerFactory { + return try { + val factory = Class.forName("org.jetbrains.kotlin.idea.base.searching.usages.KotlinFindUsagesHandlerFactory") + ReflectiveKotlinFindUsagesFactory(factory.getConstructor(Project::class.java).newInstance(project) as FindUsagesHandlerFactory) + } catch (e: ClassNotFoundException) { + LegacyKotlinFindUsagesFactory(org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory(project)) + } +} diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt new file mode 100644 index 00000000000..05ca51f1c2d --- /dev/null +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt @@ -0,0 +1,14 @@ +package app.cash.sqldelight.intellij.usages + +import com.intellij.find.findUsages.FindUsagesHandler +import com.intellij.psi.PsiElement + +class LegacyKotlinFindUsagesFactory( + private val wrapped: org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory +) : KotlinFindUsagesHandlerFactory { + override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler { + return wrapped.createFindUsagesHandler(element, forHighlightUsages) + } + override val findFunctionOptions get() = wrapped.findFunctionOptions + override val findPropertyOptions get() = wrapped.findPropertyOptions +} diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt new file mode 100644 index 00000000000..8eb06e2d1f0 --- /dev/null +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt @@ -0,0 +1,21 @@ +package app.cash.sqldelight.intellij.usages + +import com.intellij.find.findUsages.FindUsagesHandler +import com.intellij.find.findUsages.FindUsagesHandlerFactory +import com.intellij.find.findUsages.FindUsagesOptions +import com.intellij.psi.PsiElement +import java.lang.reflect.Method + +class ReflectiveKotlinFindUsagesFactory( + private val wrapped: FindUsagesHandlerFactory +) : KotlinFindUsagesHandlerFactory { + private val findFunctionOptionsMethod: Method = wrapped.javaClass.getMethod("getFindFunctionOptions") + private val findPropertyOptionsMethod: Method = wrapped.javaClass.getMethod("getFindPropertyOptions") + + override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler { + return wrapped.createFindUsagesHandler(element, forHighlightUsages)!! + } + + override val findFunctionOptions get() = findFunctionOptionsMethod.invoke(wrapped) as FindUsagesOptions + override val findPropertyOptions get() = findPropertyOptionsMethod.invoke(wrapped) as FindUsagesOptions +} From f96d8faf020a7e5451c6a4d587fedbc29af443e4 Mon Sep 17 00:00:00 2001 From: Madis Pink Date: Wed, 5 Apr 2023 13:40:34 +0300 Subject: [PATCH 2/7] Fix mutating plugin classloader on newer IDEA --- .../intellij/gradle/FileIndexMap.kt | 50 +++++++++++++++---- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt index 8cdc6cea83e..a1bebd9444d 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt @@ -22,6 +22,7 @@ import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.Task import com.intellij.ui.EditorNotifications +import com.intellij.util.lang.ClassPath import com.intellij.util.lang.UrlClassLoader import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper import org.jetbrains.plugins.gradle.settings.DistributionType @@ -100,6 +101,8 @@ internal class FileIndexMap { ?: ExternalSystemJdkUtil.getAvailableJdk(project).second.homePath )?.let { File(it) } + Timber.i("Using JAVA_HOME at %s", javaHome?.absolutePath) + val properties = connection.action(FetchProjectModelsBuildAction).setJavaHome(javaHome).run() @@ -135,6 +138,8 @@ internal class FileIndexMap { EditorNotifications.getInstance(module.project).updateAllNotifications() } catch (externalException: ExternalSystemException) { // It's a gradle error, ignore and let the user fix when they try and build the project + Timber.i("sqldelight model gen failed") + Timber.i(externalException) FileIndexingNotification.getInstance(project).unconfiguredReason = FileIndexingNotification.UnconfiguredReason.Incompatible( @@ -161,22 +166,45 @@ internal class FileIndexMap { val pluginClassLoader = pluginClassLoader as UrlClassLoader // We need to remove the last loaded dialect as well as add our new one. - val files = UrlClassLoader::class.java.getDeclaredField("files").let { field -> - field.isAccessible = true - val result = field.get(pluginClassLoader) as MutableList - field.isAccessible = false - return@let result + val files = try { + UrlClassLoader::class.java.getDeclaredField("files").let { field -> + field.isAccessible = true + val result = field.get(pluginClassLoader) as List + field.isAccessible = false + return@let result + } + } catch (e: NoSuchFieldException) { + // This is a newer version of IntelliJ that doesn't have the files field on UrlClassLoader, + // reflect on Classpath instead. + ClassPath::class.java.getDeclaredField("files").let { field -> + field.isAccessible = true + val result = (field.get(pluginClassLoader.classPath) as Array).toList() + field.isAccessible = false + return@let result + } } - // Remove the last loaded dialect. - previouslyAddedDialect?.let { - files.removeAll(it) - } + // Filter out the last loaded dialect. + val filtered = files.filter { it != previouslyAddedDialect } + val newClasspath = filtered + dialectPath previouslyAddedDialect = dialectPath // Add the new one in. - files.addAll(dialectPath) - pluginClassLoader.classPath.reset(files) + try { + pluginClassLoader.classPath.reset(newClasspath) + } catch (e: NoSuchMethodError) { + // classPath.reset is hidden in newer versions of IntelliJ, set files reflectively. + ClassPath::class.java.getDeclaredMethod("reset").let { method -> + method.isAccessible = true + method.invoke(pluginClassLoader.classPath) + method.isAccessible = false + } + ClassPath::class.java.getDeclaredField("files").let { field -> + field.isAccessible = true + field.set(pluginClassLoader.classPath, newClasspath.toTypedArray()) + field.isAccessible = false + } + } return shouldInvalidate } From d2131507d30f2509d50f5ca7032f8dbd77307940 Mon Sep 17 00:00:00 2001 From: Madis Pink Date: Wed, 5 Apr 2023 13:47:22 +0300 Subject: [PATCH 3/7] Remove debug log line --- .../kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt index a1bebd9444d..ee23444f72c 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt @@ -101,8 +101,6 @@ internal class FileIndexMap { ?: ExternalSystemJdkUtil.getAvailableJdk(project).second.homePath )?.let { File(it) } - Timber.i("Using JAVA_HOME at %s", javaHome?.absolutePath) - val properties = connection.action(FetchProjectModelsBuildAction).setJavaHome(javaHome).run() From b0b1eb4a51bf71e686e4b2fce5e37bb0bbf8f328 Mon Sep 17 00:00:00 2001 From: Madis Pink Date: Wed, 5 Apr 2023 14:03:31 +0300 Subject: [PATCH 4/7] Fix spotless violations --- .../sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt | 2 +- .../intellij/usages/ReflectiveKotlinFindUsagesFactory.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt index 05ca51f1c2d..a0c0995a9d0 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt @@ -4,7 +4,7 @@ import com.intellij.find.findUsages.FindUsagesHandler import com.intellij.psi.PsiElement class LegacyKotlinFindUsagesFactory( - private val wrapped: org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory + private val wrapped: org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory, ) : KotlinFindUsagesHandlerFactory { override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler { return wrapped.createFindUsagesHandler(element, forHighlightUsages) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt index 8eb06e2d1f0..98ff8791b78 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt @@ -7,7 +7,7 @@ import com.intellij.psi.PsiElement import java.lang.reflect.Method class ReflectiveKotlinFindUsagesFactory( - private val wrapped: FindUsagesHandlerFactory + private val wrapped: FindUsagesHandlerFactory, ) : KotlinFindUsagesHandlerFactory { private val findFunctionOptionsMethod: Method = wrapped.javaClass.getMethod("getFindFunctionOptions") private val findPropertyOptionsMethod: Method = wrapped.javaClass.getMethod("getFindPropertyOptions") From 33a3ebb841776837736faee01caa5f5697f7043c Mon Sep 17 00:00:00 2001 From: Madis Pink Date: Wed, 5 Apr 2023 17:13:41 +0300 Subject: [PATCH 5/7] Add IDEA 2023.1 to runPluginVerifier task --- sqldelight-idea-plugin/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/sqldelight-idea-plugin/build.gradle b/sqldelight-idea-plugin/build.gradle index fc2021e0b70..9140f17dff7 100644 --- a/sqldelight-idea-plugin/build.gradle +++ b/sqldelight-idea-plugin/build.gradle @@ -42,6 +42,7 @@ tasks.named('runPluginVerifier') { "IC-2022.1.4", // AS: Electric Eel (2022.1.1) RC 1 "IC-2022.2.4", // IC "IC-2022.3.1", // IC + "IC-2023.1", // IC ] def customFailureLevel = FailureLevel.ALL From b230d167436bf4d75137f6852bb90b6cb38bb0aa Mon Sep 17 00:00:00 2001 From: Madis Pink Date: Wed, 5 Apr 2023 17:57:06 +0300 Subject: [PATCH 6/7] Fix compatibility issues as reported by plugin verifier --- .../sqldelight/core/SqlDelightEnvironment.kt | 4 +- .../SqlDelightFindUsagesHandlerFactory.kt | 6 +-- .../intellij/gradle/FileIndexMap.kt | 11 +++-- .../usages/KotlinFindUsagesHandlerFactory.kt | 22 ---------- .../usages/LegacyKotlinFindUsagesFactory.kt | 14 ------ .../ReflectiveKotlinFindUsagesFactory.kt | 44 ++++++++++++++++--- 6 files changed, 53 insertions(+), 48 deletions(-) delete mode 100644 sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt delete mode 100644 sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt diff --git a/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/SqlDelightEnvironment.kt b/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/SqlDelightEnvironment.kt index d550e5fd6fe..7ffe3627936 100644 --- a/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/SqlDelightEnvironment.kt +++ b/sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/SqlDelightEnvironment.kt @@ -37,6 +37,7 @@ import com.alecstrong.sql.psi.core.psi.SqlCreateTableStmt import com.alecstrong.sql.psi.core.psi.SqlStmt import com.intellij.core.CoreApplicationEnvironment import com.intellij.mock.MockModule +import com.intellij.openapi.extensions.ExtensionPointName import com.intellij.openapi.module.Module import com.intellij.openapi.roots.ModuleExtension import com.intellij.openapi.vfs.VirtualFile @@ -80,9 +81,10 @@ class SqlDelightEnvironment( init { project.registerService(SqlDelightProjectService::class.java, this) + @Suppress("UnresolvedPluginConfigReference") CoreApplicationEnvironment.registerExtensionPoint( module.extensionArea, - ModuleExtension.EP_NAME, + ExtensionPointName.create("com.intellij.moduleExtension"), ModuleExtension::class.java, ) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt index c78b1a15909..1f6fe103ccb 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt @@ -5,7 +5,7 @@ import app.cash.sqldelight.core.lang.SqlDelightFile import app.cash.sqldelight.core.lang.psi.StmtIdentifierMixin import app.cash.sqldelight.core.lang.queriesName import app.cash.sqldelight.core.psi.SqlDelightStmtIdentifier -import app.cash.sqldelight.intellij.usages.KotlinFindUsagesHandlerFactory +import app.cash.sqldelight.intellij.usages.ReflectiveKotlinFindUsagesFactory import com.alecstrong.sql.psi.core.psi.SqlColumnName import com.intellij.find.findUsages.FindUsagesHandler import com.intellij.find.findUsages.FindUsagesHandlerFactory @@ -43,7 +43,7 @@ class SqlDelightFindUsagesHandlerFactory : FindUsagesHandlerFactory() { private class SqlDelightIdentifierHandler( private val element: PsiElement, ) : FindUsagesHandler(element) { - private val factory = KotlinFindUsagesHandlerFactory(element.project) + private val factory = ReflectiveKotlinFindUsagesFactory(element.project) private val kotlinHandlers = when (element) { is StmtIdentifierMixin -> element.generatedMethods() is SqlColumnName -> element.generatedProperties() @@ -66,7 +66,7 @@ private class SqlDelightIdentifierHandler( ): Boolean { val generatedFiles = element.generatedVirtualFiles() val ignoringFileProcessor = Processor { t -> - if (t is KotlinReferenceUsageInfo && t.virtualFile in generatedFiles) { + if (factory.isKotlinReferenceUsageInfo(t) && t.virtualFile in generatedFiles) { return@Processor true } processor.process(t) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt index ee23444f72c..cf3a7eee3b0 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/gradle/FileIndexMap.kt @@ -189,9 +189,14 @@ internal class FileIndexMap { // Add the new one in. try { - pluginClassLoader.classPath.reset(newClasspath) - } catch (e: NoSuchMethodError) { - // classPath.reset is hidden in newer versions of IntelliJ, set files reflectively. + // older IntelliJ versions have a reset method that takes a list of files. + ClassPath::class.java.getDeclaredMethod("reset", List::class.java).let { method -> + method.isAccessible = true + method.invoke(pluginClassLoader.classPath, newClasspath) + method.isAccessible = false + } + } catch (e: NoSuchMethodException) { + // in newer versions of IntelliJ, call both argless reset and set files reflectively. ClassPath::class.java.getDeclaredMethod("reset").let { method -> method.isAccessible = true method.invoke(pluginClassLoader.classPath) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt deleted file mode 100644 index a918f6cbd1e..00000000000 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/KotlinFindUsagesHandlerFactory.kt +++ /dev/null @@ -1,22 +0,0 @@ -package app.cash.sqldelight.intellij.usages - -import com.intellij.find.findUsages.FindUsagesHandler -import com.intellij.find.findUsages.FindUsagesHandlerFactory -import com.intellij.find.findUsages.FindUsagesOptions -import com.intellij.openapi.project.Project -import com.intellij.psi.PsiElement - -interface KotlinFindUsagesHandlerFactory { - fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler - val findFunctionOptions: FindUsagesOptions - val findPropertyOptions: FindUsagesOptions -} - -fun KotlinFindUsagesHandlerFactory(project: Project): KotlinFindUsagesHandlerFactory { - return try { - val factory = Class.forName("org.jetbrains.kotlin.idea.base.searching.usages.KotlinFindUsagesHandlerFactory") - ReflectiveKotlinFindUsagesFactory(factory.getConstructor(Project::class.java).newInstance(project) as FindUsagesHandlerFactory) - } catch (e: ClassNotFoundException) { - LegacyKotlinFindUsagesFactory(org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory(project)) - } -} diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt deleted file mode 100644 index a0c0995a9d0..00000000000 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/LegacyKotlinFindUsagesFactory.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.cash.sqldelight.intellij.usages - -import com.intellij.find.findUsages.FindUsagesHandler -import com.intellij.psi.PsiElement - -class LegacyKotlinFindUsagesFactory( - private val wrapped: org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory, -) : KotlinFindUsagesHandlerFactory { - override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler { - return wrapped.createFindUsagesHandler(element, forHighlightUsages) - } - override val findFunctionOptions get() = wrapped.findFunctionOptions - override val findPropertyOptions get() = wrapped.findPropertyOptions -} diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt index 98ff8791b78..f29c4def799 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt @@ -3,19 +3,53 @@ package app.cash.sqldelight.intellij.usages import com.intellij.find.findUsages.FindUsagesHandler import com.intellij.find.findUsages.FindUsagesHandlerFactory import com.intellij.find.findUsages.FindUsagesOptions +import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement +import com.intellij.usageView.UsageInfo import java.lang.reflect.Method -class ReflectiveKotlinFindUsagesFactory( +class ReflectiveKotlinFindUsagesFactory private constructor( private val wrapped: FindUsagesHandlerFactory, -) : KotlinFindUsagesHandlerFactory { +) { + constructor(project: Project) : this(createKotlinFindUsagesHandlerFactory(project)) + private val findFunctionOptionsMethod: Method = wrapped.javaClass.getMethod("getFindFunctionOptions") private val findPropertyOptionsMethod: Method = wrapped.javaClass.getMethod("getFindPropertyOptions") - override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler { + val findFunctionOptions get() = findFunctionOptionsMethod.invoke(wrapped) as FindUsagesOptions + val findPropertyOptions get() = findPropertyOptionsMethod.invoke(wrapped) as FindUsagesOptions + + fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler { return wrapped.createFindUsagesHandler(element, forHighlightUsages)!! } - override val findFunctionOptions get() = findFunctionOptionsMethod.invoke(wrapped) as FindUsagesOptions - override val findPropertyOptions get() = findPropertyOptionsMethod.invoke(wrapped) as FindUsagesOptions + fun isKotlinReferenceUsageInfo(info: UsageInfo): Boolean { + return kotlinReferenceUsageInfoClass.isAssignableFrom(info.javaClass) + } + + companion object { + // IC 2023.1 or later + private const val kotlinUsagePackage = "org.jetbrains.kotlin.idea.base.searching.usages" + // older than IC 2023.1 + private const val legacyKotlinUsagePackage = "org.jetbrains.kotlin.idea.findUsages" + + private val factoryClass = try { + Class.forName("$kotlinUsagePackage.KotlinFindUsagesHandlerFactory") + } catch (e: ClassNotFoundException) { + // fall back to older version + Class.forName("$legacyKotlinUsagePackage.KotlinFindUsagesHandlerFactory") + } + + private val kotlinReferenceUsageInfoClass = try { + Class.forName("$kotlinUsagePackage.KotlinReferenceUsageInfo") + } catch (e: ClassNotFoundException) { + // fall back to older version + Class.forName("$legacyKotlinUsagePackage.KotlinReferenceUsageInfo") + } + + private fun createKotlinFindUsagesHandlerFactory(project: Project): FindUsagesHandlerFactory { + val ctor = factoryClass.getConstructor(Project::class.java) + return ctor.newInstance(project) as FindUsagesHandlerFactory + } + } } From 24dcd0b76649076584c6131d83173f01aff3f225 Mon Sep 17 00:00:00 2001 From: Madis Pink Date: Wed, 5 Apr 2023 18:00:24 +0300 Subject: [PATCH 7/7] Fix spotless violations --- .../sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt | 1 - .../intellij/usages/ReflectiveKotlinFindUsagesFactory.kt | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt index 1f6fe103ccb..592272f26ed 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/SqlDelightFindUsagesHandlerFactory.kt @@ -21,7 +21,6 @@ import com.intellij.psi.PsiManager import com.intellij.psi.util.PsiTreeUtil import com.intellij.usageView.UsageInfo import com.intellij.util.Processor -import org.jetbrains.kotlin.idea.findUsages.KotlinReferenceUsageInfo import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedDeclaration diff --git a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt index f29c4def799..de8c2f39be6 100644 --- a/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt +++ b/sqldelight-idea-plugin/src/main/kotlin/app/cash/sqldelight/intellij/usages/ReflectiveKotlinFindUsagesFactory.kt @@ -30,6 +30,7 @@ class ReflectiveKotlinFindUsagesFactory private constructor( companion object { // IC 2023.1 or later private const val kotlinUsagePackage = "org.jetbrains.kotlin.idea.base.searching.usages" + // older than IC 2023.1 private const val legacyKotlinUsagePackage = "org.jetbrains.kotlin.idea.findUsages"