Skip to content

Commit

Permalink
Resolve to FirResolvePhase.TYPES for custom types
Browse files Browse the repository at this point in the history
Some checks in AA require them to be resolved.
  • Loading branch information
ting-yuan committed Aug 20, 2024
1 parent 3ff526d commit 7e2f107
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,12 @@ class KSPCompilerPluginTest : AbstractKSPCompilerPluginTest() {
runTest("../test-utils/testData/api/typeArgumentVariance.kt")
}

@TestMetadata("typeComparison2.kt")
@Test
fun testTypeComparison2() {
runTest("../test-utils/testData/api/typeComparison2.kt")
}

@TestMetadata("typeComposure.kt")
@Test
fun testTypeComposure() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ class KSClassDeclarationImpl private constructor(internal val ktClassOrObjectSym
errorType = ::KSErrorType,
)?.let { error -> return error }
return analyze {
ktClassOrObjectSymbol.tryResolveToTypePhase()
if (typeArguments.isEmpty()) {
// Resolving a class symbol also resolves its type parameters.
typeParameters.map { buildTypeParameterType((it as KSTypeParameterImpl).ktTypeParameterSymbol) }
.let { typeParameterTypes ->
buildClassType(ktClassOrObjectSymbol) {
Expand All @@ -150,7 +152,7 @@ class KSClassDeclarationImpl private constructor(internal val ktClassOrObjectSym
override fun asStarProjectedType(): KSType {
return analyze {
KSTypeImpl.getCached(
useSiteSession.buildClassType(ktClassOrObjectSymbol) {
useSiteSession.buildClassType(ktClassOrObjectSymbol.tryResolveToTypePhase()) {
var current: KSNode? = this@KSClassDeclarationImpl
while (current is KSClassDeclarationImpl) {
current.ktClassOrObjectSymbol.typeParameters.forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@ import com.google.devtools.ksp.symbol.*
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.impl.compiled.ClsMemberImpl
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
import org.jetbrains.kotlin.analysis.api.KaImplementationDetail
import org.jetbrains.kotlin.analysis.api.KaNonPublicApi
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.*
import org.jetbrains.kotlin.analysis.api.annotations.KaAnnotated
import org.jetbrains.kotlin.analysis.api.annotations.KaAnnotation
import org.jetbrains.kotlin.analysis.api.annotations.KaAnnotationValue
import org.jetbrains.kotlin.analysis.api.components.KaSubstitutorBuilder
import org.jetbrains.kotlin.analysis.api.fir.KaSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.evaluate.FirAnnotationValueConverter
import org.jetbrains.kotlin.analysis.api.fir.symbols.KaFirSymbol
import org.jetbrains.kotlin.analysis.api.fir.symbols.KaFirValueParameterSymbol
import org.jetbrains.kotlin.analysis.api.fir.types.KaFirFunctionType
import org.jetbrains.kotlin.analysis.api.fir.types.KaFirType
Expand All @@ -56,6 +55,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.*
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaDeclarationContainerSymbol
import org.jetbrains.kotlin.analysis.api.types.*
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.getTargetType
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.expressions.FirArrayLiteral
Expand All @@ -65,14 +65,8 @@ import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack
import org.jetbrains.kotlin.fir.java.toFirExpression
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType
import org.jetbrains.kotlin.fir.types.abbreviatedType
import org.jetbrains.kotlin.fir.types.classId
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isAny
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationArgument
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
import org.jetbrains.kotlin.load.java.structure.impl.JavaUnknownAnnotationArgumentImpl
Expand All @@ -89,11 +83,7 @@ import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.getEffectiveVariance
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.org.objectweb.asm.ClassVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.*

internal val ktSymbolOriginToOrigin = mapOf(
KaSymbolOrigin.JAVA_SOURCE to Origin.JAVA,
Expand Down Expand Up @@ -703,7 +693,7 @@ internal fun KaType.convertToKotlinType(): KaType {
?: declaration
} else declaration
return analyze {
buildClassType(base) {
buildClassType(base.tryResolveToTypePhase()) {
this@convertToKotlinType.typeArguments().forEach { typeProjection ->
if (typeProjection is KaTypeArgumentWithVariance) {
argument(typeProjection.type.convertToKotlinType(), typeProjection.variance)
Expand Down Expand Up @@ -731,7 +721,7 @@ internal fun KaType.isAssignableFrom(that: KaType): Boolean {
internal fun KaType.replace(newArgs: List<KaTypeProjection>): KaType {
require(newArgs.isEmpty() || newArgs.size == this.typeArguments().size)
return analyze {
when (val symbol = classifierSymbol()) {
when (val symbol = classifierSymbol().tryResolveToTypePhase()) {
is KaClassLikeSymbol -> useSiteSession.buildClassType(symbol) {
newArgs.forEach { arg -> argument(arg) }
nullability = this@replace.nullability
Expand Down Expand Up @@ -784,7 +774,7 @@ internal fun KaType.toWildcard(mode: TypeMappingMode): KtType {
when (this@toWildcard) {
is KaClassType -> {
// TODO: missing annotations from original type.
buildClassType(this@toWildcard.expandedSymbol!!) {
buildClassType(this@toWildcard.expandedSymbol!!.tryResolveToTypePhase()) {
parameters.zip(args).map { (param, arg) ->
val argMode = mode.updateFromAnnotations(arg.type)
val variance = getVarianceForWildcard(param, arg, argMode)
Expand All @@ -802,7 +792,7 @@ internal fun KaType.toWildcard(mode: TypeMappingMode): KtType {
}
}
is KaTypeParameterType -> {
buildTypeParameterType(this@toWildcard.symbol)
buildTypeParameterType(this@toWildcard.symbol.tryResolveToTypePhase())
}
else -> throw IllegalStateException("Unexpected type ${this@toWildcard}")
}
Expand Down Expand Up @@ -879,3 +869,8 @@ internal fun KaFunctionType.abbreviatedSymbol(): KaTypeAliasSymbol? {
val classId = (this as? KaFirFunctionType)?.coneType?.abbreviatedType?.classId ?: return null
return classId.toTypeAlias()
}

fun <T : KaSymbol?> T.tryResolveToTypePhase(): T {
(this as? KaFirSymbol<*>)?.firSymbol?.lazyResolveToPhase(FirResolvePhase.TYPES)
return this
}
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,12 @@ class KSPAATest : AbstractKSPAATest() {
runTest("../test-utils/testData/api/typeComposure.kt")
}

@TestMetadata("typeComparison2.kt")
@Test
fun testTypeComparison2() {
runTest("../test-utils/testData/api/typeComparison2.kt")
}

@TestMetadata("typeParameterReference.kt")
@Test
fun testTypeParameterReference() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2020 Google LLC
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.devtools.ksp.processor

import com.google.devtools.ksp.getClassDeclarationByName
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.*

open class TypeComparison2Processor : AbstractTestProcessor() {
val results = mutableListOf<String>()

override fun process(resolver: Resolver): List<KSAnnotated> {
resolver.getClassDeclarationByName("StyleBuilder")!!.let { cls ->
val typeOne = cls.asType(emptyList())
val typeTwo = cls.asType(emptyList())
results.add("${typeOne == typeTwo}")
}
return emptyList()
}

override fun toResult(): List<String> {
return results
}
}
30 changes: 30 additions & 0 deletions test-utils/testData/api/typeComparison2.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2020 Google LLC
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// WITH_RUNTIME
// TEST PROCESSOR: TypeComparison2Processor
// EXPECTED:
// true
// END

// FILE: A.kt
class StyleApplier<X, Y>
class StyleBuilder<out B : StyleBuilder<B, A>, out A : StyleApplier<*, *>>
class KotlinSubject {
fun subject_1(builder: StyleBuilder<*, *>) {
}
}

0 comments on commit 7e2f107

Please sign in to comment.