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 18 19 import com.android.tools.metalava.model.ClassItem 20 import com.android.tools.metalava.model.FieldItem 21 import com.android.tools.metalava.model.Item 22 import com.android.tools.metalava.model.MethodItem 23 import com.android.tools.metalava.model.visitors.ApiVisitor 24 import java.io.PrintWriter 25 import java.util.function.Predicate 26 27 class DexApiWriter( 28 private val writer: PrintWriter, 29 filterEmit: Predicate<Item>, 30 filterReference: Predicate<Item>, 31 inlineInheritedFields: Boolean = true, 32 private val membersOnly: Boolean = false, 33 private val includePositions: Boolean = false 34 ) : ApiVisitor( 35 visitConstructorsAsMethods = true, 36 nestInnerClasses = false, 37 inlineInheritedFields = inlineInheritedFields, 38 filterEmit = filterEmit, 39 filterReference = filterReference 40 ) { visitClassnull41 override fun visitClass(cls: ClassItem) { 42 if (membersOnly) { 43 return 44 } 45 46 if (filterEmit.test(cls)) { 47 writer.print(cls.toType().internalName()) 48 writer.print("\n") 49 } 50 if (includePositions) { 51 writeLocation(cls) 52 } 53 } 54 visitMethodnull55 override fun visitMethod(method: MethodItem) { 56 if (method.inheritedMethod) { 57 return 58 } 59 60 writer.print(method.containingClass().toType().internalName()) 61 writer.print("->") 62 writer.print(method.internalName()) 63 writer.print("(") 64 for (pi in method.parameters()) { 65 writer.print(pi.type().internalName()) 66 } 67 writer.print(")") 68 if (method.isConstructor()) { 69 writer.print("V") 70 } else { 71 val returnType = method.returnType() 72 writer.print(returnType?.internalName() ?: "V") 73 } 74 writer.print("\n") 75 if (includePositions) { 76 writeLocation(method) 77 } 78 } 79 visitFieldnull80 override fun visitField(field: FieldItem) { 81 val cls = field.containingClass() 82 83 writer.print(cls.toType().internalName()) 84 writer.print("->") 85 writer.print(field.name()) 86 writer.print(":") 87 writer.print(field.type().internalName()) 88 writer.print("\n") 89 if (includePositions) { 90 writeLocation(field) 91 } 92 } 93 writeLocationnull94 private fun writeLocation(item: Item) { 95 val psiItem = 96 item.psi() ?: throw DriverException(stderr = "$ARG_DEX_API_MAPPING should only be used on source trees") 97 val location = reporter.elementToLocation(psiItem, false) 98 writer.println(location ?: "<unknown>:-1") 99 } 100 }