Skip to content

Commit

Permalink
Split Origin.CLASS into KOTLIN_LIB and JAVA_LIB
Browse files Browse the repository at this point in the history
For KSAnnotationDescriptor, check whether the underlying descripter is
JavaAnnotationDescriptor.

For KSDeclarationDescriptorImpl, KSPropertyAccessorDescriptorImpl and
KSValueParameterDescriptorImpl, check whether they are contained by
JavaClassDescriptor.

For KSTypeReferenceDescriptorImpl, KSClassifierReferenceDescriptorImpl
and KSTypeArgumentDescriptorImpl, specify the origin in their creation
appropriately. Most of time it is the same as where they are created.
The only exception is when it's created for type arguemnts from
KotlinType.  In that case it is SYNTHETIC.
  • Loading branch information
ting-yuan committed May 11, 2021
1 parent 8589a96 commit fc3abf9
Show file tree
Hide file tree
Showing 27 changed files with 530 additions and 67 deletions.
3 changes: 2 additions & 1 deletion api/src/main/kotlin/com/google/devtools/ksp/symbol/Origin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ package com.google.devtools.ksp.symbol

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


package com.google.devtools.ksp.processor

import com.google.devtools.ksp.*
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSAnnotation
import com.google.devtools.ksp.symbol.KSClassifierReference
import com.google.devtools.ksp.symbol.KSDeclaration
import com.google.devtools.ksp.symbol.KSNode
import com.google.devtools.ksp.symbol.KSPropertyAccessor
import com.google.devtools.ksp.symbol.KSTypeArgument
import com.google.devtools.ksp.symbol.KSTypeReference
import com.google.devtools.ksp.symbol.KSValueParameter
import com.google.devtools.ksp.visitor.KSTopDownVisitor

class LibOriginsProcessor : AbstractTestProcessor() {
private val result = mutableListOf<String>()

override fun toResult(): List<String> {
return result
}

inner class MyCollector : KSTopDownVisitor<Unit, Unit>() {
override fun defaultHandler(node: KSNode, data: Unit) = Unit

override fun visitDeclaration(declaration: KSDeclaration, data: Unit) {
result.add("declaration: ${declaration.qualifiedName?.asString() ?: declaration.simpleName.asString()}: ${declaration.origin.name}")
super.visitDeclaration(declaration, data)
}

override fun visitAnnotation(annotation: KSAnnotation, data: Unit) {
result.add("annotation: ${annotation.shortName.asString()}: ${annotation.origin.name}")
super.visitAnnotation(annotation, data)
}

override fun visitTypeReference(typeReference: KSTypeReference, data: Unit) {
result.add("reference: $typeReference: ${typeReference.origin.name}")
super.visitTypeReference(typeReference, data)
}

override fun visitClassifierReference(reference: KSClassifierReference, data: Unit) {
result.add("classifier ref: $reference: ${reference.origin.name}")
super.visitClassifierReference(reference, data)
}

override fun visitValueParameter(valueParameter: KSValueParameter, data: Unit) {
result.add("value param: $valueParameter: ${valueParameter.origin.name}")
super.visitValueParameter(valueParameter, data)
}

override fun visitTypeArgument(typeArgument: KSTypeArgument, data: Unit) {
result.add("type arg: $typeArgument: ${typeArgument.origin.name}")
super.visitTypeArgument(typeArgument, data)
}

override fun visitPropertyAccessor(accessor: KSPropertyAccessor, data: Unit) {
result.add("property accessor: $accessor: ${accessor.origin.name}")
super.visitPropertyAccessor(accessor, data)
}
}

@KspExperimental
override fun process(resolver: Resolver): List<KSAnnotated> {
val visitor = MyCollector()

// FIXME: workaround for https://github.com/google/ksp/issues/418
resolver.getDeclarationsFromPackage("foo.bar").forEach {
if (it.containingFile == null) {
it.accept(visitor, Unit)
}
}

resolver.getNewFiles().forEach {
it.accept(visitor, Unit)
}

result.sort()
return emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ open class ReferenceElementProcessor: AbstractTestProcessor() {
for (i in sortedReferences)
results.add("KSClassifierReferenceImpl: Qualifier of ${i.element} is ${(i.element as KSClassifierReference).qualifier}")

val descriptorReferences = sortedReferences.map { KSTypeReferenceDescriptorImpl.getCached((it.resolve() as KSTypeImpl).kotlinType) }
val descriptorReferences = sortedReferences.map { KSTypeReferenceDescriptorImpl.getCached((it.resolve() as KSTypeImpl).kotlinType, Origin.SYNTHETIC) }
for (i in descriptorReferences) {
results.add("KSClassifierReferenceDescriptorImpl: Qualifier of ${i.element} is ${(i.element as KSClassifierReference).qualifier}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import com.google.devtools.ksp.symbol.impl.findPsi
import com.google.devtools.ksp.symbol.impl.kotlin.KSNameImpl
import com.google.devtools.ksp.symbol.impl.kotlin.KSValueArgumentLiteImpl
import com.google.devtools.ksp.symbol.impl.kotlin.getKSTypeCached
import org.jetbrains.kotlin.load.java.components.JavaAnnotationDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaAnnotationDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
Expand All @@ -42,12 +44,17 @@ class KSAnnotationDescriptorImpl private constructor(val descriptor: AnnotationD
fun getCached(descriptor: AnnotationDescriptor) = cache.getOrPut(descriptor) { KSAnnotationDescriptorImpl(descriptor) }
}

override val origin = Origin.CLASS
override val origin =
when (descriptor) {
is JavaAnnotationDescriptor, is LazyJavaAnnotationDescriptor -> Origin.JAVA_LIB
else -> Origin.KOTLIN_LIB
}


override val location: Location = NonExistLocation

override val annotationType: KSTypeReference by lazy {
KSTypeReferenceDescriptorImpl.getCached(descriptor.type)
KSTypeReferenceDescriptorImpl.getCached(descriptor.type, origin)
}

override val arguments: List<KSValueArgument> by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ class KSClassDeclarationDescriptorImpl private constructor(val descriptor: Class
override val superTypes: Sequence<KSTypeReference> by lazy {
descriptor.defaultType.constructor.supertypes.asSequence().map {
KSTypeReferenceDescriptorImpl.getCached(
if (it === mockSerializableType) javaSerializableType else it
if (it === mockSerializableType) javaSerializableType else it,
origin
)
}.memoized()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,36 +25,35 @@ import com.google.devtools.ksp.symbol.impl.KSObjectCache
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjection

class KSClassifierReferenceDescriptorImpl private constructor(val descriptor: ClassifierDescriptor, val arguments: List<TypeProjection>) :
class KSClassifierReferenceDescriptorImpl private constructor(val descriptor: ClassifierDescriptor, val arguments: List<TypeProjection>, override val origin: Origin) :
KSClassifierReference {
companion object : KSObjectCache<Pair<ClassifierDescriptor, List<TypeProjection>>, KSClassifierReferenceDescriptorImpl>() {
fun getCached(kotlinType: KotlinType) = cache.getOrPut(
Pair(
companion object : KSObjectCache<Triple<ClassifierDescriptor, List<TypeProjection>, Origin>, KSClassifierReferenceDescriptorImpl>() {
fun getCached(kotlinType: KotlinType, origin: Origin) = cache.getOrPut(
Triple(
kotlinType.constructor.declarationDescriptor!!,
kotlinType.arguments
kotlinType.arguments,
origin
)
) { KSClassifierReferenceDescriptorImpl(kotlinType.constructor.declarationDescriptor!!, kotlinType.arguments) }
) { KSClassifierReferenceDescriptorImpl(kotlinType.constructor.declarationDescriptor!!, kotlinType.arguments, origin) }

fun getCached(descriptor: ClassifierDescriptor, arguments: List<TypeProjection>) =
cache.getOrPut(Pair(descriptor, arguments)) { KSClassifierReferenceDescriptorImpl(descriptor, arguments) }
fun getCached(descriptor: ClassifierDescriptor, arguments: List<TypeProjection>, origin: Origin) =
cache.getOrPut(Triple(descriptor, arguments, origin)) { KSClassifierReferenceDescriptorImpl(descriptor, arguments, origin) }
}

private val nDeclaredArgs by lazy {
(descriptor as? ClassifierDescriptorWithTypeParameters)?.declaredTypeParameters?.size ?: 0
}

override val origin = Origin.CLASS

override val location: Location = NonExistLocation

override val qualifier: KSClassifierReference? by lazy {
val outerDescriptor = descriptor.containingDeclaration as? ClassifierDescriptor ?: return@lazy null
val outerArguments = arguments.drop(nDeclaredArgs)
getCached(outerDescriptor, outerArguments)
getCached(outerDescriptor, outerArguments, origin)
}

override val typeArguments: List<KSTypeArgument> by lazy {
arguments.map { KSTypeArgumentDescriptorImpl.getCached(it) }
arguments.map { KSTypeArgumentDescriptorImpl.getCached(it, origin) }
}

override fun referencedName(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import com.google.devtools.ksp.symbol.*
import com.google.devtools.ksp.symbol.impl.kotlin.KSNameImpl
import com.google.devtools.ksp.symbol.impl.memoized
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull

abstract class KSDeclarationDescriptorImpl(descriptor: DeclarationDescriptor) : KSDeclaration {
abstract class KSDeclarationDescriptorImpl(private val descriptor: DeclarationDescriptor) : KSDeclaration {

override val origin = Origin.CLASS
override val origin by lazy {
descriptor.origin
}

override val containingFile: KSFile? = null

Expand Down Expand Up @@ -66,3 +71,10 @@ abstract class KSDeclarationDescriptorImpl(descriptor: DeclarationDescriptor) :
}

}

val DeclarationDescriptor.origin: Origin
get() = if (parentsWithSelf.firstIsInstanceOrNull<JavaClassDescriptor>() != null) {
Origin.JAVA_LIB
} else {
Origin.KOTLIN_LIB
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class KSFunctionDeclarationDescriptorImpl private constructor(val descriptor: Fu
override val extensionReceiver: KSTypeReference? by lazy {
val extensionReceiver = descriptor.extensionReceiverParameter?.type
if (extensionReceiver != null) {
KSTypeReferenceDescriptorImpl.getCached(extensionReceiver)
KSTypeReferenceDescriptorImpl.getCached(extensionReceiver, origin)
} else {
null
}
Expand Down Expand Up @@ -95,7 +95,7 @@ class KSFunctionDeclarationDescriptorImpl private constructor(val descriptor: Fu
if (returnType == null) {
null
} else {
KSTypeReferenceDescriptorImpl.getCached(returnType)
KSTypeReferenceDescriptorImpl.getCached(returnType, origin)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,19 @@ import com.google.devtools.ksp.symbol.impl.memoized
import com.google.devtools.ksp.symbol.impl.toFunctionKSModifiers
import com.google.devtools.ksp.symbol.impl.toKSModifiers
import com.google.devtools.ksp.symbol.impl.toKSPropertyDeclaration
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull

abstract class KSPropertyAccessorDescriptorImpl(val descriptor: PropertyAccessorDescriptor) : KSPropertyAccessor {
override val origin: Origin
get() = when(receiver.origin) {
override val origin: Origin by lazy {
when (receiver.origin) {
// if receiver is kotlin source, that means we are a synthetic where developer
// didn't declare an explicit accessor so we used the descriptor instead
Origin.KOTLIN -> Origin.SYNTHETIC
else -> Origin.CLASS
else -> descriptor.origin
}
}

override val receiver: KSPropertyDeclaration by lazy {
descriptor.correspondingProperty.toKSPropertyDeclaration()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class KSPropertyDeclarationDescriptorImpl private constructor(val descriptor: Pr

override val extensionReceiver: KSTypeReference? by lazy {
if (descriptor.extensionReceiverParameter != null) {
KSTypeReferenceDescriptorImpl.getCached(descriptor.extensionReceiverParameter!!.type)
KSTypeReferenceDescriptorImpl.getCached(descriptor.extensionReceiverParameter!!.type, origin)
} else {
null
}
Expand Down Expand Up @@ -78,7 +78,7 @@ class KSPropertyDeclarationDescriptorImpl private constructor(val descriptor: Pr
}

override val type: KSTypeReference by lazy {
KSTypeReferenceDescriptorImpl.getCached(descriptor.type)
KSTypeReferenceDescriptorImpl.getCached(descriptor.type, origin)
}

override fun findOverridee(): KSPropertyDeclaration? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class KSPropertyGetterDescriptorImpl private constructor(descriptor: PropertyGet

override val returnType: KSTypeReference? by lazy {
if (descriptor.returnType != null) {
KSTypeReferenceDescriptorImpl.getCached(descriptor.returnType!!)
KSTypeReferenceDescriptorImpl.getCached(descriptor.returnType!!, origin)
} else {
null
}
Expand All @@ -43,4 +43,4 @@ class KSPropertyGetterDescriptorImpl private constructor(descriptor: PropertyGet
override fun toString(): String {
return "$receiver.getter()"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class KSTypeAliasDescriptorImpl(descriptor: TypeAliasDescriptor) : KSTypeAlias,
}

override val type: KSTypeReference by lazy {
KSTypeReferenceDescriptorImpl.getCached(descriptor.underlyingType)
KSTypeReferenceDescriptorImpl.getCached(descriptor.underlyingType, origin)
}

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 @@ -24,17 +24,15 @@ import com.google.devtools.ksp.symbol.impl.kotlin.IdKey
import com.google.devtools.ksp.symbol.impl.kotlin.KSTypeArgumentImpl
import org.jetbrains.kotlin.types.TypeProjection

class KSTypeArgumentDescriptorImpl private constructor(val descriptor: TypeProjection) : KSTypeArgumentImpl() {
companion object : KSObjectCache<IdKey<TypeProjection>, KSTypeArgumentDescriptorImpl>() {
fun getCached(descriptor: TypeProjection) = cache.getOrPut(IdKey(descriptor)) { KSTypeArgumentDescriptorImpl(descriptor) }
class KSTypeArgumentDescriptorImpl private constructor(val descriptor: TypeProjection, override val origin: Origin) : KSTypeArgumentImpl() {
companion object : KSObjectCache<IdKey<Pair<TypeProjection, Origin>>, KSTypeArgumentDescriptorImpl>() {
fun getCached(descriptor: TypeProjection, origin: Origin) = cache.getOrPut(IdKey(Pair(descriptor, origin))) { KSTypeArgumentDescriptorImpl(descriptor, origin) }
}

override val origin = Origin.CLASS

override val location: Location = NonExistLocation

override val type: KSTypeReference by lazy {
KSTypeReferenceDescriptorImpl.getCached(descriptor.type)
KSTypeReferenceDescriptorImpl.getCached(descriptor.type, origin)
}

override val variance: Variance by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class KSTypeParameterDescriptorImpl private constructor(val descriptor: TypePara
}

override val bounds: Sequence<KSTypeReference> by lazy {
descriptor.upperBounds.asSequence().map { KSTypeReferenceDescriptorImpl.getCached(it) }
descriptor.upperBounds.asSequence().map { KSTypeReferenceDescriptorImpl.getCached(it, origin) }
}

override val typeParameters: List<KSTypeParameter> = emptyList()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,15 @@ import com.google.devtools.ksp.symbol.impl.kotlin.getKSTypeCached
import com.google.devtools.ksp.symbol.impl.memoized
import org.jetbrains.kotlin.types.*

class KSTypeReferenceDescriptorImpl private constructor(val kotlinType: KotlinType) : KSTypeReference {
companion object : KSObjectCache<IdKey<KotlinType>, KSTypeReferenceDescriptorImpl>() {
fun getCached(kotlinType: KotlinType) = cache.getOrPut(IdKey(kotlinType)) { KSTypeReferenceDescriptorImpl(kotlinType) }
class KSTypeReferenceDescriptorImpl private constructor(val kotlinType: KotlinType, override val origin: Origin) : KSTypeReference {
companion object : KSObjectCache<IdKey<Pair<KotlinType, Origin>>, KSTypeReferenceDescriptorImpl>() {
fun getCached(kotlinType: KotlinType, origin: Origin) = cache.getOrPut(IdKey(Pair(kotlinType, origin))) { KSTypeReferenceDescriptorImpl(kotlinType, origin) }
}

override val origin = Origin.CLASS

override val location: Location = NonExistLocation

override val element: KSReferenceElement by lazy {
KSClassifierReferenceDescriptorImpl.getCached(kotlinType)
KSClassifierReferenceDescriptorImpl.getCached(kotlinType, origin)
}

override val annotations: Sequence<KSAnnotation> by lazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@ import com.google.devtools.ksp.symbol.impl.KSObjectCache
import com.google.devtools.ksp.symbol.impl.kotlin.KSNameImpl
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf

class KSValueParameterDescriptorImpl private constructor(val descriptor: ValueParameterDescriptor) : KSValueParameter {
companion object : KSObjectCache<ValueParameterDescriptor, KSValueParameterDescriptorImpl>() {
fun getCached(descriptor: ValueParameterDescriptor) = cache.getOrPut(descriptor) { KSValueParameterDescriptorImpl(descriptor) }
}

override val origin = Origin.CLASS
override val origin by lazy {
descriptor.origin
}

override val location: Location = NonExistLocation

Expand All @@ -53,7 +56,7 @@ class KSValueParameterDescriptorImpl private constructor(val descriptor: ValuePa
}

override val type: KSTypeReference by lazy {
KSTypeReferenceDescriptorImpl.getCached(descriptor.type)
KSTypeReferenceDescriptorImpl.getCached(descriptor.type, origin)
}

override val hasDefault: Boolean = descriptor.hasDefaultValue()
Expand Down
Loading

0 comments on commit fc3abf9

Please sign in to comment.