From 97774aa1cf12ef72fc65df66cab5b9ec03a87fa5 Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Fri, 10 Mar 2023 17:08:29 -0800 Subject: [PATCH] AA: include java files for class declaration index. * minor fix to property qualified name. --- .../ksp/impl/KotlinSymbolProcessing.kt | 5 +- .../devtools/ksp/impl/ResolverAAImpl.kt | 52 ++++++++++++++++++- .../kotlin/KSPropertyDeclarationImpl.kt | 4 +- .../ksp/impl/test/AbstractKSPAATest.kt | 2 +- 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt index 91efb6d957..ac6676617d 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/KotlinSymbolProcessing.kt @@ -107,7 +107,8 @@ class KotlinSymbolProcessing( ktFiles.map { analyze { it.getFileSymbol() } }, - javaFiles + options, + project ) ResolverAAImpl.instance = resolver processors.forEach { it.process(resolver) } @@ -119,7 +120,7 @@ fun main(args: Array) { val commandLineProcessor = KSPCommandLineProcessor(compilerConfiguration) val logger = CommandLineKSPLogger() - val analysisSession = buildStandaloneAnalysisAPISession { + val analysisSession = buildStandaloneAnalysisAPISession(withPsiDeclarationFromBinaryModuleProvider = true) { buildKtModuleProviderByCompilerConfiguration(compilerConfiguration) } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt index 687b2242f9..328f2406f0 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/ResolverAAImpl.kt @@ -18,6 +18,7 @@ package com.google.devtools.ksp.impl import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.KspOptions import com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationEnumEntryImpl import com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationImpl import com.google.devtools.ksp.impl.symbol.kotlin.KSFileImpl @@ -46,10 +47,15 @@ import com.google.devtools.ksp.symbol.KSType import com.google.devtools.ksp.symbol.KSTypeArgument import com.google.devtools.ksp.symbol.KSTypeReference import com.google.devtools.ksp.symbol.Modifier +import com.google.devtools.ksp.symbol.Origin import com.google.devtools.ksp.symbol.Variance import com.google.devtools.ksp.toKSName import com.google.devtools.ksp.visitor.CollectAnnotatedSymbolsVisitor +import com.intellij.openapi.project.Project +import com.intellij.openapi.vfs.StandardFileSystems +import com.intellij.openapi.vfs.VirtualFileManager import com.intellij.psi.PsiJavaFile +import com.intellij.psi.PsiManager import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol @@ -64,17 +70,33 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name +import java.io.File +import java.nio.file.Files @OptIn(KspExperimental::class) class ResolverAAImpl( val ktFiles: List, - val javaFiles: List + val options: KspOptions, + val project: Project ) : Resolver { companion object { lateinit var instance: ResolverAAImpl lateinit var ktModule: KtModule } + val javaFiles: List + init { + val psiManager = PsiManager.getInstance(project) + val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL) + // Get non-symbolic paths first + javaFiles = options.javaSourceRoots.sortedBy { Files.isSymbolicLink(it.toPath()) } + .flatMap { root -> root.walk().filter { it.isFile && it.extension == "java" }.toList() } + // This time is for .java files + .sortedBy { Files.isSymbolicLink(it.toPath()) } + .distinctBy { it.canonicalPath } + .mapNotNull { localFileSystem.findFileByPath(it.path)?.let { psiManager.findFile(it) } as? PsiJavaFile } + } + private val ksFiles by lazy { ktFiles.map { KSFileImpl.getCached(it) } + javaFiles.map { KSFileJavaImpl.getCached(it) } } @@ -166,10 +188,36 @@ class ResolverAAImpl( else -> null } } - }.asSequence() + }.plus(javaPackageToClassMap.getOrDefault(packageName, emptyList()).asSequence()).asSequence() } } + private val javaPackageToClassMap: Map> by lazy { + val packageToClassMapping = mutableMapOf>() + ksFiles + .filter { file -> + file.origin == Origin.JAVA && + options.javaSourceRoots.any { root -> + file.filePath.startsWith(root.absolutePath) && + file.filePath.substringAfter(root.absolutePath) + .dropLastWhile { c -> c != File.separatorChar }.dropLast(1).drop(1) + .replace(File.separatorChar, '.') == file.packageName.asString() + } + } + .forEach { + packageToClassMapping.put( + it.packageName.asString(), + packageToClassMapping.getOrDefault(it.packageName.asString(), emptyList()) + .plus( + it.declarations.filterNot { + it.containingFile?.fileName?.split(".")?.first() == it.simpleName.asString() + } + ) + ) + } + packageToClassMapping + } + override fun getDeclarationsInSourceOrder(container: KSDeclarationContainer): Sequence { TODO("Not yet implemented") } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt index e1d51e82be..ba5f676c1e 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt @@ -98,7 +98,9 @@ class KSPropertyDeclarationImpl private constructor(internal val ktPropertySymbo } override val qualifiedName: KSName? by lazy { - KSNameImpl.getCached("${parentDeclaration?.qualifiedName?.asString()}.${this.simpleName.asString()}") + val name = ktPropertySymbol.callableIdIfNonLocal?.asSingleFqName()?.asString() + ?: ("${parentDeclaration?.qualifiedName?.asString()}.${this.simpleName.asString()}") + KSNameImpl.getCached(name) } override fun accept(visitor: KSVisitor, data: D): R { diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/AbstractKSPAATest.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/AbstractKSPAATest.kt index 39687c831c..69da8a6d9a 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/AbstractKSPAATest.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/AbstractKSPAATest.kt @@ -142,7 +142,7 @@ abstract class AbstractKSPAATest : AbstractKSPTest(FrontendKinds.FIR) { cachesDir = File(testRoot, "kspTest/kspCaches") kspOutputDir = File(testRoot, "kspTest") }.build() - val analysisSession = buildStandaloneAnalysisAPISession { + val analysisSession = buildStandaloneAnalysisAPISession(withPsiDeclarationFromBinaryModuleProvider = true) { buildKtModuleProviderByCompilerConfiguration(compilerConfiguration) } val ksp = KotlinSymbolProcessing(