1 /*
2  * Copyright 2020 Google LLC
3  * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.google.devtools.ksp.symbol.impl.binary
19 
20 import com.google.devtools.ksp.ExceptionMessage
21 import com.google.devtools.ksp.KSObjectCache
22 import com.google.devtools.ksp.processing.impl.ResolverImpl
23 import com.google.devtools.ksp.symbol.*
24 import com.google.devtools.ksp.symbol.impl.*
25 import com.google.devtools.ksp.toFunctionKSModifiers
26 import com.google.devtools.ksp.toKSModifiers
27 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
28 import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
29 import org.jetbrains.kotlin.load.java.isFromJava
30 import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
31 import org.jetbrains.org.objectweb.asm.Opcodes
32 
33 class KSFunctionDeclarationDescriptorImpl private constructor(val descriptor: FunctionDescriptor) :
34     KSFunctionDeclaration,
35     KSDeclarationDescriptorImpl(descriptor),
36     KSExpectActual by KSExpectActualDescriptorImpl(descriptor) {
37     companion object : KSObjectCache<FunctionDescriptor, KSFunctionDeclarationDescriptorImpl>() {
getCachednull38         fun getCached(descriptor: FunctionDescriptor) =
39             cache.getOrPut(descriptor) { KSFunctionDeclarationDescriptorImpl(descriptor) }
40     }
41 
findOverrideenull42     override fun findOverridee(): KSDeclaration? {
43         return descriptor?.findClosestOverridee()?.toKSDeclaration()
44     }
45 
<lambda>null46     override val typeParameters: List<KSTypeParameter> by lazy {
47         descriptor.typeParameters.map { KSTypeParameterDescriptorImpl.getCached(it) }
48     }
49 
50     override val declarations: Sequence<KSDeclaration> = emptySequence()
51 
<lambda>null52     override val extensionReceiver: KSTypeReference? by lazy {
53         val extensionReceiver = descriptor.extensionReceiverParameter?.type
54         if (extensionReceiver != null) {
55             KSTypeReferenceDescriptorImpl.getCached(extensionReceiver, origin, this)
56         } else {
57             null
58         }
59     }
60 
<lambda>null61     override val functionKind: FunctionKind by lazy {
62 
63         when {
64             descriptor.dispatchReceiverParameter == null -> when {
65                 descriptor.isFromJava -> FunctionKind.STATIC
66                 else -> FunctionKind.TOP_LEVEL
67             }
68             !descriptor.name.isSpecial && !descriptor.name.asString().isEmpty() -> FunctionKind.MEMBER
69             descriptor is AnonymousFunctionDescriptor -> FunctionKind.ANONYMOUS
70             else -> throw IllegalStateException(
71                 "Unable to resolve FunctionKind for ${descriptor.fqNameSafe}, $ExceptionMessage"
72             )
73         }
74     }
75 
<lambda>null76     override val isAbstract: Boolean by lazy {
77         this.modifiers.contains(Modifier.ABSTRACT)
78     }
79 
<lambda>null80     override val modifiers: Set<Modifier> by lazy {
81         val modifiers = mutableSetOf<Modifier>()
82         modifiers.addAll(descriptor.toKSModifiers())
83         modifiers.addAll(descriptor.toFunctionKSModifiers())
84 
85         if (this.origin == Origin.JAVA_LIB) {
86             if (this.jvmAccessFlag and Opcodes.ACC_STRICT != 0)
87                 modifiers.add(Modifier.JAVA_STRICT)
88             if (this.jvmAccessFlag and Opcodes.ACC_SYNCHRONIZED != 0)
89                 modifiers.add(Modifier.JAVA_SYNCHRONIZED)
90         }
91 
92         modifiers
93     }
94 
<lambda>null95     override val parameters: List<KSValueParameter> by lazy {
96         descriptor.valueParameters.map { KSValueParameterDescriptorImpl.getCached(it, this) }
97     }
98 
<lambda>null99     override val returnType: KSTypeReference? by lazy {
100         val returnType = descriptor.returnType
101         if (returnType == null) {
102             null
103         } else {
104             KSTypeReferenceDescriptorImpl.getCached(returnType, origin, this)
105         }
106     }
107 
acceptnull108     override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R {
109         return visitor.visitFunctionDeclaration(this, data)
110     }
111 
asMemberOfnull112     override fun asMemberOf(containing: KSType): KSFunction =
113         ResolverImpl.instance!!.asMemberOf(this, containing)
114 }
115