Skip to content

Commit

Permalink
use psi based type reference to defer type resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
neetopia committed Nov 1, 2023
1 parent 6bf8193 commit e3a44a1
Show file tree
Hide file tree
Showing 22 changed files with 532 additions and 197 deletions.
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) }

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,61 @@
/*
* 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 com.google.devtools.ksp.symbol.Origin
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? = null) =
cache.getOrPut(IdKeyPair(ktUserType, parent)) { KSClassifierReferenceImpl(ktUserType, parent) }
}

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 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()
ktUserType.typeArguments.map { KSTypeArgumentImpl.getCached(it) }
// ktUserType.typeArguments.map { KSTypeArgumentKtImpl.getCached(it) }
}
}

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)
}
}

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 fun toString(): String {
return referencedName()
override val qualifier: KSClassifierReference? by lazy {
if (ktUserType.qualifier == null) {
null
} else {
KSClassifierReferenceImpl.getCached(ktUserType.qualifier!!, parent)
}
}

override fun toString() = referencedName()
}
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)
}

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

0 comments on commit e3a44a1

Please sign in to comment.