Skip to content

Instantly share code, notes, and snippets.

@LionZXY
Created July 28, 2025 19:53
Show Gist options
  • Save LionZXY/867ea0a15cc5744bc1bf2ec9434c221c to your computer and use it in GitHub Desktop.
Save LionZXY/867ea0a15cc5744bc1bf2ec9434c221c to your computer and use it in GitHub Desktop.
metro-migration-all
// depends-on-plugin org.jetbrains.kotlin
// depends-on-plugin com.intellij.java.ide
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.application.ReadAction
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.fileTypes.FileTypeManager
import com.intellij.openapi.project.Project
import com.intellij.psi.search.FileTypeIndex
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiReference
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.elementType
import liveplugin.PluginUtil.show
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtLambdaArgument
import org.jetbrains.kotlin.psi.KtLambdaExpression
fun findInjectAnnotatedKotlinClasses(project: Project): List<KtClass> {
val psiManager = PsiManager.getInstance(project)
val kotlinFileType = FileTypeManager.getInstance().getFileTypeByExtension("kt")
val searchScope = GlobalSearchScope.projectScope(project)
val injectAnnotatedClasses = mutableListOf<KtClass>()
val allKtFiles: Collection<VirtualFile> = FileTypeIndex.getFiles(kotlinFileType, searchScope)
ReadAction.run<RuntimeException> {
for (virtualFile in allKtFiles) {
val psiFile = psiManager.findFile(virtualFile) as? KtFile ?: continue
val ktClasses = psiFile.declarations.filterIsInstance<KtClass>()
for (ktClass in ktClasses) {
val annotationEntries = ktClass.annotationEntries
if (annotationEntries.any { it.shortName?.asString() == "Inject" } && hasAssistedParameter(ktClass)) {
injectAnnotatedClasses.add(ktClass)
}
}
}
}
return injectAnnotatedClasses
}
fun hasAssistedParameter(ktClass: KtClass): Boolean {
val constructor = ktClass.primaryConstructor ?: return false
val parameters = constructor.valueParameters
for (param in parameters) {
if (param.annotationEntries.any {
it.shortName?.asString() == "Assisted"
}
) {
return true
}
}
return false
}
fun processOneClass(ktClass: KtClass, project: Project) {
val usages = ReferencesSearch.search(ktClass, GlobalSearchScope.projectScope(project)).findAll().toList()
show("Process ${ktClass.fqName?.asString()} with ${usages.size} usages")
usages.forEach {
var parent = it.element.parent
while (parent != null) {
if (PsiTreeUtil.getParentOfType(parent, KtLambdaExpression::class.java) != null) {
show("Find!")
}
//show("Parent is ${parent.elementType?.debugName}")
parent = parent.parent
}
}
}
val project = ProjectManager.getInstance().openProjects.firstOrNull()
if (project != null) {
val classes = findInjectAnnotatedKotlinClasses(project)
if (classes.isEmpty()) {
show("No Kotlin classes with @Inject found.")
} else {
processOneClass(classes.first(), project)
}
} else {
show("No open project found.")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment