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.FieldItem
21 import com.android.tools.metalava.model.PropertyItem
22 import com.android.tools.metalava.model.TypeItem
23 import com.intellij.psi.PsiClass
24 import com.intellij.psi.PsiMethod
25 import com.intellij.psi.PsiType
26 import org.jetbrains.uast.UClass
27 
28 class PsiPropertyItem(
29     override val codebase: PsiBasedCodebase,
30     private val psiMethod: PsiMethod,
31     private val containingClass: PsiClassItem,
32     private val name: String,
33     modifiers: PsiModifierItem,
34     documentation: String,
35     private val fieldType: PsiTypeItem
36 ) :
37     PsiItem(
38         codebase = codebase,
39         modifiers = modifiers,
40         documentation = documentation,
41         element = psiMethod
42     ), PropertyItem {
43 
typenull44     override fun type(): TypeItem = fieldType
45     override fun name(): String = name
46     override fun containingClass(): ClassItem = containingClass
47 
48     override fun isCloned(): Boolean {
49         val psiClass = run {
50             val p = containingClass().psi() as? PsiClass ?: return false
51             if (p is UClass) {
52                 p.sourcePsi as? PsiClass ?: return false
53             } else {
54                 p
55             }
56         }
57         return psiMethod.containingClass != psiClass
58     }
59 
equalsnull60     override fun equals(other: Any?): Boolean {
61         if (this === other) {
62             return true
63         }
64         return other is FieldItem && name == other.name() && containingClass == other.containingClass()
65     }
66 
hashCodenull67     override fun hashCode(): Int {
68         return name.hashCode()
69     }
70 
toStringnull71     override fun toString(): String = "field ${containingClass.fullName()}.${name()}"
72 
73     companion object {
74         fun create(
75             codebase: PsiBasedCodebase,
76             containingClass: PsiClassItem,
77             name: String,
78             psiType: PsiType,
79             psiMethod: PsiMethod
80         ): PsiPropertyItem {
81             val commentText = javadoc(psiMethod)
82             val modifiers = modifiers(codebase, psiMethod, commentText)
83             val typeItem = codebase.getType(psiType)
84             val property = PsiPropertyItem(
85                 codebase = codebase,
86                 psiMethod = psiMethod,
87                 containingClass = containingClass,
88                 name = name,
89                 documentation = commentText,
90                 modifiers = modifiers,
91                 fieldType = typeItem
92             )
93             property.modifiers.setOwner(property)
94             return property
95         }
96     }
97 }