1 /*
2  * Copyright (C) 2023 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 package com.android.tools.metalava.model.turbine
17 
18 import com.android.tools.metalava.model.AnnotationItem
19 import com.android.tools.metalava.model.Codebase
20 import com.android.tools.metalava.model.DefaultModifierList
21 import com.android.tools.metalava.model.DefaultModifierList.Companion.ABSTRACT
22 import com.android.tools.metalava.model.DefaultModifierList.Companion.DEFAULT
23 import com.android.tools.metalava.model.DefaultModifierList.Companion.FINAL
24 import com.android.tools.metalava.model.DefaultModifierList.Companion.NATIVE
25 import com.android.tools.metalava.model.DefaultModifierList.Companion.PRIVATE
26 import com.android.tools.metalava.model.DefaultModifierList.Companion.PROTECTED
27 import com.android.tools.metalava.model.DefaultModifierList.Companion.PUBLIC
28 import com.android.tools.metalava.model.DefaultModifierList.Companion.SEALED
29 import com.android.tools.metalava.model.DefaultModifierList.Companion.STATIC
30 import com.android.tools.metalava.model.DefaultModifierList.Companion.STRICT_FP
31 import com.android.tools.metalava.model.DefaultModifierList.Companion.SYNCHRONIZED
32 import com.android.tools.metalava.model.DefaultModifierList.Companion.TRANSIENT
33 import com.android.tools.metalava.model.DefaultModifierList.Companion.VARARG
34 import com.android.tools.metalava.model.DefaultModifierList.Companion.VOLATILE
35 import com.google.turbine.model.TurbineFlag
36 
37 internal object TurbineModifierItem {
createnull38     fun create(
39         codebase: Codebase,
40         flag: Int,
41         annotations: List<AnnotationItem>?,
42         isDeprecatedViaDoc: Boolean,
43     ): DefaultModifierList {
44         val modifierItem =
45             when (flag) {
46                 0 -> { // No Modifier. Default modifier is PACKAGE_PRIVATE in such case
47                     DefaultModifierList(codebase, annotations = annotations?.toMutableList())
48                 }
49                 else -> {
50                     DefaultModifierList(codebase, computeFlag(flag), annotations?.toMutableList())
51                 }
52             }
53         modifierItem.setDeprecated(isDeprecated(annotations) || isDeprecatedViaDoc)
54         return modifierItem
55     }
56 
57     /**
58      * Given flag value corresponding to Turbine modifiers compute the equivalent flag in Metalava.
59      */
computeFlagnull60     private fun computeFlag(flag: Int): Int {
61         // If no visibility flag is provided, result remains 0, implying a 'package-private' default
62         // state.
63         var result = 0
64 
65         if (flag and TurbineFlag.ACC_STATIC != 0) {
66             result = result or STATIC
67         }
68         if (flag and TurbineFlag.ACC_ABSTRACT != 0) {
69             result = result or ABSTRACT
70         }
71         if (flag and TurbineFlag.ACC_FINAL != 0) {
72             result = result or FINAL
73         }
74         if (flag and TurbineFlag.ACC_NATIVE != 0) {
75             result = result or NATIVE
76         }
77         if (flag and TurbineFlag.ACC_SYNCHRONIZED != 0) {
78             result = result or SYNCHRONIZED
79         }
80         if (flag and TurbineFlag.ACC_STRICT != 0) {
81             result = result or STRICT_FP
82         }
83         if (flag and TurbineFlag.ACC_TRANSIENT != 0) {
84             result = result or TRANSIENT
85         }
86         if (flag and TurbineFlag.ACC_VOLATILE != 0) {
87             result = result or VOLATILE
88         }
89         if (flag and TurbineFlag.ACC_DEFAULT != 0) {
90             result = result or DEFAULT
91         }
92         if (flag and TurbineFlag.ACC_SEALED != 0) {
93             result = result or SEALED
94         }
95         if (flag and TurbineFlag.ACC_VARARGS != 0) {
96             result = result or VARARG
97         }
98 
99         // Visibility Modifiers
100         if (flag and TurbineFlag.ACC_PUBLIC != 0) {
101             result = result or PUBLIC
102         }
103         if (flag and TurbineFlag.ACC_PRIVATE != 0) {
104             result = result or PRIVATE
105         }
106         if (flag and TurbineFlag.ACC_PROTECTED != 0) {
107             result = result or PROTECTED
108         }
109 
110         return result
111     }
112 
isDeprecatednull113     private fun isDeprecated(annotations: List<AnnotationItem>?): Boolean {
114         return annotations?.any { it.qualifiedName == "java.lang.Deprecated" } ?: false
115     }
116 }
117