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.java
19 
20 import com.google.devtools.ksp.KSObjectCache
21 import com.google.devtools.ksp.memoized
22 import com.google.devtools.ksp.processing.impl.KSNameImpl
23 import com.google.devtools.ksp.processing.impl.ResolverImpl
24 import com.google.devtools.ksp.symbol.*
25 import com.google.devtools.ksp.symbol.impl.*
26 import com.google.devtools.ksp.symbol.impl.kotlin.KSExpectActualNoImpl
27 import com.google.devtools.ksp.toKSModifiers
28 import com.intellij.lang.jvm.JvmModifier
29 import com.intellij.psi.PsiJavaFile
30 import com.intellij.psi.PsiMethod
31 import org.jetbrains.kotlin.descriptors.FunctionDescriptor
32 
33 class KSFunctionDeclarationJavaImpl private constructor(val psi: PsiMethod) :
34     KSFunctionDeclaration,
35     KSDeclarationJavaImpl(psi),
36     KSExpectActual by KSExpectActualNoImpl() {
37     companion object : KSObjectCache<PsiMethod, KSFunctionDeclarationJavaImpl>() {
<lambda>null38         fun getCached(psi: PsiMethod) = cache.getOrPut(psi) { KSFunctionDeclarationJavaImpl(psi) }
39     }
40 
41     override val origin = Origin.JAVA
42 
<lambda>null43     override val location: Location by lazy {
44         psi.toLocation()
45     }
46 
<lambda>null47     override val annotations: Sequence<KSAnnotation> by lazy {
48         psi.annotations.asSequence().map { KSAnnotationJavaImpl.getCached(it) }.memoized()
49     }
50 
<lambda>null51     override val containingFile: KSFile? by lazy {
52         KSFileJavaImpl.getCached(psi.containingFile as PsiJavaFile)
53     }
54 
findOverrideenull55     override fun findOverridee(): KSDeclaration? {
56         val descriptor = ResolverImpl.instance!!.resolveFunctionDeclaration(this)
57         return (descriptor as? FunctionDescriptor)?.findClosestOverridee()?.toKSDeclaration()
58     }
59 
60     override val declarations: Sequence<KSDeclaration> = emptySequence()
61 
62     override val extensionReceiver: KSTypeReference? = null
63 
64     override val functionKind: FunctionKind = when {
65         psi.hasModifier(JvmModifier.STATIC) -> FunctionKind.STATIC
66         else -> FunctionKind.MEMBER
67     }
68 
<lambda>null69     override val isAbstract: Boolean by lazy {
70         this.modifiers.contains(Modifier.ABSTRACT) ||
71             (
72                 (this.parentDeclaration as? KSClassDeclaration)?.classKind == ClassKind.INTERFACE &&
73                     !this.modifiers.contains(Modifier.JAVA_DEFAULT) && functionKind != FunctionKind.STATIC
74                 )
75     }
76 
<lambda>null77     override val modifiers: Set<Modifier> by lazy {
78         psi.toKSModifiers()
79     }
80 
<lambda>null81     override val parameters: List<KSValueParameter> by lazy {
82         psi.parameterList.parameters.map { KSValueParameterJavaImpl.getCached(it) }
83     }
84 
<lambda>null85     override val parentDeclaration: KSDeclaration? by lazy {
86         psi.findParentDeclaration()
87     }
88 
<lambda>null89     override val qualifiedName: KSName by lazy {
90         KSNameImpl.getCached("${parentDeclaration?.qualifiedName?.asString()}.${this.simpleName.asString()}")
91     }
92 
<lambda>null93     override val returnType: KSTypeReference? by lazy {
94         when {
95             psi.returnType != null -> {
96                 KSTypeReferenceJavaImpl.getCached(psi.returnType!!, this)
97             }
98             psi.isConstructor -> {
99                 KSTypeReferenceLiteJavaImpl.getCached(psi, this)
100             }
101             else -> {
102                 null
103             }
104         }
105     }
106 
<lambda>null107     override val simpleName: KSName by lazy {
108         if (psi.isConstructor) {
109             KSNameImpl.getCached("<init>")
110         } else {
111             KSNameImpl.getCached(psi.name)
112         }
113     }
114 
<lambda>null115     override val typeParameters: List<KSTypeParameter> by lazy {
116         psi.typeParameters.map { KSTypeParameterJavaImpl.getCached(it) }
117     }
118 
acceptnull119     override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R {
120         return visitor.visitFunctionDeclaration(this, data)
121     }
122 
asMemberOfnull123     override fun asMemberOf(containing: KSType): KSFunction =
124         ResolverImpl.instance!!.asMemberOf(this, containing)
125 }
126