Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A mitigation for processors with memory leaks #1067

Merged
merged 2 commits into from Aug 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -221,7 +221,10 @@ abstract class AbstractKotlinSymbolProcessingExtension(
findTargetInfos(module)
)
)
}?.let { analysisResult -> return@doAnalysis analysisResult }
}?.let { analysisResult ->
resolver.tearDown()
return@doAnalysis analysisResult
}
if (logger.hasError()) {
return@mapNotNull null
}
Expand All @@ -237,7 +240,10 @@ abstract class AbstractKotlinSymbolProcessingExtension(
handleException(module, project) {
deferredSymbols[processor] =
processor.process(resolver).filter { it.origin == Origin.KOTLIN || it.origin == Origin.JAVA }
}?.let { return it }
}?.let {
resolver.tearDown()
return it
}
if (logger.hasError()) {
return@processing
}
Expand All @@ -259,14 +265,20 @@ abstract class AbstractKotlinSymbolProcessingExtension(
processors.forEach { processor ->
handleException(module, project) {
processor.onError()
}?.let { return it }
}?.let {
resolver.tearDown()
return it
}
}
} else {
if (finished) {
processors.forEach { processor ->
handleException(module, project) {
processor.finish()
}?.let { return it }
}?.let {
resolver.tearDown()
return it
}
}
if (deferredSymbols.isNotEmpty()) {
deferredSymbols.map { entry ->
Expand All @@ -289,6 +301,7 @@ abstract class AbstractKotlinSymbolProcessingExtension(
if (finished) {
logger.reportAll()
}
resolver.tearDown()
return if (finished && !options.withCompilation) {
if (!options.returnOkOnError && logger.hasError()) {
AnalysisResult.compilationError(BindingContext.EMPTY)
Expand Down
Expand Up @@ -109,7 +109,6 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.SimpleClassicTypeSystemContext
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
import org.jetbrains.kotlin.types.typeUtil.substitute
import org.jetbrains.kotlin.types.typeUtil.supertypes
Expand Down Expand Up @@ -158,27 +157,23 @@ class ResolverImpl(
}

companion object {
lateinit var resolveSession: ResolveSession
lateinit var bodyResolver: BodyResolver
lateinit var constantExpressionEvaluator: ConstantExpressionEvaluator
lateinit var declarationScopeProvider: DeclarationScopeProvider
lateinit var topDownAnalyzer: LazyTopDownAnalyzer
lateinit var instance: ResolverImpl
lateinit var annotationResolver: AnnotationResolver
lateinit var moduleClassResolver: ModuleClassResolver
lateinit var javaTypeResolver: JavaTypeResolver
lateinit var lazyJavaResolverContext: LazyJavaResolverContext
lateinit var doubleColonExpressionResolver: DoubleColonExpressionResolver
var instance: ResolverImpl? = null
}

var resolveSession: ResolveSession
var bodyResolver: BodyResolver
var constantExpressionEvaluator: ConstantExpressionEvaluator
var declarationScopeProvider: DeclarationScopeProvider

lateinit var moduleClassResolver: ModuleClassResolver
lateinit var javaTypeResolver: JavaTypeResolver
lateinit var lazyJavaResolverContext: LazyJavaResolverContext

init {
resolveSession = componentProvider.get()
bodyResolver = componentProvider.get()
declarationScopeProvider = componentProvider.get()
topDownAnalyzer = componentProvider.get()
constantExpressionEvaluator = componentProvider.get()
doubleColonExpressionResolver = componentProvider.get()
annotationResolver = resolveSession.annotationResolver

componentProvider.tryGetService(JavaResolverComponents::class.java)?.let {
lazyJavaResolverContext = LazyJavaResolverContext(it, TypeParameterResolver.EMPTY) { null }
Expand Down Expand Up @@ -222,6 +217,12 @@ class ResolverImpl(
allKSFiles.forEach { it.accept(visitor, Unit) }
}

// Mitigation for processors with memory leaks
// https://github.com/google/ksp/issues/1063
fun tearDown() {
instance = null
}

override fun getNewFiles(): Sequence<KSFile> {
return newKSFiles.asSequence()
}
Expand Down
Expand Up @@ -109,7 +109,7 @@ class KSAnnotationDescriptorImpl private constructor(

private fun ClassId.findKSClassDeclaration(): KSClassDeclaration? {
val ksName = KSNameImpl.getCached(this.asSingleFqName().asString().replace("$", "."))
return ResolverImpl.instance.getClassDeclarationByName(ksName)
return ResolverImpl.instance!!.getClassDeclarationByName(ksName)
}

private fun ClassId.findKSType(): KSType? = findKSClassDeclaration()?.asStarProjectedType()
Expand All @@ -126,9 +126,9 @@ private fun <T> ConstantValue<T>.toValue(parent: KSNode): Any? = when (this) {
classValue.value.classId.findKSType()?.let { componentType ->
var resultingType = componentType
for (i in 1..classValue.arrayDimensions) {
resultingType = ResolverImpl.instance.builtIns.arrayType.replace(
resultingType = ResolverImpl.instance!!.builtIns.arrayType.replace(
listOf(
ResolverImpl.instance.getTypeArgument(
ResolverImpl.instance!!.getTypeArgument(
KSTypeReferenceSyntheticImpl.getCached(resultingType, null), Variance.INVARIANT
)
)
Expand Down Expand Up @@ -250,7 +250,7 @@ fun ValueParameterDescriptor.getDefaultValue(ownerAnnotation: KSAnnotation): Any
}
is JavaAnnotationAsAnnotationArgument -> {
AnnotationValue(
LazyJavaAnnotationDescriptor(ResolverImpl.lazyJavaResolverContext, this.getAnnotation())
LazyJavaAnnotationDescriptor(ResolverImpl.instance!!.lazyJavaResolverContext, this.getAnnotation())
)
}
is JavaClassObjectAnnotationArgument -> {
Expand Down Expand Up @@ -310,7 +310,7 @@ fun ValueParameterDescriptor.getDefaultValue(ownerAnnotation: KSAnnotation): Any
}
}
is KtParameter -> if (!this.type.isError) {
ResolverImpl.instance.evaluateConstant(psi.defaultValue, this.type)?.toValue(ownerAnnotation)
ResolverImpl.instance!!.evaluateConstant(psi.defaultValue, this.type)?.toValue(ownerAnnotation)
} else {
KSErrorType
}
Expand Down
Expand Up @@ -75,8 +75,8 @@ class KSClassDeclarationDescriptorImpl private constructor(val descriptor: Class
}

// Workaround for https://github.com/google/ksp/issues/195
private val mockSerializableType = ResolverImpl.instance.mockSerializableType
private val javaSerializableType = ResolverImpl.instance.javaSerializableType
private val mockSerializableType = ResolverImpl.instance!!.mockSerializableType
private val javaSerializableType = ResolverImpl.instance!!.javaSerializableType

override val superTypes: Sequence<KSTypeReference> by lazy {

Expand Down Expand Up @@ -155,7 +155,7 @@ class KSClassDeclarationDescriptorImpl private constructor(val descriptor: Class
}

internal fun ClassDescriptor.getAllFunctions(): Sequence<KSFunctionDeclaration> {
ResolverImpl.instance.incrementalContext.recordLookupForGetAllFunctions(this)
ResolverImpl.instance!!.incrementalContext.recordLookupForGetAllFunctions(this)
val functionDescriptors = unsubstitutedMemberScope.getDescriptorsFiltered(DescriptorKindFilter.FUNCTIONS)
.asSequence()
.filter { (it as FunctionDescriptor).visibility != DescriptorVisibilities.INVISIBLE_FAKE }
Expand All @@ -169,7 +169,7 @@ internal fun ClassDescriptor.getAllFunctions(): Sequence<KSFunctionDeclaration>
}

internal fun ClassDescriptor.getAllProperties(): Sequence<KSPropertyDeclaration> {
ResolverImpl.instance.incrementalContext.recordLookupForGetAllProperties(this)
ResolverImpl.instance!!.incrementalContext.recordLookupForGetAllProperties(this)
return unsubstitutedMemberScope.getDescriptorsFiltered(DescriptorKindFilter.VARIABLES).asSequence()
.filter { (it as PropertyDescriptor).visibility != DescriptorVisibilities.INVISIBLE_FAKE }
.map {
Expand Down
Expand Up @@ -110,5 +110,5 @@ class KSFunctionDeclarationDescriptorImpl private constructor(val descriptor: Fu
}

override fun asMemberOf(containing: KSType): KSFunction =
ResolverImpl.instance.asMemberOf(this, containing)
ResolverImpl.instance!!.asMemberOf(this, containing)
}
Expand Up @@ -107,7 +107,7 @@ class KSPropertyDeclarationDescriptorImpl private constructor(val descriptor: Pr
}

override fun findOverridee(): KSPropertyDeclaration? {
val propertyDescriptor = ResolverImpl.instance.resolvePropertyDeclaration(this)
val propertyDescriptor = ResolverImpl.instance!!.resolvePropertyDeclaration(this)
return propertyDescriptor?.findClosestOverridee()?.toKSPropertyDeclaration()
}

Expand All @@ -120,5 +120,5 @@ class KSPropertyDeclarationDescriptorImpl private constructor(val descriptor: Pr
}

override fun asMemberOf(containing: KSType): KSType =
ResolverImpl.instance.asMemberOf(this, containing)
ResolverImpl.instance!!.asMemberOf(this, containing)
}
Expand Up @@ -119,16 +119,16 @@ class KSAnnotationJavaImpl private constructor(val psi: PsiAnnotation) : KSAnnot
private fun resolveJavaTypeSimple(psiType: PsiType): KSType {
return when (psiType) {
is PsiPrimitiveType -> {
ResolverImpl.instance.getClassDeclarationByName(psiType.boxedTypeName!!)!!.asStarProjectedType()
ResolverImpl.instance!!.getClassDeclarationByName(psiType.boxedTypeName!!)!!.asStarProjectedType()
}
is PsiArrayType -> {
val componentType = resolveJavaTypeSimple(psiType.componentType)
val componentTypeRef = ResolverImpl.instance.createKSTypeReferenceFromKSType(componentType)
val typeArgs = listOf(ResolverImpl.instance.getTypeArgument(componentTypeRef, Variance.INVARIANT))
ResolverImpl.instance.builtIns.arrayType.replace(typeArgs)
val componentTypeRef = ResolverImpl.instance!!.createKSTypeReferenceFromKSType(componentType)
val typeArgs = listOf(ResolverImpl.instance!!.getTypeArgument(componentTypeRef, Variance.INVARIANT))
ResolverImpl.instance!!.builtIns.arrayType.replace(typeArgs)
}
else -> {
ResolverImpl.instance.getClassDeclarationByName(psiType.canonicalText)?.asStarProjectedType()
ResolverImpl.instance!!.getClassDeclarationByName(psiType.canonicalText)?.asStarProjectedType()
?: KSErrorType
}
}
Expand Down Expand Up @@ -160,7 +160,7 @@ class KSAnnotationJavaImpl private constructor(val psi: PsiAnnotation) : KSAnnot
if (containingClass?.classKind == JvmClassKind.ENUM) {
// this is an enum entry
containingClass.qualifiedName?.let {
ResolverImpl.instance.getClassDeclarationByName(it)
ResolverImpl.instance!!.getClassDeclarationByName(it)
}?.declarations?.find {
it is KSClassDeclaration && it.classKind == ClassKind.ENUM_ENTRY &&
it.simpleName.asString() == result.name
Expand Down
Expand Up @@ -61,7 +61,7 @@ class KSClassDeclarationJavaEnumEntryImpl private constructor(val psi: PsiEnumCo
override fun getSealedSubclasses(): Sequence<KSClassDeclaration> = emptySequence()

private val descriptor: ClassDescriptor? by lazy {
ResolverImpl.instance.resolveJavaDeclaration(psi) as ClassDescriptor
ResolverImpl.instance!!.resolveJavaDeclaration(psi) as ClassDescriptor
}

override fun getAllFunctions(): Sequence<KSFunctionDeclaration> =
Expand Down
Expand Up @@ -74,7 +74,7 @@ class KSClassDeclarationJavaImpl private constructor(val psi: PsiClass) :

// Could the resolution ever fail?
private val descriptor: ClassDescriptor? by lazy {
ResolverImpl.moduleClassResolver.resolveClass(JavaClassImpl(psi))
ResolverImpl.instance!!.moduleClassResolver.resolveClass(JavaClassImpl(psi))
}

// TODO in 1.5 + jvmTarget 15, will we return Java permitted types?
Expand Down
Expand Up @@ -54,7 +54,7 @@ class KSFunctionDeclarationJavaImpl private constructor(val psi: PsiMethod) :
}

override fun findOverridee(): KSDeclaration? {
val descriptor = ResolverImpl.instance.resolveFunctionDeclaration(this)
val descriptor = ResolverImpl.instance!!.resolveFunctionDeclaration(this)
return descriptor.safeAs<FunctionDescriptor>()?.findClosestOverridee()?.toKSDeclaration()
}

Expand Down Expand Up @@ -122,5 +122,5 @@ class KSFunctionDeclarationJavaImpl private constructor(val psi: PsiMethod) :
}

override fun asMemberOf(containing: KSType): KSFunction =
ResolverImpl.instance.asMemberOf(this, containing)
ResolverImpl.instance!!.asMemberOf(this, containing)
}
Expand Up @@ -96,5 +96,5 @@ class KSPropertyDeclarationJavaImpl private constructor(val psi: PsiField) :
}

override fun asMemberOf(containing: KSType): KSType =
ResolverImpl.instance.asMemberOf(this, containing)
ResolverImpl.instance!!.asMemberOf(this, containing)
}
Expand Up @@ -68,15 +68,15 @@ class KSTypeReferenceJavaImpl private constructor(val psi: PsiType, override val
override val element: KSReferenceElement by lazy {
fun PsiPrimitiveType.toKotlinType(): KotlinType {
return when (this.name) {
"int" -> ResolverImpl.instance.module.builtIns.intType
"short" -> ResolverImpl.instance.module.builtIns.shortType
"byte" -> ResolverImpl.instance.module.builtIns.byteType
"long" -> ResolverImpl.instance.module.builtIns.longType
"float" -> ResolverImpl.instance.module.builtIns.floatType
"double" -> ResolverImpl.instance.module.builtIns.doubleType
"char" -> ResolverImpl.instance.module.builtIns.charType
"boolean" -> ResolverImpl.instance.module.builtIns.booleanType
"void" -> ResolverImpl.instance.module.builtIns.unitType
"int" -> ResolverImpl.instance!!.module.builtIns.intType
"short" -> ResolverImpl.instance!!.module.builtIns.shortType
"byte" -> ResolverImpl.instance!!.module.builtIns.byteType
"long" -> ResolverImpl.instance!!.module.builtIns.longType
"float" -> ResolverImpl.instance!!.module.builtIns.floatType
"double" -> ResolverImpl.instance!!.module.builtIns.doubleType
"char" -> ResolverImpl.instance!!.module.builtIns.charType
"boolean" -> ResolverImpl.instance!!.module.builtIns.booleanType
"void" -> ResolverImpl.instance!!.module.builtIns.unitType
else -> throw IllegalStateException("Unexpected primitive type ${this.name}, $ExceptionMessage")
}
}
Expand All @@ -91,31 +91,31 @@ class KSTypeReferenceJavaImpl private constructor(val psi: PsiType, override val
is PsiWildcardType -> KSClassifierReferenceJavaImpl.getCached(type.extendsBound as PsiClassType, this)
is PsiPrimitiveType -> KSClassifierReferenceDescriptorImpl.getCached(type.toKotlinType(), origin, this)
is PsiArrayType -> {
val componentType = ResolverImpl.instance.resolveJavaType(type.componentType, this)
val componentType = ResolverImpl.instance!!.resolveJavaType(type.componentType, this)
if (type.componentType !is PsiPrimitiveType) {
KSClassifierReferenceDescriptorImpl.getCached(
ResolverImpl.instance.module.builtIns.getArrayType(Variance.INVARIANT, componentType),
ResolverImpl.instance!!.module.builtIns.getArrayType(Variance.INVARIANT, componentType),
origin,
this
)
} else {
KSClassifierReferenceDescriptorImpl.getCached(
ResolverImpl.instance.module.builtIns
ResolverImpl.instance!!.module.builtIns
.getPrimitiveArrayKotlinTypeByPrimitiveKotlinType(componentType)!!,
origin, this
)
}
}
null ->
KSClassifierReferenceDescriptorImpl.getCached(
(ResolverImpl.instance.builtIns.anyType as KSTypeImpl).kotlinType.makeNullable(), origin, this
(ResolverImpl.instance!!.builtIns.anyType as KSTypeImpl).kotlinType.makeNullable(), origin, this
)
else -> throw IllegalStateException("Unexpected psi type for ${type.javaClass}, $ExceptionMessage")
}
}

override fun resolve(): KSType {
val resolvedType = ResolverImpl.instance.resolveUserType(this)
val resolvedType = ResolverImpl.instance!!.resolveUserType(this)
return if ((resolvedType.declaration as? KSClassDeclarationDescriptorImpl)
?.descriptor is NotFoundClasses.MockClassDescriptor
) {
Expand Down
Expand Up @@ -50,7 +50,7 @@ class KSTypeReferenceLiteJavaImpl private constructor(val psiElement: PsiElement
val psiClass = psiElement.nameReferenceElement!!.resolve() as? PsiClass
psiClass?.let {
(psiElement.containingFile as? PsiJavaFile)?.let {
ResolverImpl.instance.incrementalContext.recordLookup(it, psiClass.qualifiedName!!)
ResolverImpl.instance!!.incrementalContext.recordLookup(it, psiClass.qualifiedName!!)
}
KSClassDeclarationJavaImpl.getCached(psiClass).asStarProjectedType()
} ?: KSErrorType
Expand Down
Expand Up @@ -110,7 +110,7 @@ class KSAnnotationImpl private constructor(val ktAnnotationEntry: KtAnnotationEn
}

private val resolved: AnnotationDescriptor? by lazy {
ResolverImpl.instance.resolveAnnotationEntry(ktAnnotationEntry)
ResolverImpl.instance!!.resolveAnnotationEntry(ktAnnotationEntry)
}

override fun toString(): String {
Expand Down