• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.tools.metalava.model.psi
18 
19 import com.android.tools.metalava.model.BaseModifierList
20 import com.android.tools.metalava.model.VariableTypeItem
21 import com.android.tools.metalava.model.item.DefaultTypeParameterItem
22 import com.intellij.psi.PsiTypeParameter
23 import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterBuilder
24 import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
25 import org.jetbrains.kotlin.lexer.KtTokens
26 import org.jetbrains.kotlin.psi.KtTypeParameter
27 
28 internal class PsiTypeParameterItem(
29     override val codebase: PsiBasedCodebase,
30     private val psiTypeParameter: PsiTypeParameter,
31     name: String,
32     modifiers: BaseModifierList
33 ) :
34     DefaultTypeParameterItem(
35         codebase = codebase,
36         modifiers = modifiers,
37         name = name,
38         isReified = isReified(psiTypeParameter),
39     ) {
psinull40     fun psi() = psiTypeParameter
41 
42     override fun createVariableTypeItem(): VariableTypeItem {
43         return codebase.globalTypeItemFactory.getVariableTypeForTypeParameter(this)
44     }
45 
46     companion object {
createnull47         fun create(
48             codebase: PsiBasedCodebase,
49             psiTypeParameter: PsiTypeParameter,
50         ): PsiTypeParameterItem {
51             val simpleName = psiTypeParameter.name!!
52             val modifiers = PsiModifierItem.create(codebase, psiTypeParameter)
53 
54             return PsiTypeParameterItem(
55                 codebase = codebase,
56                 psiTypeParameter = psiTypeParameter,
57                 name = simpleName,
58                 modifiers = modifiers
59             )
60         }
61 
isReifiednull62         fun isReified(element: PsiTypeParameter?): Boolean {
63             element ?: return false
64             // TODO(jsjeon): Handle PsiElementWithOrigin<*> when available
65             if (
66                 element is KtLightDeclaration<*, *> &&
67                     element.kotlinOrigin is KtTypeParameter &&
68                     element.kotlinOrigin?.text?.startsWith(KtTokens.REIFIED_KEYWORD.value) == true
69             ) {
70                 return true
71             } else if (
72                 element is KotlinLightTypeParameterBuilder &&
73                     element.origin.text.startsWith(KtTokens.REIFIED_KEYWORD.value)
74             ) {
75                 return true
76             }
77             return false
78         }
79 
80         /**
81          * Creates a [DefaultTypeParameterItem] using the [ktTypeParameter]. Should be used only
82          * when there is no [PsiTypeParameter] available.
83          *
84          * The returned type parameter uses the default type implementation, which does not create a
85          * [PsiVariableTypeItem], as the analysis API doesn't have a direct way to create a psi type
86          * from the [KtTypeParameter].
87          */
createnull88         fun create(
89             codebase: PsiBasedCodebase,
90             ktTypeParameter: KtTypeParameter
91         ): DefaultTypeParameterItem {
92             return DefaultTypeParameterItem(
93                 codebase = codebase,
94                 modifiers = PsiModifierItem.createForKtDeclaration(codebase, ktTypeParameter),
95                 name = ktTypeParameter.name!!,
96                 isReified = ktTypeParameter.text.startsWith(KtTokens.REIFIED_KEYWORD.value)
97             )
98         }
99     }
100 }
101