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.TypeParameterItem 20 import com.android.tools.metalava.model.psi.ClassType.TYPE_PARAMETER 21 import com.intellij.psi.PsiTypeParameter 22 import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterBuilder 23 import org.jetbrains.kotlin.asJava.elements.KtLightTypeParameter 24 25 class PsiTypeParameterItem( 26 codebase: PsiBasedCodebase, 27 psiClass: PsiTypeParameter, 28 name: String, 29 modifiers: PsiModifierItem 30 31 ) : PsiClassItem( 32 codebase = codebase, 33 psiClass = psiClass, 34 name = name, 35 fullName = name, 36 qualifiedName = name, 37 hasImplicitDefaultConstructor = false, 38 classType = TYPE_PARAMETER, 39 modifiers = modifiers, 40 documentation = "", 41 fromClassPath = false 42 ), 43 TypeParameterItem { typeBoundsnull44 override fun typeBounds(): List<PsiTypeItem> = bounds 45 46 override fun isReified(): Boolean { 47 return isReified(element as? PsiTypeParameter) 48 } 49 50 private lateinit var bounds: List<PsiTypeItem> 51 finishInitializationnull52 override fun finishInitialization() { 53 super.finishInitialization() 54 55 val refs = psiClass.extendsList?.referencedTypes 56 bounds = if (refs != null && refs.isNotEmpty()) { 57 // Omit java.lang.Object since PSI will turn "T extends Comparable" to "T extends Object & Comparable" 58 // and this just makes comparisons harder; *everything* extends Object. 59 refs.mapNotNull { PsiTypeItem.create(codebase, it) }.filter { !it.isJavaLangObject() } 60 } else { 61 emptyList() 62 } 63 } 64 65 companion object { createnull66 fun create(codebase: PsiBasedCodebase, psiClass: PsiTypeParameter): PsiTypeParameterItem { 67 val simpleName = psiClass.name!! 68 val modifiers = modifiers(codebase, psiClass, "") 69 70 val item = PsiTypeParameterItem( 71 codebase = codebase, 72 psiClass = psiClass, 73 name = simpleName, 74 modifiers = modifiers 75 ) 76 item.modifiers.setOwner(item) 77 item.initialize(emptyList(), emptyList(), emptyList(), emptyList(), emptyList()) 78 return item 79 } 80 isReifiednull81 fun isReified(element: PsiTypeParameter?): Boolean { 82 element ?: return false 83 if (element is KtLightTypeParameter && 84 element.kotlinOrigin.text.startsWith("reified") 85 ) { 86 return true 87 } else if (element is KotlinLightTypeParameterBuilder) { 88 if (element.origin.text.startsWith("reified")) { 89 return true 90 } 91 } 92 return false 93 } 94 } 95 } 96