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