Skip to content

Commit

Permalink
Apply the nested java class workaround more
Browse files Browse the repository at this point in the history
The fix in the compiler won't be available before 1.8.20.

The workaround comes from google#1049
  • Loading branch information
ting-yuan committed Oct 17, 2022
1 parent f259b5b commit f160317
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 18 deletions.
Expand Up @@ -65,7 +65,6 @@ import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
import org.jetbrains.kotlin.load.java.structure.classId
import org.jetbrains.kotlin.load.java.structure.impl.JavaArrayTypeImpl
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
Expand Down Expand Up @@ -519,7 +518,9 @@ class ResolverImpl(
// 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 PsiClass -> moduleClassResolver.resolveClass(
JavaClassImpl(psi).apply { workaroundForNested(lazyJavaResolverContext) }
)
is PsiMethod -> {
// TODO: get rid of hardcoded check if possible.
val property = if (psi.name.startsWith("set") || psi.name.startsWith("get")) {
Expand Down Expand Up @@ -547,7 +548,9 @@ class ResolverImpl(
}
is PsiField -> {
moduleClassResolver
.resolveClass(JavaFieldImpl(psi).containingClass)
.resolveClass(
JavaFieldImpl(psi).containingClass.apply { workaroundForNested(lazyJavaResolverContext) }
)
?.findEnclosedDescriptor(
kindFilter = DescriptorKindFilter.VARIABLES,
filter = { it.findPsi() == psi }
Expand Down Expand Up @@ -628,16 +631,6 @@ class ResolverImpl(
}
// Construct resolver context for the PsiType
var resolverContext = lazyJavaResolverContext
// TODO: fix in compiler.
// Temporary work around for https://github.com/google/ksp/issues/1034
// Force resolve outer most class for Java nested classes.
javaType.safeAs<JavaClassifierType>()?.classifier.safeAs<JavaClass>()?.let {
var outerMost = it.outerClass
while (outerMost?.outerClass != null) {
outerMost = outerMost.outerClass
}
outerMost?.classId?.let { lazyJavaResolverContext.components.finder.findClass(it) }
}

for (e in stack) {
when (e) {
Expand Down Expand Up @@ -714,7 +707,9 @@ class ResolverImpl(
}
}
val containingDeclaration = if (psi.owner is PsiClass) {
moduleClassResolver.resolveClass(JavaClassImpl(psi.owner as PsiClass))
moduleClassResolver.resolveClass(
JavaClassImpl(psi.owner as PsiClass).apply { workaroundForNested(lazyJavaResolverContext) }
)
} else {
val owner = psi.owner
check(owner is PsiMethod) {
Expand Down Expand Up @@ -1561,3 +1556,16 @@ internal fun KSTypeReference.resolveToUnderlying(): KSType {
}
return candidate
}

// TODO: Remove this after upgrading to Kotlin 1.8.20.
// Temporary work around for https://github.com/google/ksp/issues/1034
// Force resolve outer most class for Java nested classes.
internal fun JavaClass.workaroundForNested(
lazyJavaResolverContext: LazyJavaResolverContext = ResolverImpl.instance!!.lazyJavaResolverContext
) {
var outerMost = outerClass
while (outerMost?.outerClass != null) {
outerMost = outerMost.outerClass
}
outerMost?.classId?.let { lazyJavaResolverContext.components.finder.findClass(it) }
}
Expand Up @@ -21,6 +21,7 @@ import com.google.devtools.ksp.KSObjectCache
import com.google.devtools.ksp.isConstructor
import com.google.devtools.ksp.memoized
import com.google.devtools.ksp.processing.impl.ResolverImpl
import com.google.devtools.ksp.processing.impl.workaroundForNested
import com.google.devtools.ksp.symbol.*
import com.google.devtools.ksp.symbol.impl.*
import com.google.devtools.ksp.symbol.impl.binary.getAllFunctions
Expand Down Expand Up @@ -74,7 +75,7 @@ class KSClassDeclarationJavaImpl private constructor(val psi: PsiClass) :

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

// TODO in 1.5 + jvmTarget 15, will we return Java permitted types?
Expand Down
Expand Up @@ -21,6 +21,7 @@ import com.google.devtools.ksp.ExceptionMessage
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.findPsi
import com.google.devtools.ksp.processing.impl.ResolverImpl
import com.google.devtools.ksp.processing.impl.workaroundForNested
import com.google.devtools.ksp.symbol.*
import com.google.devtools.ksp.symbol.Variance
import com.google.devtools.ksp.symbol.impl.binary.KSClassDeclarationDescriptorImpl
Expand Down Expand Up @@ -229,9 +230,9 @@ internal inline fun <reified T : CallableMemberDescriptor> T.findClosestOverride

internal fun ModuleClassResolver.resolveContainingClass(psiMethod: PsiMethod): ClassDescriptor? {
return if (psiMethod.isConstructor) {
resolveClass(JavaConstructorImpl(psiMethod).containingClass)
resolveClass(JavaConstructorImpl(psiMethod).containingClass.apply { workaroundForNested() })
} else {
resolveClass(JavaMethodImpl(psiMethod).containingClass)
resolveClass(JavaMethodImpl(psiMethod).containingClass.apply { workaroundForNested() })
}
}

Expand Down
Expand Up @@ -13,7 +13,10 @@ class ValidateProcessor(val codeGenerator: CodeGenerator, val logger: KSPLogger)

val toValidate = resolver.getSymbolsWithAnnotation("com.example.MyAnnotation")
if (toValidate.firstOrNull() == null || !toValidate.all { it.validate() }) {
logger.error("not ok")
logger.error("$toValidate.validate(): not ok")
}
if ((toValidate as? KSClassDeclaration)?.asStarProjectedType()?.isError == true) {
logger.error("$toValidate.asStarProjectedType(): not ok")
}
return emptyList()
}
Expand Down

0 comments on commit f160317

Please sign in to comment.