• 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.FieldItem
22 import com.android.tools.metalava.model.Item
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.visitors.ApiVisitor
27 import java.io.PrintWriter
28 import java.util.function.Predicate
29 
30 class ProguardWriter(
31     private val writer: PrintWriter,
32     filterEmit: Predicate<Item>,
33     filterReference: Predicate<Item>
34 ) : ApiVisitor(
35     visitConstructorsAsMethods = false,
36     nestInnerClasses = false,
37     inlineInheritedFields = true,
38     filterEmit = filterEmit,
39     filterReference = filterReference
40 ) {
41 
visitClassnull42     override fun visitClass(cls: ClassItem) {
43         writer.print("-keep class ")
44         writer.print(cls.qualifiedNameWithDollarInnerClasses())
45         writer.print(" {\n")
46     }
47 
afterVisitClassnull48     override fun afterVisitClass(cls: ClassItem) {
49         writer.print("}\n")
50     }
51 
visitConstructornull52     override fun visitConstructor(constructor: ConstructorItem) {
53         writer.print("    ")
54         writer.print("<init>")
55 
56         writeParametersKeepList(constructor.parameters())
57         writer.print(";\n")
58     }
59 
visitMethodnull60     override fun visitMethod(method: MethodItem) {
61         writer.print("    ")
62         val modifiers = method.modifiers
63         when {
64             modifiers.isPublic() -> writer.write("public ")
65             modifiers.isProtected() -> writer.write("protected ")
66             modifiers.isPrivate() -> writer.write("private ")
67         }
68 
69         if (modifiers.isStatic()) {
70             writer.print("static ")
71         }
72         if (modifiers.isAbstract()) {
73             writer.print("abstract ")
74         }
75         if (modifiers.isSynchronized()) {
76             writer.print("synchronized ")
77         }
78 
79         writer.print(getCleanTypeName(method.returnType()))
80         writer.print(" ")
81         writer.print(method.name())
82 
83         writeParametersKeepList(method.parameters())
84 
85         writer.print(";\n")
86     }
87 
writeParametersKeepListnull88     private fun writeParametersKeepList(params: List<ParameterItem>) {
89         writer.print("(")
90 
91         for (pi in params) {
92             if (pi !== params[0]) {
93                 writer.print(", ")
94             }
95             writer.print(getCleanTypeName(pi.type()))
96         }
97 
98         writer.print(")")
99     }
100 
visitFieldnull101     override fun visitField(field: FieldItem) {
102         writer.print("    ")
103 
104         val modifiers = field.modifiers
105         when {
106             modifiers.isPublic() -> writer.write("public ")
107             modifiers.isProtected() -> writer.write("protected ")
108             modifiers.isPrivate() -> writer.write("private ")
109         }
110 
111         if (modifiers.isStatic()) {
112             writer.print("static ")
113         }
114         if (modifiers.isTransient()) {
115             writer.print("transient ")
116         }
117         if (modifiers.isVolatile()) {
118             writer.print("volatile ")
119         }
120 
121         writer.print(getCleanTypeName(field.type()))
122 
123         writer.print(" ")
124         writer.print(field.name())
125 
126         writer.print(";\n")
127     }
128 
getCleanTypeNamenull129     private fun getCleanTypeName(t: TypeItem?): String {
130         t ?: return ""
131         val cls = t.asClass() ?: return t.toSimpleType()
132         return cls.qualifiedNameWithDollarInnerClasses()
133     }
134 }