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

use psi based type reference to defer type resolution #1506

Merged
merged 2 commits into from
Nov 1, 2023
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 @@ -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
Expand Down Expand Up @@ -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<KSValueArgument> by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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?
Expand All @@ -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!!))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -15,18 +18,18 @@ 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) }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the purpose of deferring and restoring, all type references in sources (be it java or kotlin) need to be implemented by KSTypeReferenceImpl.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, KSCallableReferenceImpl can not take KtFunctionalType for sources, because it is subject to change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KtCallableReference is left as TODO in this PR.


override val functionParameters: List<KSValueParameter>
get() = ktFunctionalType.parameterTypes.map {
KSValueParameterLiteImpl.getCached(it, this@KSCallableReferenceImpl)
}

override val returnType: KSTypeReference
get() = KSTypeReferenceImpl.getCached(ktFunctionalType.returnType)
get() = KSTypeReferenceResolvedImpl.getCached(ktFunctionalType.returnType)

override val typeArguments: List<KSTypeArgument>
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) :
Expand Down Expand Up @@ -62,9 +66,21 @@ class KSClassDeclarationImpl private constructor(internal val ktClassOrObjectSym
}

override val superTypes: Sequence<KSTypeReference> by lazy {
analyze {
(ktClassOrObjectSymbol.psiIfSource() as? KtClassOrObject)?.let {
if (classKind == ClassKind.ANNOTATION_CLASS || classKind == ClassKind.ENUM_CLASS) {
null
} else {
it.superTypeListEntries.map {
KSTypeReferenceImpl.getCached(it.typeReference!!, this)
}.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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,77 +1,64 @@
/*
* 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.symbol.KSClassifierReference
import com.google.devtools.ksp.symbol.KSNode
import com.google.devtools.ksp.symbol.KSTypeArgument
import com.google.devtools.ksp.symbol.Location
import org.jetbrains.kotlin.psi.KtUserType

class KSClassifierReferenceImpl private constructor(
internal val ktType: KtClassType,
internal val index: Int,
override val parent: KSTypeReference?
val ktUserType: KtUserType,
override val parent: KSNode
) : KSClassifierReference {
companion object : KSObjectCache<IdKeyTriple<KtClassType, Int, KSTypeReference?>, KSClassifierReferenceImpl>() {
fun getCached(ktType: KtClassType, index: Int, parent: KSTypeReference?) =
cache.getOrPut(IdKeyTriple(ktType, index, parent)) { KSClassifierReferenceImpl(ktType, index, parent) }
companion object : KSObjectCache<IdKeyPair<KtUserType, KSNode?>, KSClassifierReferenceImpl>() {
fun getCached(ktUserType: KtUserType, parent: KSNode) =
cache.getOrPut(IdKeyPair(ktUserType, parent)) { KSClassifierReferenceImpl(ktUserType, parent) }
}

private val classifierReference: KtClassTypeQualifier
get() = ktType.qualifiers[index]
override val origin = parent.origin

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 location: Location by lazy {
ktUserType.toLocation()
}

override val typeArguments: List<KSTypeArgument> by lazy {
classifierReference.typeArguments.map { KSTypeArgumentImpl.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<IdKeyPair<KtTypeParameterType, KSTypeReference?>, KSClassifierParameterImpl>() {
fun getCached(ktType: KtTypeParameterType, parent: KSTypeReference?) =
KSClassifierParameterImpl.cache.getOrPut(IdKeyPair(ktType, parent)) {
KSClassifierParameterImpl(ktType, parent)
}
ktUserType.typeArguments.map { KSTypeArgumentImpl.getCached(it) }
// ktUserType.typeArguments.map { KSTypeArgumentKtImpl.getCached(it) }
}

override val qualifier: KSClassifierReference? = null

override fun referencedName(): String {
return ktType.name.asString()
return ktUserType.referencedName ?: ""
}

override val typeArguments: List<KSTypeArgument>
get() = emptyList()
override val origin: Origin
get() = parent?.origin ?: Origin.SYNTHETIC
override val location: Location
get() = parent?.location ?: NonExistLocation
override val qualifier: KSClassifierReference? by lazy {
if (ktUserType.qualifier == null) {
null
} else {
getCached(ktUserType.qualifier!!, parent)
}
}

override fun toString(): String {
return referencedName()
return ktUserType.referencedName + if (typeArguments.isNotEmpty()) "<${
typeArguments.map { it.toString() }.joinToString(", ")
}>" else ""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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, this@KSFunctionDeclarationImpl) }
?: 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, this) }
?: 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<KSValueParameter> by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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(
Expand Down Expand Up @@ -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, this) }
?: KSTypeReferenceResolvedImpl.getCached(getter.returnType, this@KSPropertyGetterImpl)
}

override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand All @@ -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,
Expand Down Expand Up @@ -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, this) }
?: 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, this) }
?: KSTypeReferenceResolvedImpl.getCached(ktPropertySymbol.returnType, this@KSPropertyDeclarationImpl)
}

override val isMutable: Boolean by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
neetopia marked this conversation as resolved.
Show resolved Hide resolved
}

override val isMutable: Boolean
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -28,7 +30,9 @@ 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, this) }
?: KSTypeReferenceResolvedImpl.getCached(ktLocalVariableSymbol.returnType, this)
}

override val isMutable: Boolean = !ktLocalVariableSymbol.isVal
Expand Down
Loading
Loading