From 3c1efde3634a6c40fecf6b9e0602beb836c4a6d7 Mon Sep 17 00:00:00 2001 From: Jiaxiang Chen Date: Thu, 24 Aug 2023 14:10:11 -0700 Subject: [PATCH] use psi based type reference to defer type resolution --- .../impl/symbol/java/KSAnnotationJavaImpl.kt | 5 +- .../impl/symbol/kotlin/KSAnnotationImpl.kt | 4 +- .../symbol/kotlin/KSCallableReferenceImpl.kt | 9 +- .../symbol/kotlin/KSClassDeclarationImpl.kt | 14 +- .../kotlin/KSClassifierReferenceImpl.kt | 101 ++++++-------- .../kotlin/KSFunctionDeclarationImpl.kt | 26 ++-- .../symbol/kotlin/KSPropertyAccessorImpl.kt | 6 +- .../kotlin/KSPropertyDeclarationImpl.kt | 10 +- .../kotlin/KSPropertyDeclarationJavaImpl.kt | 3 +- .../KSPropertyDeclarationLocalVariableImpl.kt | 5 +- .../ksp/impl/symbol/kotlin/KSTypeAliasImpl.kt | 3 +- .../impl/symbol/kotlin/KSTypeArgumentImpl.kt | 75 +++++------ .../ksp/impl/symbol/kotlin/KSTypeImpl.kt | 6 +- .../impl/symbol/kotlin/KSTypeParameterImpl.kt | 23 +++- .../impl/symbol/kotlin/KSTypeReferenceImpl.kt | 123 +++++++++--------- .../symbol/kotlin/KSValueParameterImpl.kt | 4 +- .../symbol/kotlin/KSValueParameterLiteImpl.kt | 3 +- .../KSClassifierReferenceResolvedImpl.kt | 80 ++++++++++++ .../resolved/KSTypeArgumentResolvedImpl.kt | 84 ++++++++++++ .../resolved/KSTypeReferenceResolvedImpl.kt | 122 +++++++++++++++++ .../devtools/ksp/impl/symbol/kotlin/util.kt | 12 +- .../testData/typeParameterReference.kt | 3 - 22 files changed, 523 insertions(+), 198 deletions(-) create mode 100644 kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSClassifierReferenceResolvedImpl.kt create mode 100644 kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeArgumentResolvedImpl.kt create mode 100644 kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeReferenceResolvedImpl.kt diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSAnnotationJavaImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSAnnotationJavaImpl.kt index 447d585326..ca73501915 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSAnnotationJavaImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSAnnotationJavaImpl.kt @@ -4,11 +4,11 @@ import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.getClassDeclarationByName import com.google.devtools.ksp.impl.ResolverAAImpl import com.google.devtools.ksp.impl.symbol.kotlin.KSErrorType -import com.google.devtools.ksp.impl.symbol.kotlin.KSTypeReferenceImpl import com.google.devtools.ksp.impl.symbol.kotlin.KSValueArgumentImpl import com.google.devtools.ksp.impl.symbol.kotlin.analyze import com.google.devtools.ksp.impl.symbol.kotlin.classifierSymbol import com.google.devtools.ksp.impl.symbol.kotlin.getDefaultValue +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.impl.symbol.kotlin.toLocation import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.AnnotationUseSiteTarget @@ -59,7 +59,8 @@ class KSAnnotationJavaImpl private constructor(private val psi: PsiAnnotation, o } override val annotationType: KSTypeReference by lazy { - KSTypeReferenceImpl.getCached(type, this) + // TODO: repleace with psi based implementation once `PsiType -> KtType` is supported in AA. + KSTypeReferenceResolvedImpl.getCached(type, this) } override val arguments: List by lazy { diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt index a0e82ff8ae..b876a1eb9a 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt @@ -21,6 +21,7 @@ import com.google.devtools.ksp.IdKeyPair import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.impl.symbol.java.KSValueArgumentLiteImpl import com.google.devtools.ksp.impl.symbol.java.calcValue +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.* import com.intellij.psi.PsiAnnotationMethod @@ -31,6 +32,7 @@ import org.jetbrains.kotlin.analysis.api.components.buildClassType import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.* +// TODO: implement a psi based version of annotation application. class KSAnnotationImpl private constructor( private val annotationApplication: KtAnnotationApplicationWithArgumentsInfo, override val parent: KSNode? @@ -42,7 +44,7 @@ class KSAnnotationImpl private constructor( override val annotationType: KSTypeReference by lazy { analyze { - KSTypeReferenceImpl.getCached(buildClassType(annotationApplication.classId!!)) + KSTypeReferenceResolvedImpl.getCached(buildClassType(annotationApplication.classId!!)) } } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSCallableReferenceImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSCallableReferenceImpl.kt index 606d84a521..379390b53f 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSCallableReferenceImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSCallableReferenceImpl.kt @@ -2,10 +2,13 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.IdKeyPair import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeArgumentResolvedImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType import org.jetbrains.kotlin.analysis.api.types.KtType +// TODO: implement a psi based version, rename this class to resolved Impl. class KSCallableReferenceImpl private constructor( private val ktFunctionalType: KtFunctionalType, override val parent: KSNode? @@ -15,7 +18,7 @@ class KSCallableReferenceImpl private constructor( cache.getOrPut(IdKeyPair(ktFunctionalType, parent)) { KSCallableReferenceImpl(ktFunctionalType, parent) } } override val receiverType: KSTypeReference? - get() = ktFunctionalType.receiverType?.let { KSTypeReferenceImpl.getCached(it) } + get() = ktFunctionalType.receiverType?.let { KSTypeReferenceResolvedImpl.getCached(it) } override val functionParameters: List get() = ktFunctionalType.parameterTypes.map { @@ -23,10 +26,10 @@ class KSCallableReferenceImpl private constructor( } override val returnType: KSTypeReference - get() = KSTypeReferenceImpl.getCached(ktFunctionalType.returnType) + get() = KSTypeReferenceResolvedImpl.getCached(ktFunctionalType.returnType) override val typeArguments: List - get() = ktFunctionalType.typeArguments().map { KSTypeArgumentImpl.getCached(it, this) } + get() = ktFunctionalType.typeArguments().map { KSTypeArgumentResolvedImpl.getCached(it, this) } override val origin: Origin get() = parent?.origin ?: Origin.SYNTHETIC diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt index 2520061765..f2bb3b8746 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt @@ -18,12 +18,16 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.ResolverAAImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl +import com.google.devtools.ksp.processing.impl.KSTypeReferenceSyntheticImpl import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection import org.jetbrains.kotlin.analysis.api.components.buildClassType import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.descriptors.java.JavaVisibilities +import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtObjectDeclaration class KSClassDeclarationImpl private constructor(internal val ktClassOrObjectSymbol: KtClassOrObjectSymbol) : @@ -62,9 +66,15 @@ class KSClassDeclarationImpl private constructor(internal val ktClassOrObjectSym } override val superTypes: Sequence by lazy { - analyze { + (ktClassOrObjectSymbol.psiIfSource() as? KtClassOrObject)?.superTypeListEntries?.map { + KSTypeReferenceImpl.getCached(it.typeReference!!) + }?.asSequence()?.ifEmpty { + sequenceOf( + KSTypeReferenceSyntheticImpl.getCached(ResolverAAImpl.instance.builtIns.anyType, this) + ) + } ?: analyze { val supers = ktClassOrObjectSymbol.superTypes.mapIndexed { index, type -> - KSTypeReferenceImpl.getCached(type, this@KSClassDeclarationImpl, index) + KSTypeReferenceResolvedImpl.getCached(type, this@KSClassDeclarationImpl, index) } // AA is returning additional kotlin.Any for java classes, explicitly extending kotlin.Any will result in // compile error, therefore filtering by name should work. diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassifierReferenceImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassifierReferenceImpl.kt index e662a13e44..50926001f2 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassifierReferenceImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassifierReferenceImpl.kt @@ -1,77 +1,62 @@ +/* + * Copyright 2023 Google LLC + * Copyright 2010-2023 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.impl.symbol.kotlin -import com.google.devtools.ksp.IdKeyPair -import com.google.devtools.ksp.IdKeyTriple import com.google.devtools.ksp.KSObjectCache -import com.google.devtools.ksp.symbol.* -import org.jetbrains.kotlin.analysis.api.types.KtClassType -import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier -import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType +import com.google.devtools.ksp.findParentOfType +import com.google.devtools.ksp.symbol.KSClassifierReference +import com.google.devtools.ksp.symbol.KSNode +import com.google.devtools.ksp.symbol.KSTypeArgument +import com.google.devtools.ksp.symbol.Location +import com.google.devtools.ksp.symbol.Origin +import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.psi.KtUserType -class KSClassifierReferenceImpl private constructor( - internal val ktType: KtClassType, - internal val index: Int, - override val parent: KSTypeReference? -) : KSClassifierReference { - companion object : KSObjectCache, KSClassifierReferenceImpl>() { - fun getCached(ktType: KtClassType, index: Int, parent: KSTypeReference?) = - cache.getOrPut(IdKeyTriple(ktType, index, parent)) { KSClassifierReferenceImpl(ktType, index, parent) } +class KSClassifierReferenceImpl private constructor(val ktUserType: KtUserType) : KSClassifierReference { + companion object : KSObjectCache() { + fun getCached(ktUserType: KtUserType) = cache.getOrPut(ktUserType) { KSClassifierReferenceImpl(ktUserType) } } - private val classifierReference: KtClassTypeQualifier - get() = ktType.qualifiers[index] + override val origin = Origin.KOTLIN - override val qualifier: KSClassifierReference? by lazy { - if (index == 0) { - null - } else { - getCached(ktType, index - 1, parent) - } + override val location: Location by lazy { + ktUserType.toLocation() } - override fun referencedName(): String { - return classifierReference.name.asString() + override val parent: KSNode? by lazy { + ktUserType.findParentOfType()?.let { KSTypeReferenceImpl.getCached(it) } } override val typeArguments: List by lazy { - classifierReference.typeArguments.map { KSTypeArgumentImpl.getCached(it, this) } + ktUserType.typeArguments.map { KSTypeArgumentImpl.getCached(it) } + // ktUserType.typeArguments.map { KSTypeArgumentKtImpl.getCached(it) } } - override val origin: Origin = parent?.origin ?: Origin.SYNTHETIC - - override val location: Location - get() = parent?.location ?: NonExistLocation - - override fun toString(): String { - return referencedName() - } -} - -class KSClassifierParameterImpl private constructor( - internal val ktType: KtTypeParameterType, - override val parent: KSTypeReference? -) : KSClassifierReference { - companion object : KSObjectCache, KSClassifierParameterImpl>() { - fun getCached(ktType: KtTypeParameterType, parent: KSTypeReference?) = - KSClassifierParameterImpl.cache.getOrPut(IdKeyPair(ktType, parent)) { - KSClassifierParameterImpl(ktType, parent) - } - } - - override val qualifier: KSClassifierReference? = null - override fun referencedName(): String { - return ktType.name.asString() + return ktUserType.referencedName ?: "" } - override val typeArguments: List - get() = emptyList() - override val origin: Origin - get() = parent?.origin ?: Origin.SYNTHETIC - override val location: Location - get() = parent?.location ?: NonExistLocation - - override fun toString(): String { - return referencedName() + override val qualifier: KSClassifierReference? by lazy { + if (ktUserType.qualifier == null) { + null + } else { + KSClassifierReferenceImpl.getCached(ktUserType.qualifier!!) + } } + + override fun toString() = referencedName() } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt index a6180a0f3d..788bdcf277 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt @@ -20,6 +20,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.* import com.google.devtools.ksp.impl.ResolverAAImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.* import com.intellij.psi.PsiClass @@ -73,22 +74,25 @@ class KSFunctionDeclarationImpl private constructor(internal val ktFunctionSymbo if (!ktFunctionSymbol.isExtension) { null } else { - ktFunctionSymbol.receiverType?.let { - KSTypeReferenceImpl.getCached(it, this@KSFunctionDeclarationImpl) - } + (ktFunctionSymbol.psiIfSource() as? KtFunction)?.receiverTypeReference + ?.let { KSTypeReferenceImpl.getCached(it) } + ?: ktFunctionSymbol.receiverType?.let { + KSTypeReferenceResolvedImpl.getCached(it, this@KSFunctionDeclarationImpl) + } } } } override val returnType: KSTypeReference? by lazy { - analyze { - // Constructors - if (ktFunctionSymbol is KtConstructorSymbol) { - ((parentDeclaration as KSClassDeclaration).asStarProjectedType() as KSTypeImpl).type - } else { - ktFunctionSymbol.returnType - }.let { KSTypeReferenceImpl.getCached(it, this@KSFunctionDeclarationImpl) } - } + (ktFunctionSymbol.psiIfSource() as? KtFunction)?.typeReference?.let { KSTypeReferenceImpl.getCached(it) } + ?: analyze { + // Constructors + if (ktFunctionSymbol is KtConstructorSymbol) { + ((parentDeclaration as KSClassDeclaration).asStarProjectedType() as KSTypeImpl).type + } else { + ktFunctionSymbol.returnType + }.let { KSTypeReferenceResolvedImpl.getCached(it, this@KSFunctionDeclarationImpl) } + } } override val parameters: List by lazy { diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyAccessorImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyAccessorImpl.kt index fb5863c85b..b0fd7d7ba7 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyAccessorImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyAccessorImpl.kt @@ -18,6 +18,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.impl.symbol.util.toKSModifiers import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.annotations.annotations @@ -27,6 +28,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySetterSymbol import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtModifierListOwner +import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtPropertyAccessor abstract class KSPropertyAccessorImpl( @@ -125,7 +127,9 @@ class KSPropertyGetterImpl private constructor( } override val returnType: KSTypeReference? by lazy { - KSTypeReferenceImpl.getCached(getter.returnType, this@KSPropertyGetterImpl) + ((owner as? KSPropertyDeclarationImpl)?.ktPropertySymbol?.psiIfSource() as? KtProperty)?.typeReference + ?.let { KSTypeReferenceImpl.getCached(it) } + ?: KSTypeReferenceResolvedImpl.getCached(getter.returnType, this@KSPropertyGetterImpl) } override fun accept(visitor: KSVisitor, data: D): R { diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt index 22c4e9ee8e..9507c8f1a1 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationImpl.kt @@ -19,6 +19,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.impl.ResolverAAImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.impl.symbol.util.BinaryClassInfoCache import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.* @@ -32,6 +33,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.java.JavaVisibilities import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl +import org.jetbrains.kotlin.psi.KtProperty class KSPropertyDeclarationImpl private constructor(internal val ktPropertySymbol: KtPropertySymbol) : KSPropertyDeclaration, @@ -85,11 +87,15 @@ class KSPropertyDeclarationImpl private constructor(internal val ktPropertySymbo } override val extensionReceiver: KSTypeReference? by lazy { - ktPropertySymbol.receiverType?.let { KSTypeReferenceImpl.getCached(it, this@KSPropertyDeclarationImpl) } + (ktPropertySymbol.psiIfSource() as? KtProperty)?.receiverTypeReference + ?.let { KSTypeReferenceImpl.getCached(it) } + ?: ktPropertySymbol.receiverType + ?.let { KSTypeReferenceResolvedImpl.getCached(it, this@KSPropertyDeclarationImpl) } } override val type: KSTypeReference by lazy { - KSTypeReferenceImpl.getCached(ktPropertySymbol.returnType, this@KSPropertyDeclarationImpl) + (ktPropertySymbol.psiIfSource() as? KtProperty)?.typeReference?.let { KSTypeReferenceImpl.getCached(it) } + ?: KSTypeReferenceResolvedImpl.getCached(ktPropertySymbol.returnType, this@KSPropertyDeclarationImpl) } override val isMutable: Boolean by lazy { diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationJavaImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationJavaImpl.kt index f035f468a9..b4ac9a4f1a 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationJavaImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationJavaImpl.kt @@ -3,6 +3,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.impl.ResolverAAImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.symbols.KtJavaFieldSymbol @@ -27,7 +28,7 @@ class KSPropertyDeclarationJavaImpl private constructor(private val ktJavaFieldS get() = null override val type: KSTypeReference by lazy { - KSTypeReferenceImpl.getCached(ktJavaFieldSymbol.returnType, this@KSPropertyDeclarationJavaImpl) + KSTypeReferenceResolvedImpl.getCached(ktJavaFieldSymbol.returnType, this@KSPropertyDeclarationJavaImpl) } override val isMutable: Boolean diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationLocalVariableImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationLocalVariableImpl.kt index d4f1e7ca3f..6781cb522f 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationLocalVariableImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSPropertyDeclarationLocalVariableImpl.kt @@ -1,6 +1,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.symbol.KSExpectActual import com.google.devtools.ksp.symbol.KSName import com.google.devtools.ksp.symbol.KSPropertyDeclaration @@ -10,6 +11,7 @@ import com.google.devtools.ksp.symbol.KSType import com.google.devtools.ksp.symbol.KSTypeReference import com.google.devtools.ksp.symbol.KSVisitor import org.jetbrains.kotlin.analysis.api.symbols.KtLocalVariableSymbol +import org.jetbrains.kotlin.psi.KtProperty class KSPropertyDeclarationLocalVariableImpl private constructor( private val ktLocalVariableSymbol: KtLocalVariableSymbol @@ -28,7 +30,8 @@ class KSPropertyDeclarationLocalVariableImpl private constructor( override val extensionReceiver: KSTypeReference? = null override val type: KSTypeReference by lazy { - KSTypeReferenceImpl.getCached(ktLocalVariableSymbol.returnType) + (ktLocalVariableSymbol.psiIfSource() as? KtProperty)?.typeReference?.let { KSTypeReferenceImpl.getCached(it) } + ?: KSTypeReferenceResolvedImpl.getCached(ktLocalVariableSymbol.returnType) } override val isMutable: Boolean = !ktLocalVariableSymbol.isVal diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeAliasImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeAliasImpl.kt index 2ac5430079..1b1d8a2cb9 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeAliasImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeAliasImpl.kt @@ -17,6 +17,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.KSExpectActual import com.google.devtools.ksp.symbol.KSName @@ -40,7 +41,7 @@ class KSTypeAliasImpl private constructor(private val ktTypeAliasSymbol: KtTypeA } override val type: KSTypeReference by lazy { - KSTypeReferenceImpl.getCached(ktTypeAliasSymbol.expandedType, this) + KSTypeReferenceResolvedImpl.getCached(ktTypeAliasSymbol.expandedType, this) } override val simpleName: KSName diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeArgumentImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeArgumentImpl.kt index 67c890b9fe..7ebbd970c8 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeArgumentImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeArgumentImpl.kt @@ -1,6 +1,6 @@ /* - * Copyright 2022 Google LLC - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2023 Google LLC + * Copyright 2010-2023 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. @@ -14,11 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.google.devtools.ksp.impl.symbol.kotlin -import com.google.devtools.ksp.IdKeyPair import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.findParentOfType import com.google.devtools.ksp.symbol.KSAnnotation import com.google.devtools.ksp.symbol.KSNode import com.google.devtools.ksp.symbol.KSTypeArgument @@ -27,55 +26,51 @@ import com.google.devtools.ksp.symbol.KSVisitor import com.google.devtools.ksp.symbol.Location import com.google.devtools.ksp.symbol.Origin import com.google.devtools.ksp.symbol.Variance -import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection -import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance -import org.jetbrains.kotlin.analysis.api.KtTypeProjection - -class KSTypeArgumentImpl private constructor( - private val ktTypeProjection: KtTypeProjection, - override val parent: KSNode? -) : KSTypeArgument, Deferrable { - companion object : KSObjectCache, KSTypeArgumentImpl>() { - fun getCached(ktTypeProjection: KtTypeProjection, parent: KSNode? = null) = - cache.getOrPut(IdKeyPair(ktTypeProjection, parent)) { KSTypeArgumentImpl(ktTypeProjection, parent) } - } +import org.jetbrains.kotlin.psi.KtProjectionKind +import org.jetbrains.kotlin.psi.KtTypeProjection +import org.jetbrains.kotlin.psi.KtUserType - override val variance: Variance by lazy { - when (ktTypeProjection) { - is KtStarTypeProjection -> Variance.STAR - is KtTypeArgumentWithVariance -> { - when (ktTypeProjection.variance) { - org.jetbrains.kotlin.types.Variance.INVARIANT -> Variance.INVARIANT - org.jetbrains.kotlin.types.Variance.IN_VARIANCE -> Variance.CONTRAVARIANT - org.jetbrains.kotlin.types.Variance.OUT_VARIANCE -> Variance.COVARIANT - else -> throw IllegalStateException("Unexpected variance") - } - } +class KSTypeArgumentImpl(private val ktTypeArgument: KtTypeProjection) : KSTypeArgument { + companion object : KSObjectCache() { + fun getCached(ktTypeArgument: KtTypeProjection) = cache.getOrPut(ktTypeArgument) { + KSTypeArgumentImpl(ktTypeArgument) } } - override val type: KSTypeReference? by lazy { - ktTypeProjection.type?.let { KSTypeReferenceImpl.getCached(it, this@KSTypeArgumentImpl) } - } + override val origin = Origin.KOTLIN - override val annotations: Sequence by lazy { - ktTypeProjection.type?.annotations(this) ?: emptySequence() + override val location: Location by lazy { + ktTypeArgument.toLocation() } - override val origin: Origin = parent?.origin ?: Origin.SYNTHETIC - - override val location: Location - get() = TODO("Not yet implemented") + override val parent: KSNode? by lazy { + ktTypeArgument.findParentOfType()?.let { KSClassifierReferenceImpl.getCached(it) } + } override fun accept(visitor: KSVisitor, data: D): R { return visitor.visitTypeArgument(this, data) } - override fun toString(): String { - return "$variance $type" + override val variance: Variance by lazy { + when (ktTypeArgument.projectionKind) { + KtProjectionKind.STAR -> Variance.STAR + KtProjectionKind.IN -> Variance.CONTRAVARIANT + KtProjectionKind.NONE -> Variance.INVARIANT + KtProjectionKind.OUT -> Variance.COVARIANT + } } - override fun defer(): Restorable? { - TODO("Not yet implemented") + override val type: KSTypeReference? by lazy { + if (ktTypeArgument.typeReference != null) { + KSTypeReferenceImpl.getCached(ktTypeArgument.typeReference!!) + } else { + null + } + } + override val annotations: Sequence + get() = emptySequence() + + override fun toString(): String { + return "$variance $type" } } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt index 9b2c817e6a..9620f614c5 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt @@ -20,6 +20,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.IdKeyPair import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.impl.ResolverAAImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeArgumentResolvedImpl import com.google.devtools.ksp.impl.symbol.kotlin.synthetic.getExtensionFunctionTypeAnnotation import com.google.devtools.ksp.symbol.KSAnnotation import com.google.devtools.ksp.symbol.KSDeclaration @@ -76,9 +77,10 @@ class KSTypeImpl private constructor(internal val type: KtType) : KSType { emptyList() } else { if (type is KtFlexibleType) { - type.upperBound.typeArguments().map { KSTypeArgumentImpl.getCached(it) } + type.upperBound.typeArguments().map { KSTypeArgumentResolvedImpl.getCached(it) } } else { - (type as? KtNonErrorClassType)?.typeArguments()?.map { KSTypeArgumentImpl.getCached(it) } ?: emptyList() + (type as? KtNonErrorClassType)?.typeArguments()?.map { KSTypeArgumentResolvedImpl.getCached(it) } + ?: emptyList() } } } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeParameterImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeParameterImpl.kt index 6cc39df17c..ca09b2b305 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeParameterImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeParameterImpl.kt @@ -19,10 +19,13 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.impl.ResolverAAImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.processing.impl.KSTypeReferenceSyntheticImpl import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol +import org.jetbrains.kotlin.psi.KtTypeParameter +import org.jetbrains.kotlin.psi.KtTypeParameterListOwner class KSTypeParameterImpl private constructor(internal val ktTypeParameterSymbol: KtTypeParameterSymbol) : KSTypeParameter, @@ -48,8 +51,24 @@ class KSTypeParameterImpl private constructor(internal val ktTypeParameterSymbol override val isReified: Boolean = ktTypeParameterSymbol.isReified override val bounds: Sequence by lazy { - ktTypeParameterSymbol.upperBounds.asSequence().mapIndexed { index, type -> - KSTypeReferenceImpl.getCached(type, this@KSTypeParameterImpl, index) + when (val psi = ktTypeParameterSymbol.psi) { + is KtTypeParameter -> { + val owner = (parentDeclaration as AbstractKSDeclarationImpl) + .ktDeclarationSymbol.psi as KtTypeParameterListOwner + val list = sequenceOf(psi.extendsBound) + list.plus( + owner.typeConstraints + .filter { + it.subjectTypeParameterName!!.getReferencedName() == psi.nameAsSafeName.asString() + } + .map { it.boundTypeReference } + ).filterNotNull().map { KSTypeReferenceImpl.getCached(it) } + } + else -> { + ktTypeParameterSymbol.upperBounds.asSequence().mapIndexed { index, type -> + KSTypeReferenceResolvedImpl.getCached(type, this@KSTypeParameterImpl, index) + } + } }.ifEmpty { sequenceOf( KSTypeReferenceSyntheticImpl.getCached(ResolverAAImpl.instance.builtIns.anyType.makeNullable(), this) diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeReferenceImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeReferenceImpl.kt index 73049c255d..d61e9021a2 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeReferenceImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeReferenceImpl.kt @@ -1,6 +1,6 @@ /* - * Copyright 2022 Google LLC - * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2023 Google LLC + * Copyright 2010-2023 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. @@ -14,97 +14,90 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.google.devtools.ksp.impl.symbol.kotlin -import com.google.devtools.ksp.IdKeyTriple +import com.google.devtools.ksp.ExceptionMessage import com.google.devtools.ksp.KSObjectCache -import com.google.devtools.ksp.symbol.* -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiTypeParameter -import com.intellij.psi.impl.source.PsiClassReferenceType -import org.jetbrains.kotlin.analysis.api.types.* -import org.jetbrains.kotlin.psi.KtClassOrObject -import org.jetbrains.kotlin.psi.KtTypeParameter +import com.google.devtools.ksp.impl.symbol.util.toKSModifiers +import com.google.devtools.ksp.symbol.KSAnnotation +import com.google.devtools.ksp.symbol.KSNode +import com.google.devtools.ksp.symbol.KSReferenceElement +import com.google.devtools.ksp.symbol.KSType +import com.google.devtools.ksp.symbol.KSTypeReference +import com.google.devtools.ksp.symbol.KSVisitor +import com.google.devtools.ksp.symbol.Location +import com.google.devtools.ksp.symbol.Modifier +import com.google.devtools.ksp.symbol.Origin +import org.jetbrains.kotlin.analysis.api.annotations.annotations +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.psi.KtNullableType +import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.psi.KtUserType -class KSTypeReferenceImpl private constructor( - private val ktType: KtType, - override val parent: KSNode?, - private val index: Int -) : KSTypeReference, Deferrable { - companion object : KSObjectCache, KSTypeReference>() { - fun getCached(type: KtType, parent: KSNode? = null, index: Int = -1): KSTypeReference = - cache.getOrPut(IdKeyTriple(type, parent, index)) { KSTypeReferenceImpl(type, parent, index) } +class KSTypeReferenceImpl(private val ktTypeReference: KtTypeReference) : KSTypeReference { + companion object : KSObjectCache() { + fun getCached(ktTypeReference: KtTypeReference): KSTypeReference { + return cache.getOrPut(ktTypeReference) { + KSTypeReferenceImpl(ktTypeReference) + } + } } + private val ktType: KtType by lazy { + analyze { ktTypeReference.getKtType() } + } override val element: KSReferenceElement? by lazy { - if (parent == null || parent.origin == Origin.SYNTHETIC) { - null - } else { - ktType.toClassifierReference(this) + var typeElement = ktTypeReference.typeElement + while (typeElement is KtNullableType) + typeElement = typeElement.innerType + when (typeElement) { + // is KtFunctionType -> KSCallableReferenceImpl.getCached(typeElement) + is KtUserType -> KSClassifierReferenceImpl.getCached(typeElement) + // is KtDynamicType -> KSDynamicReferenceImpl.getCached(this) + // is KtIntersectionType -> KSDefNonNullReferenceImpl.getCached(typeElement) + else -> throw IllegalStateException("Unexpected type element ${typeElement?.javaClass}, $ExceptionMessage") } } override fun resolve(): KSType { - // TODO: non exist type returns KtNonErrorClassType, check upstream for KtClassErrorType usage. - return if ( - analyze { - ktType is KtClassErrorType || (ktType.classifierSymbol() == null) - } - ) { - KSErrorType - } else { - KSTypeImpl.getCached(ktType) - } + return KSTypeImpl.getCached(ktType) } override val annotations: Sequence by lazy { - ktType.annotations(this) + ktType.annotations.map { KSAnnotationImpl.getCached(it) }.asSequence() } - override val origin: Origin = parent?.origin ?: Origin.SYNTHETIC + override val origin: Origin = Origin.KOTLIN override val location: Location by lazy { - if (index != -1) { - parent?.location ?: NonExistLocation - } else { - when (parent) { - is KSClassDeclarationImpl -> { - when (val psi = parent.ktClassOrObjectSymbol.psi) { - is KtClassOrObject -> psi.superTypeListEntries.get(index).toLocation() - is PsiClass -> (psi as? PsiClassReferenceType)?.reference?.toLocation() ?: NonExistLocation - else -> NonExistLocation - } - } - is KSTypeParameterImpl -> { - when (val psi = parent.ktTypeParameterSymbol.psi) { - is KtTypeParameter -> parent.location - is PsiTypeParameter -> (psi.extendsListTypes[index] as? PsiClassReferenceType) - ?.reference?.toLocation() ?: NonExistLocation - else -> NonExistLocation - } - } - else -> NonExistLocation - } - } + ktTypeReference.toLocation() + } + + override val parent: KSNode? by lazy { + null } override fun accept(visitor: KSVisitor, data: D): R { return visitor.visitTypeReference(this, data) } - override val modifiers: Set - get() = if (ktType is KtFunctionalType && ktType.isSuspend) { - setOf(Modifier.SUSPEND) - } else { - emptySet() + override val modifiers: Set by lazy { + val innerModifiers = mutableSetOf() + visitNullableType { + innerModifiers.addAll(it.modifierList.toKSModifiers()) } + innerModifiers + ktTypeReference.toKSModifiers() + } override fun toString(): String { - return ktType.render() + return element.toString() } - override fun defer(): Restorable? { - TODO("Not yet implemented") + private fun visitNullableType(visit: (KtNullableType) -> Unit) { + var typeElement = ktTypeReference.typeElement + while (typeElement is KtNullableType) { + visit(typeElement) + typeElement = typeElement.innerType + } } } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt index f725dc7f71..9a4ee9891d 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterImpl.kt @@ -19,6 +19,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirValueParameterSymbol @@ -56,7 +57,8 @@ class KSValueParameterImpl private constructor( it.returnTypeRef.resolveIfJavaType(it.moduleData.session, JavaTypeParameterStack.EMPTY) } } - KSTypeReferenceImpl.getCached(ktValueParameterSymbol.returnType, this@KSValueParameterImpl) + (ktValueParameterSymbol.psiIfSource() as? KtParameter)?.typeReference?.let { KSTypeReferenceImpl.getCached(it) } + ?: KSTypeReferenceResolvedImpl.getCached(ktValueParameterSymbol.returnType, this@KSValueParameterImpl) } override val isVararg: Boolean by lazy { diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterLiteImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterLiteImpl.kt index 615dc277f6..356e27b862 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterLiteImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueParameterLiteImpl.kt @@ -2,6 +2,7 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.IdKeyPair import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSTypeReferenceResolvedImpl import com.google.devtools.ksp.processing.impl.KSNameImpl import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.types.KtType @@ -17,7 +18,7 @@ class KSValueParameterLiteImpl private constructor(private val ktType: KtType, o // preferably maybe use empty name to match compiler, but use underscore to match FE1.0 implementation. override val name: KSName = KSNameImpl.getCached("_") - override val type: KSTypeReference = KSTypeReferenceImpl.getCached(ktType) + override val type: KSTypeReference = KSTypeReferenceResolvedImpl.getCached(ktType) override val isVararg: Boolean = false diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSClassifierReferenceResolvedImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSClassifierReferenceResolvedImpl.kt new file mode 100644 index 0000000000..4d2905fc00 --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSClassifierReferenceResolvedImpl.kt @@ -0,0 +1,80 @@ +package com.google.devtools.ksp.impl.symbol.kotlin.resolved + +import com.google.devtools.ksp.IdKeyPair +import com.google.devtools.ksp.IdKeyTriple +import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.symbol.* +import org.jetbrains.kotlin.analysis.api.types.KtClassType +import org.jetbrains.kotlin.analysis.api.types.KtClassTypeQualifier +import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType + +class KSClassifierReferenceResolvedImpl private constructor( + internal val ktType: KtClassType, + internal val index: Int, + override val parent: KSTypeReference? +) : KSClassifierReference { + companion object : + KSObjectCache, KSClassifierReferenceResolvedImpl>() { + fun getCached(ktType: KtClassType, index: Int, parent: KSTypeReference?) = + cache.getOrPut(IdKeyTriple(ktType, index, parent)) { + KSClassifierReferenceResolvedImpl(ktType, index, parent) + } + } + + private val classifierReference: KtClassTypeQualifier + get() = ktType.qualifiers[index] + + override val qualifier: KSClassifierReference? by lazy { + if (index == 0) { + null + } else { + getCached(ktType, index - 1, parent) + } + } + + override fun referencedName(): String { + return classifierReference.name.asString() + } + + override val typeArguments: List by lazy { + classifierReference.typeArguments.map { KSTypeArgumentResolvedImpl.getCached(it, this) } + } + + override val origin: Origin = parent?.origin ?: Origin.SYNTHETIC + + override val location: Location + get() = parent?.location ?: NonExistLocation + + override fun toString(): String { + return referencedName() + } +} + +class KSClassifierParameterImpl private constructor( + internal val ktType: KtTypeParameterType, + override val parent: KSTypeReference? +) : KSClassifierReference { + companion object : KSObjectCache, KSClassifierParameterImpl>() { + fun getCached(ktType: KtTypeParameterType, parent: KSTypeReference?) = + KSClassifierParameterImpl.cache.getOrPut(IdKeyPair(ktType, parent)) { + KSClassifierParameterImpl(ktType, parent) + } + } + + override val qualifier: KSClassifierReference? = null + + override fun referencedName(): String { + return ktType.name.asString() + } + + override val typeArguments: List + get() = emptyList() + override val origin: Origin + get() = parent?.origin ?: Origin.SYNTHETIC + override val location: Location + get() = parent?.location ?: NonExistLocation + + override fun toString(): String { + return referencedName() + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeArgumentResolvedImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeArgumentResolvedImpl.kt new file mode 100644 index 0000000000..6c46ca9f4a --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeArgumentResolvedImpl.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 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.impl.symbol.kotlin.resolved + +import com.google.devtools.ksp.IdKeyPair +import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.Deferrable +import com.google.devtools.ksp.impl.symbol.kotlin.Restorable +import com.google.devtools.ksp.impl.symbol.kotlin.annotations +import com.google.devtools.ksp.symbol.KSAnnotation +import com.google.devtools.ksp.symbol.KSNode +import com.google.devtools.ksp.symbol.KSTypeArgument +import com.google.devtools.ksp.symbol.KSTypeReference +import com.google.devtools.ksp.symbol.KSVisitor +import com.google.devtools.ksp.symbol.Location +import com.google.devtools.ksp.symbol.Origin +import com.google.devtools.ksp.symbol.Variance +import org.jetbrains.kotlin.analysis.api.KtStarTypeProjection +import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance +import org.jetbrains.kotlin.analysis.api.KtTypeProjection + +class KSTypeArgumentResolvedImpl private constructor( + private val ktTypeProjection: KtTypeProjection, + override val parent: KSNode? +) : KSTypeArgument, Deferrable { + companion object : KSObjectCache, KSTypeArgumentResolvedImpl>() { + fun getCached(ktTypeProjection: KtTypeProjection, parent: KSNode? = null) = + cache.getOrPut(IdKeyPair(ktTypeProjection, parent)) { KSTypeArgumentResolvedImpl(ktTypeProjection, parent) } + } + + override val variance: Variance by lazy { + when (ktTypeProjection) { + is KtStarTypeProjection -> Variance.STAR + is KtTypeArgumentWithVariance -> { + when (ktTypeProjection.variance) { + org.jetbrains.kotlin.types.Variance.INVARIANT -> Variance.INVARIANT + org.jetbrains.kotlin.types.Variance.IN_VARIANCE -> Variance.CONTRAVARIANT + org.jetbrains.kotlin.types.Variance.OUT_VARIANCE -> Variance.COVARIANT + else -> throw IllegalStateException("Unexpected variance") + } + } + } + } + + override val type: KSTypeReference? by lazy { + ktTypeProjection.type?.let { KSTypeReferenceResolvedImpl.getCached(it, this@KSTypeArgumentResolvedImpl) } + } + + override val annotations: Sequence by lazy { + ktTypeProjection.type?.annotations(this) ?: emptySequence() + } + + override val origin: Origin = parent?.origin ?: Origin.SYNTHETIC + + override val location: Location + get() = TODO("Not yet implemented") + + override fun accept(visitor: KSVisitor, data: D): R { + return visitor.visitTypeArgument(this, data) + } + + override fun toString(): String { + return "$variance $type" + } + + override fun defer(): Restorable? { + TODO("Not yet implemented") + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeReferenceResolvedImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeReferenceResolvedImpl.kt new file mode 100644 index 0000000000..9ee1f32a58 --- /dev/null +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/resolved/KSTypeReferenceResolvedImpl.kt @@ -0,0 +1,122 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2010-2022 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.impl.symbol.kotlin.resolved + +import com.google.devtools.ksp.IdKeyTriple +import com.google.devtools.ksp.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.Deferrable +import com.google.devtools.ksp.impl.symbol.kotlin.KSClassDeclarationImpl +import com.google.devtools.ksp.impl.symbol.kotlin.KSErrorType +import com.google.devtools.ksp.impl.symbol.kotlin.KSTypeImpl +import com.google.devtools.ksp.impl.symbol.kotlin.KSTypeParameterImpl +import com.google.devtools.ksp.impl.symbol.kotlin.Restorable +import com.google.devtools.ksp.impl.symbol.kotlin.analyze +import com.google.devtools.ksp.impl.symbol.kotlin.annotations +import com.google.devtools.ksp.impl.symbol.kotlin.classifierSymbol +import com.google.devtools.ksp.impl.symbol.kotlin.render +import com.google.devtools.ksp.impl.symbol.kotlin.toClassifierReference +import com.google.devtools.ksp.impl.symbol.kotlin.toLocation +import com.google.devtools.ksp.symbol.* +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiTypeParameter +import com.intellij.psi.impl.source.PsiClassReferenceType +import org.jetbrains.kotlin.analysis.api.types.* +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtTypeParameter + +class KSTypeReferenceResolvedImpl private constructor( + private val ktType: KtType, + override val parent: KSNode?, + private val index: Int +) : KSTypeReference, Deferrable { + companion object : KSObjectCache, KSTypeReference>() { + fun getCached(type: KtType, parent: KSNode? = null, index: Int = -1): KSTypeReference = + cache.getOrPut(IdKeyTriple(type, parent, index)) { KSTypeReferenceResolvedImpl(type, parent, index) } + } + + override val element: KSReferenceElement? by lazy { + if (parent == null || parent.origin == Origin.SYNTHETIC) { + null + } else { + ktType.toClassifierReference(this) + } + } + + override fun resolve(): KSType { + // TODO: non exist type returns KtNonErrorClassType, check upstream for KtClassErrorType usage. + return if ( + analyze { + ktType is KtClassErrorType || (ktType.classifierSymbol() == null) + } + ) { + KSErrorType + } else { + KSTypeImpl.getCached(ktType) + } + } + + override val annotations: Sequence by lazy { + ktType.annotations(this) + } + + override val origin: Origin = parent?.origin ?: Origin.SYNTHETIC + + override val location: Location by lazy { + if (index != -1) { + parent?.location ?: NonExistLocation + } else { + when (parent) { + is KSClassDeclarationImpl -> { + when (val psi = parent.ktClassOrObjectSymbol.psi) { + is KtClassOrObject -> psi.superTypeListEntries.get(index).toLocation() + is PsiClass -> (psi as? PsiClassReferenceType)?.reference?.toLocation() ?: NonExistLocation + else -> NonExistLocation + } + } + is KSTypeParameterImpl -> { + when (val psi = parent.ktTypeParameterSymbol.psi) { + is KtTypeParameter -> parent.location + is PsiTypeParameter -> (psi.extendsListTypes[index] as? PsiClassReferenceType) + ?.reference?.toLocation() ?: NonExistLocation + else -> NonExistLocation + } + } + else -> NonExistLocation + } + } + } + + override fun accept(visitor: KSVisitor, data: D): R { + return visitor.visitTypeReference(this, data) + } + + override val modifiers: Set + get() = if (ktType is KtFunctionalType && ktType.isSuspend) { + setOf(Modifier.SUSPEND) + } else { + emptySet() + } + + override fun toString(): String { + return ktType.render() + } + + override fun defer(): Restorable? { + TODO("Not yet implemented") + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt index 6b353f1d3d..2bc42cff54 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt @@ -21,6 +21,8 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.ExceptionMessage import com.google.devtools.ksp.impl.KSPCoreEnvironment import com.google.devtools.ksp.impl.ResolverAAImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSClassifierParameterImpl +import com.google.devtools.ksp.impl.symbol.kotlin.resolved.KSClassifierReferenceResolvedImpl import com.google.devtools.ksp.impl.symbol.util.getDocString import com.google.devtools.ksp.memoized import com.google.devtools.ksp.processing.impl.KSNameImpl @@ -168,7 +170,7 @@ internal fun KtType.toClassifierReference(parent: KSTypeReference?): KSReference return when (val ktType = this) { is KtFunctionalType -> KSCallableReferenceImpl.getCached(ktType, parent) is KtDynamicType -> KSDynamicReferenceImpl.getCached(parent!!) - is KtUsualClassType -> KSClassifierReferenceImpl.getCached(ktType, ktType.qualifiers.size - 1, parent) + is KtUsualClassType -> KSClassifierReferenceResolvedImpl.getCached(ktType, ktType.qualifiers.size - 1, parent) is KtFlexibleType -> ktType.lowerBound.toClassifierReference(parent) is KtErrorType -> null is KtTypeParameterType -> KSClassifierParameterImpl.getCached(ktType, parent) @@ -475,6 +477,14 @@ internal fun fillInDeepSubstitutor(context: KtType, substitutorBuilder: KtSubsti } } +internal fun KtSymbol.psiIfSource(): PsiElement? { + return if (origin == KtSymbolOrigin.SOURCE || origin == KtSymbolOrigin.JAVA && toContainingFile() != null) { + psi + } else { + null + } +} + fun interface Restorable { fun restore(): KSAnnotated? } diff --git a/kotlin-analysis-api/testData/typeParameterReference.kt b/kotlin-analysis-api/testData/typeParameterReference.kt index f8482fdd14..ca3d9585f9 100644 --- a/kotlin-analysis-api/testData/typeParameterReference.kt +++ b/kotlin-analysis-api/testData/typeParameterReference.kt @@ -18,9 +18,6 @@ // WITH_RUNTIME // TEST PROCESSOR: TypeParameterReferenceProcessor // EXPECTED: -// kotlin.Any: false -// kotlin.Any: false -// kotlin.Any: false // kotlin.Int: false // kotlin.Int: false // LibFoo: false