• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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
18 
19 import com.android.tools.metalava.model.ClassItem
20 import com.android.tools.metalava.model.ConstructorItem
21 import com.android.tools.metalava.model.DelegatedVisitor
22 import com.android.tools.metalava.model.FieldItem
23 import com.android.tools.metalava.model.MethodItem
24 import com.android.tools.metalava.model.ParameterItem
25 import com.android.tools.metalava.model.TypeItem
26 import com.android.tools.metalava.model.TypeStringConfiguration
27 import com.android.tools.metalava.model.VisibilityLevel
28 import java.io.PrintWriter
29 
30 class ProguardWriter(
31     private val writer: PrintWriter,
32 ) : DelegatedVisitor {
33 
visitClassnull34     override fun visitClass(cls: ClassItem) {
35         writer.print("-keep class ")
36         writer.print(getCleanTypeName(cls.type()))
37         writer.print(" {\n")
38     }
39 
afterVisitClassnull40     override fun afterVisitClass(cls: ClassItem) {
41         writer.print("}\n")
42     }
43 
visitConstructornull44     override fun visitConstructor(constructor: ConstructorItem) {
45         writer.print("    ")
46         writer.print("<init>")
47 
48         writeParametersKeepList(constructor.parameters())
49         writer.print(";\n")
50     }
51 
visitMethodnull52     override fun visitMethod(method: MethodItem) {
53         writer.print("    ")
54         val modifiers = method.modifiers
55         val visibilityLevel = modifiers.getVisibilityLevel()
56         if (visibilityLevel != VisibilityLevel.PACKAGE_PRIVATE) {
57             writer.write(visibilityLevel.javaSourceCodeModifier + " ")
58         }
59 
60         if (modifiers.isStatic()) {
61             writer.print("static ")
62         }
63         if (modifiers.isAbstract()) {
64             writer.print("abstract ")
65         }
66         if (modifiers.isSynchronized()) {
67             writer.print("synchronized ")
68         }
69 
70         writer.print(getCleanTypeName(method.returnType()))
71         writer.print(" ")
72         writer.print(method.name())
73 
74         writeParametersKeepList(method.parameters())
75 
76         writer.print(";\n")
77     }
78 
writeParametersKeepListnull79     private fun writeParametersKeepList(params: List<ParameterItem>) {
80         writer.print("(")
81 
82         for (pi in params) {
83             if (pi !== params[0]) {
84                 writer.print(", ")
85             }
86             writer.print(getCleanTypeName(pi.type()))
87         }
88 
89         writer.print(")")
90     }
91 
visitFieldnull92     override fun visitField(field: FieldItem) {
93         writer.print("    ")
94 
95         val modifiers = field.modifiers
96         val visibilityLevel = modifiers.getVisibilityLevel()
97         if (visibilityLevel != VisibilityLevel.PACKAGE_PRIVATE) {
98             writer.write(visibilityLevel.javaSourceCodeModifier + " ")
99         }
100 
101         if (modifiers.isStatic()) {
102             writer.print("static ")
103         }
104         if (modifiers.isTransient()) {
105             writer.print("transient ")
106         }
107         if (modifiers.isVolatile()) {
108             writer.print("volatile ")
109         }
110 
111         writer.print(getCleanTypeName(field.type()))
112 
113         writer.print(" ")
114         writer.print(field.name())
115 
116         writer.print(";\n")
117     }
118 
getCleanTypeNamenull119     private fun getCleanTypeName(t: TypeItem?): String {
120         return t?.toTypeString(PROGUARD_TYPE_STRING_CONFIGURATION) ?: ""
121     }
122 
123     companion object {
124         private val PROGUARD_TYPE_STRING_CONFIGURATION =
125             TypeStringConfiguration(
126                 eraseGenerics = true,
127                 nestedClassSeparator = '$',
128                 treatVarargsAsArray = true,
129             )
130     }
131 }
132