Skip to content

Commit

Permalink
UPDATE_AA_VERSION: 2.0.0-dev-19480
Browse files Browse the repository at this point in the history
  • Loading branch information
neetopia committed Mar 28, 2024
1 parent 685b024 commit 163e0c4
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 14 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ junit5Version=5.8.2
junitPlatformVersion=1.8.2
googleTruthVersion=1.1

aaKotlinBaseVersion=2.0.0-dev-18803
aaKotlinBaseVersion=2.0.0-dev-19480
aaIntellijVersion=213.7172.25
aaGuavaVersion=29.0-jre
aaAsmVersion=9.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.google.devtools.ksp.impl.symbol.kotlin.typeArguments
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSNode
import com.google.devtools.ksp.symbol.Origin
import com.intellij.psi.PsiJavaFile
import com.intellij.util.containers.MultiMap
import com.intellij.util.io.DataExternalizer
Expand Down Expand Up @@ -252,8 +253,11 @@ internal fun recordLookupForGetAllFunctions(supers: List<KtType>) =
it is KtFunctionLikeSymbol
}

internal fun recordGetSealedSubclasses(classDeclaration: KSClassDeclaration) =
ResolverAAImpl.instance.incrementalContext.recordGetSealedSubclasses(classDeclaration)
internal fun recordGetSealedSubclasses(classDeclaration: KSClassDeclaration) {
if (classDeclaration.origin == Origin.KOTLIN) {
ResolverAAImpl.instance.incrementalContext.recordGetSealedSubclasses(classDeclaration)
}
}

class LookupTrackerWrapperImpl(val lookupTracker: LookupTracker) : LookupTrackerWrapper {
override val lookups: MultiMap<LookupSymbolWrapper, String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.google.devtools.ksp.impl.symbol.kotlin.analyze
import com.google.devtools.ksp.processing.*
import com.google.devtools.ksp.standalone.IncrementalKotlinDeclarationProviderFactory
import com.google.devtools.ksp.standalone.IncrementalKotlinPackageProviderFactory
import com.google.devtools.ksp.standalone.KspStandaloneDirectInheritorsProvider
import com.google.devtools.ksp.standalone.buildKspLibraryModule
import com.google.devtools.ksp.standalone.buildKspSourceModule
import com.google.devtools.ksp.symbol.KSFile
Expand Down Expand Up @@ -70,8 +71,8 @@ import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtSta
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.LLFirStandaloneLibrarySymbolProviderFactory
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getFirResolveSession
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.services.LLSealedInheritorsProviderFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirLibrarySymbolProviderFactory
import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLSealedInheritorsProvider
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleBuilder
import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleProviderBuilder
Expand Down Expand Up @@ -110,7 +111,6 @@ import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProviderImpl
import org.jetbrains.kotlin.fir.session.registerResolveComponents
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.platform.CommonPlatforms
Expand Down Expand Up @@ -328,19 +328,19 @@ class KotlinSymbolProcessing(
KotlinDeclarationProviderFactory::class.java,
IncrementalKotlinDeclarationProviderFactory(this)
)
registerService(
KotlinDirectInheritorsProvider::class.java,
KspStandaloneDirectInheritorsProvider::class.java
)
registerService(
KotlinDeclarationProviderMerger::class.java,
KotlinStaticDeclarationProviderMerger(this)
)
registerService(KotlinPackageProviderFactory::class.java, IncrementalKotlinPackageProviderFactory(project))

registerService(
LLSealedInheritorsProviderFactory::class.java,
object : LLSealedInheritorsProviderFactory {
override fun createSealedInheritorsProvider(): SealedClassInheritorsProvider {
return SealedClassInheritorsProviderImpl
}
}
SealedClassInheritorsProvider::class.java,
LLSealedInheritorsProvider::class.java,
)

registerService(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,11 @@ class IncrementalKotlinDeclarationProvider(var del: KotlinDeclarationProvider) :
class IncrementalKotlinDeclarationProviderFactory(
private val project: Project,
) : KotlinDeclarationProviderFactory() {
private var provider: IncrementalKotlinDeclarationProvider? = null
var provider: IncrementalKotlinDeclarationProvider? = null
private lateinit var scope: GlobalSearchScope
private var contextualModule: KtModule? = null
private var files: Collection<KtFile> = emptyList()
private lateinit var staticFactory: KotlinDeclarationProviderFactory
lateinit var staticFactory: KotlinDeclarationProviderFactory

override fun createDeclarationProvider(
scope: GlobalSearchScope,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package com.google.devtools.ksp.standalone

import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.fir.utils.isSubClassOf
import org.jetbrains.kotlin.analysis.api.standalone.base.providers.KotlinStandaloneDirectInheritorsProvider
import org.jetbrains.kotlin.analysis.low.level.api.fir.LLFirInternals
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSessionCache
import org.jetbrains.kotlin.analysis.project.structure.KtDanglingFileModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider
import org.jetbrains.kotlin.analysis.providers.KotlinDeclarationProviderFactory
import org.jetbrains.kotlin.analysis.providers.KotlinDirectInheritorsProvider
import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticDeclarationProviderFactory
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.contains

// TODO: copied from upstream as a workaround, remove after upstream fixes standalone session builder for KSP.
@OptIn(LLFirInternals::class, SymbolInternals::class)
class KspStandaloneDirectInheritorsProvider(private val project: Project) : KotlinDirectInheritorsProvider {
private val staticDeclarationProviderFactory by lazy {
(
(KotlinDeclarationProviderFactory.getInstance(project) as? IncrementalKotlinDeclarationProviderFactory)
?.staticFactory as? KotlinStaticDeclarationProviderFactory
) ?: error(
"`${KotlinStandaloneDirectInheritorsProvider::class.simpleName}" +
"` expects the following declaration provider factory to be" +
" registered: `${KotlinStaticDeclarationProviderFactory::class.simpleName}`"
)
}

override fun getDirectKotlinInheritors(
ktClass: KtClass,
scope: GlobalSearchScope,
includeLocalInheritors: Boolean,
): Iterable<KtClassOrObject> {
val classId = ktClass.getClassId() ?: return emptyList()

val aliases = mutableSetOf(classId.shortClassName)
calculateAliases(classId.shortClassName, aliases)

val possibleInheritors = aliases.flatMap { staticDeclarationProviderFactory.getDirectInheritorCandidates(it) }

if (possibleInheritors.isEmpty()) {
return emptyList()
}

// The index provides candidates from an original module, not dangling files. If we resolve the supertypes of a candidate in the
// context of its session, we will resolve to FIR classes from non-dangling, original modules. If `ktClass` is inside a dangling
// file, the FIR class for `ktClass` will come from the dangling module. So we'd compare the original FIR class for the supertype
// with the dangling FIR class for `ktClass`, resulting in a mismatch. To avoid such incompatible comparisons, we need to resolve
// `ktClass` to the original FIR class.
//
// Note that this means we don't support providing inheritors based on the dangling file yet, for example if an inheritor was added
// or removed only in the dangling file.
val baseKtModule = when (
val ktModule = ProjectStructureProvider.getModule(project, ktClass, contextualModule = null)
) {
is KtDanglingFileModule -> ktModule.contextModule
else -> ktModule
}

val baseFirClass = ktClass.toFirSymbol(classId, baseKtModule)?.fir as? FirClass ?: return emptyList()
return possibleInheritors.filter { isValidInheritor(it, baseFirClass, scope, includeLocalInheritors) }
}

private fun calculateAliases(aliasedName: Name, aliases: MutableSet<Name>) {
staticDeclarationProviderFactory.getInheritableTypeAliases(aliasedName).forEach { alias ->
val aliasName = alias.nameAsSafeName
val isNewAliasName = aliases.add(aliasName)
if (isNewAliasName) {
calculateAliases(aliasName, aliases)
}
}
}

private fun isValidInheritor(
candidate: KtClassOrObject,
baseFirClass: FirClass,
scope: GlobalSearchScope,
includeLocalInheritors: Boolean,
): Boolean {
if (!includeLocalInheritors && candidate.isLocal) {
return false
}

if (!scope.contains(candidate)) {
return false
}

val candidateClassId = candidate.getClassId() ?: return false
val candidateKtModule = ProjectStructureProvider.getModule(project, candidate, contextualModule = null)
val candidateFirSymbol = candidate.toFirSymbol(candidateClassId, candidateKtModule) ?: return false
val candidateFirClass = candidateFirSymbol.fir as? FirClass ?: return false

return isSubClassOf(
candidateFirClass,
baseFirClass,
candidateFirClass.moduleData.session,
allowIndirectSubtyping = false
)
}

private fun KtClassOrObject.toFirSymbol(classId: ClassId, ktModule: KtModule): FirClassLikeSymbol<*>? {
val session = LLFirSessionCache.getInstance(project).getSession(ktModule, preferBinary = true)
return session.symbolProvider.getClassLikeSymbolByClassId(classId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,6 @@ class KSPAATest : AbstractKSPAATest() {
runTest("../kotlin-analysis-api/testData/resolveJavaType.kt")
}

@Disabled
@TestMetadata("sealedClass.kt")
@Test
fun testSealedClass() {
Expand Down

0 comments on commit 163e0c4

Please sign in to comment.