Created
July 27, 2025 00:41
-
-
Save LionZXY/4ca174c713c9e0df69a63af4ee017806 to your computer and use it in GitHub Desktop.
Metro Migration Assisted
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 isUsedAsLambdaReturnType(ref: PsiReference): Boolean { | |
val element = ref.element | |
// Try to find if we are inside a function literal (lambda) | |
val lambda = element.parent?.parent?.parent?.let { ancestor -> | |
PsiTreeUtil.getParentOfType(ancestor, KtLambdaExpression::class.java) | |
} ?: return false | |
// Not 100% reliable without binding info, but can heuristically check: | |
return lambda.parent is KtLambdaArgument && | |
element.text == ref.canonicalText // ensure reference matches class name used | |
} | |
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