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

Resolve to FirResolvePhase.TYPES for custom types #2038

Merged
merged 1 commit into from
Aug 20, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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<*, *>) {
}
}
Loading