Skip to content

Commit

Permalink
Merge branch 'main' into z/moduleName
Browse files Browse the repository at this point in the history
  • Loading branch information
ZacSweers committed Apr 3, 2024
2 parents 9266fc5 + d87c083 commit d89ee65
Show file tree
Hide file tree
Showing 26 changed files with 703 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,23 @@ package com.google.devtools.ksp.common
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSType

private inline fun Any?.idHashCode() = System.identityHashCode(this)

class IdKey<T>(private val k: T) {
override fun equals(other: Any?): Boolean = if (other is IdKey<*>) k === other.k else false
override fun hashCode(): Int = k.hashCode()
override fun hashCode(): Int = k.idHashCode()
}

class IdKeyPair<T, P>(private val k1: T, private val k2: P) {
override fun equals(other: Any?): Boolean = if (other is IdKeyPair<*, *>) k1 === other.k1 &&
k2 === other.k2 else false
override fun hashCode(): Int = k1.hashCode() * 31 + k2.hashCode()
override fun hashCode(): Int = k1.idHashCode() * 31 + k2.idHashCode()
}

class IdKeyTriple<T, P, Q>(private val k1: T, private val k2: P, private val k3: Q) {
override fun equals(other: Any?): Boolean = if (other is IdKeyTriple<*, *, *>) k1 === other.k1 &&
k2 === other.k2 && k3 === other.k3 else false
override fun hashCode(): Int = k1.hashCode() * 31 * 31 + k2.hashCode() * 31 + k3.hashCode()
override fun hashCode(): Int = k1.idHashCode() * 31 * 31 + k2.idHashCode() * 31 + k3.idHashCode()
}

@SuppressWarnings("UNCHECKED_CAST")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.ClassBuilderMode
import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.state.JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.codegen.state.JVM_WILDCARD_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.container.ComponentProvider
Expand All @@ -83,6 +81,8 @@ import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaMethod
import org.jetbrains.kotlin.load.kotlin.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.JvmStandardClassIds.JVM_SUPPRESS_WILDCARDS_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.name.JvmStandardClassIds.JVM_WILDCARD_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.*
Expand Down Expand Up @@ -518,31 +518,38 @@ class ResolverImpl(
}
}

private val synthesizedPropPrefix = mapOf<String, (PropertyDescriptor?) -> PropertyAccessorDescriptor?>(
"set" to { it?.setter },
"get" to { it?.getter },
"is" to { it?.getter },
)

// TODO: Resolve Java variables is not supported by this function. Not needed currently.
fun resolveJavaDeclaration(psi: PsiElement): DeclarationDescriptor? {
return when (psi) {
is PsiClass -> moduleClassResolver.resolveClass(JavaClassImpl(psi))
is PsiMethod -> {
// TODO: get rid of hardcoded check if possible.
val property = if (psi.name.startsWith("set") || psi.name.startsWith("get")) {
moduleClassResolver
.resolveContainingClass(psi)
?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.CALLABLES
) {
(it as? PropertyDescriptor)?.getter?.findPsi() == psi ||
(it as? PropertyDescriptor)?.setter?.findPsi() == psi
}
} else null
val property = synthesizedPropPrefix.keys.firstOrNull {
psi.name.startsWith(it) && psi.name.length > it.length && psi.name[it.length].isUpperCase()
}?.let { prefix ->
val propName = psi.name.substring(prefix.length).replaceFirstChar(Char::lowercaseChar)
moduleClassResolver.resolveContainingClass(psi)?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.VARIABLES,
name = propName
) {
synthesizedPropPrefix[prefix]!!(it as? PropertyDescriptor)?.correspondsTo(psi) == true
}
}
property ?: moduleClassResolver
.resolveContainingClass(psi)?.let { containingClass ->
val filter = if (psi is SyntheticElement) {
{ declaration: DeclarationDescriptor -> declaration.name.asString() == psi.name }
} else {
{ declaration: DeclarationDescriptor -> declaration.findPsi() == psi }
{ declaration: DeclarationDescriptor -> declaration.correspondsTo(psi) }
}
containingClass.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.FUNCTIONS,
name = if (psi.name == containingClass.name.asString()) "<init>" else psi.name,
filter = filter
)
}
Expand All @@ -552,7 +559,8 @@ class ResolverImpl(
.resolveClass(JavaFieldImpl(psi).containingClass)
?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.VARIABLES,
filter = { it.findPsi() == psi }
name = psi.name,
filter = { it.correspondsTo(psi) }
)
}
else -> throw IllegalStateException("unhandled psi element kind: ${psi.javaClass}")
Expand Down Expand Up @@ -748,7 +756,8 @@ class ResolverImpl(
moduleClassResolver.resolveContainingClass(owner)
?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.FUNCTIONS,
filter = { it.findPsi() == owner }
name = owner.name,
filter = { it.correspondsTo(owner) }
) as FunctionDescriptor
} as DeclarationDescriptor
val typeParameterDescriptor = LazyJavaTypeParameterDescriptor(
Expand Down Expand Up @@ -1407,6 +1416,39 @@ class ResolverImpl(
}.toMap()

internal fun findPsiJavaFile(path: String): PsiFile? = psiJavaFiles.get(path)

// Always construct the key on the fly, so that it and value can be reclaimed any time.
private val contributedDescriptorsCache =
WeakHashMap<Pair<MemberScope, DescriptorKindFilter>, Map<String, List<DeclarationDescriptor>>>()

private inline fun MemberScope.findEnclosedDescriptor(
kindFilter: DescriptorKindFilter,
name: String,
crossinline filter: (DeclarationDescriptor) -> Boolean,
): DeclarationDescriptor? {
val nameToDescriptors = contributedDescriptorsCache.computeIfAbsent(Pair(this, kindFilter)) {
getContributedDescriptors(kindFilter).groupBy { it.name.asString() }
}
return nameToDescriptors.get(name)?.firstOrNull(filter)
}

private inline fun ClassDescriptor.findEnclosedDescriptor(
kindFilter: DescriptorKindFilter,
name: String,
crossinline filter: (DeclarationDescriptor) -> Boolean,
): DeclarationDescriptor? {
return this.unsubstitutedMemberScope.findEnclosedDescriptor(
kindFilter = kindFilter,
name = name,
filter = filter
) ?: this.staticScope.findEnclosedDescriptor(
kindFilter = kindFilter,
name = name,
filter = filter
) ?: constructors.firstOrNull {
kindFilter.accepts(it) && filter(it)
}
}
}

// TODO: cross module resolution
Expand Down Expand Up @@ -1474,30 +1516,6 @@ private fun Name.getNonSpecialIdentifier(): String {
}
}

private inline fun MemberScope.findEnclosedDescriptor(
kindFilter: DescriptorKindFilter,
crossinline filter: (DeclarationDescriptor) -> Boolean,
): DeclarationDescriptor? {
return getContributedDescriptors(
kindFilter = kindFilter
).firstOrNull(filter)
}

private inline fun ClassDescriptor.findEnclosedDescriptor(
kindFilter: DescriptorKindFilter,
crossinline filter: (DeclarationDescriptor) -> Boolean,
): DeclarationDescriptor? {
return this.unsubstitutedMemberScope.findEnclosedDescriptor(
kindFilter = kindFilter,
filter = filter
) ?: this.staticScope.findEnclosedDescriptor(
kindFilter = kindFilter,
filter = filter
) ?: constructors.firstOrNull {
kindFilter.accepts(it) && filter(it)
}
}

internal fun KSAnnotated.findAnnotationFromUseSiteTarget(): Sequence<KSAnnotation> {
return when (this) {
is KSPropertyGetter -> (this.receiver as? KSDeclarationImpl)?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,11 @@ fun DeclarationDescriptor.findPsi(): PsiElement? {
return leaf.parentsWithSelf.firstOrNull { psi.manager.areElementsEquivalent(it, psi) }
}

fun DeclarationDescriptor.correspondsTo(candidate: PsiElement): Boolean {
val psi = (this as? DeclarationDescriptorWithSource)?.source?.getPsi() ?: return false
return psi.manager.areElementsEquivalent(psi, candidate)
}

internal fun KSFile.getPackageAnnotations() = (this as? KSFileJavaImpl)?.psi?.packageStatement
?.annotationList?.annotations?.map { KSAnnotationJavaImpl.getCached(it) } ?: emptyList<KSAnnotation>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,21 @@ abstract class KspAATask @Inject constructor(
cfg.moduleName.value(kotlinCompilation.defaultSourceSet.name)
val kotlinOutputDir = KspGradleSubplugin.getKspKotlinOutputDir(project, sourceSetName, target)
val javaOutputDir = KspGradleSubplugin.getKspJavaOutputDir(project, sourceSetName, target)
val filteredTasks =
kspExtension.excludedSources.buildDependencies.getDependencies(null).map { it.name }
kotlinCompilation.allKotlinSourceSetsObservable.forAll { sourceSet ->
val filtered = sourceSet.kotlin.srcDirs.filter {
!kotlinOutputDir.isParentOf(it) && !javaOutputDir.isParentOf(it)
!kotlinOutputDir.isParentOf(it) && !javaOutputDir.isParentOf(it) &&
it !in kspExtension.excludedSources
}.map {
// @SkipWhenEmpty doesn't work well with File.
project.objects.fileTree().from(it)
}
cfg.sourceRoots.from(filtered)
cfg.javaSourceRoots.from(filtered)
kspAATask.dependsOn(sourceSet.kotlin.nonSelfDeps(kspTaskName))
kspAATask.dependsOn(
sourceSet.kotlin.nonSelfDeps(kspTaskName).filter { it.name !in filteredTasks }
)
}
if (kotlinCompilation is KotlinCommonCompilation) {
cfg.commonSourceRoots.from(kotlinCompilation.defaultSourceSet.kotlin)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@
package com.google.devtools.ksp.gradle

import org.gradle.api.GradleException
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.process.CommandLineArgumentProvider

open class KspExtension {
abstract class KspExtension {
internal val apOptions = mutableMapOf<String, String>()
internal val commandLineArgumentProviders = mutableListOf<CommandLineArgumentProvider>()
internal val excludedProcessors = mutableSetOf<String>()

// Specify sources that should be excluded from KSP.
// If you have a task that generates sources, you can call `ksp.excludedSources.from(task)`.
abstract val excludedSources: ConfigurableFileCollection

open val arguments: Map<String, String> get() = apOptions.toMap()

open fun arg(k: String, v: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,16 @@ class KspGradleSubplugin @Inject internal constructor(private val registry: Tool
)
}
} else {
val filteredTasks =
kspExtension.excludedSources.buildDependencies.getDependencies(null).map { it.name }
kotlinCompilation.allKotlinSourceSetsObservable.forAll { sourceSet ->
kspTask.setSource(
sourceSet.kotlin.srcDirs.filter {
!kotlinOutputDir.isParentOf(it) && !javaOutputDir.isParentOf(it)
!kotlinOutputDir.isParentOf(it) && !javaOutputDir.isParentOf(it) &&
it !in kspExtension.excludedSources
}
)
kspTask.dependsOn(sourceSet.kotlin.nonSelfDeps(kspTaskName))
kspTask.dependsOn(sourceSet.kotlin.nonSelfDeps(kspTaskName).filter { it.name !in filteredTasks })
}
}

Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Copied from kotlinc
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx2200m -Dfile.encoding=UTF-8

kotlinBaseVersion=2.0.0-dev-15455
kotlinBaseVersion=2.0.0-dev-19480
agpBaseVersion=7.2.0
intellijVersion=213.7172.25
junitVersion=4.13.1
junit5Version=5.8.2
junitPlatformVersion=1.8.2
googleTruthVersion=1.1

aaKotlinBaseVersion=2.0.0-dev-15455
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.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.builder.KtModuleBuilder
Expand Down Expand Up @@ -111,7 +112,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 @@ -329,19 +329,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

0 comments on commit d89ee65

Please sign in to comment.