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.ExceptionMessage
21 import com.google.devtools.ksp.KSObjectCache
22 import com.google.devtools.ksp.processing.impl.ResolverImpl
23 import com.google.devtools.ksp.symbol.KSAnnotation
24 import com.google.devtools.ksp.symbol.KSNode
25 import com.google.devtools.ksp.symbol.KSReferenceElement
26 import com.google.devtools.ksp.symbol.KSType
27 import com.google.devtools.ksp.symbol.KSTypeReference
28 import com.google.devtools.ksp.symbol.KSVisitor
29 import com.google.devtools.ksp.symbol.Location
30 import com.google.devtools.ksp.symbol.Modifier
31 import com.google.devtools.ksp.symbol.NonExistLocation
32 import com.google.devtools.ksp.symbol.Origin
33 import com.google.devtools.ksp.symbol.impl.kotlin.KSErrorType
34 import com.intellij.psi.PsiAnnotation
35 import com.intellij.psi.PsiClass
36 import com.intellij.psi.PsiElement
37 import com.intellij.psi.PsiJavaFile
38 import com.intellij.psi.PsiMethod
39 
40 class KSTypeReferenceLiteJavaImpl private constructor(val psiElement: PsiElement, override val parent: KSNode) :
41     KSTypeReference {
42     companion object : KSObjectCache<KSNode, KSTypeReferenceLiteJavaImpl>() {
getCachednull43         fun getCached(psiElement: PsiElement, parent: KSNode) = cache
44             .getOrPut(parent) { KSTypeReferenceLiteJavaImpl(psiElement, parent) }
45     }
46 
<lambda>null47     val type: KSType by lazy {
48         when (psiElement) {
49             is PsiAnnotation -> {
50                 val psiClass = psiElement.nameReferenceElement!!.resolve() as? PsiClass
51                 psiClass?.let {
52                     (psiElement.containingFile as? PsiJavaFile)?.let {
53                         ResolverImpl.instance!!.incrementalContext.recordLookup(it, psiClass.qualifiedName!!)
54                     }
55                     KSClassDeclarationJavaImpl.getCached(psiClass).asStarProjectedType()
56                 } ?: KSErrorType
57             }
58             is PsiMethod -> {
59                 KSClassDeclarationJavaImpl.getCached(psiElement.containingClass!!).asStarProjectedType()
60             }
61             else -> throw IllegalStateException(
62                 "Unexpected psi type in KSTypeReferenceLiteJavaImpl: ${psiElement.javaClass}, $ExceptionMessage"
63             )
64         }
65     }
66 
67     override val origin = Origin.JAVA
68 
69     override val location: Location = NonExistLocation
70 
<lambda>null71     override val element: KSReferenceElement by lazy {
72         KSClassifierReferenceLiteImplForJava.getCached(this)
73     }
74 
75     override val annotations: Sequence<KSAnnotation> = emptySequence()
76 
77     override val modifiers: Set<Modifier> = emptySet()
78 
resolvenull79     override fun resolve(): KSType {
80         return type
81     }
82 
acceptnull83     override fun <D, R> accept(visitor: KSVisitor<D, R>, data: D): R {
84         return visitor.visitTypeReference(this, data)
85     }
86 
toStringnull87     override fun toString(): String {
88         return type.toString()
89     }
90 }
91