1 /* <lambda>null2 * 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.model 18 19 import com.android.tools.metalava.model.visitors.ApiVisitor 20 import com.android.tools.metalava.model.visitors.ItemVisitor 21 import com.android.tools.metalava.model.visitors.TypeVisitor 22 import com.android.tools.metalava.tick 23 24 interface PackageItem : Item { 25 /** The qualified name of this package */ 26 fun qualifiedName(): String 27 28 /** All top level classes in this package */ 29 fun topLevelClasses(): Sequence<ClassItem> 30 31 /** All top level classes **and inner classes** in this package */ 32 fun allClasses(): Sequence<ClassItem> { 33 return topLevelClasses().asSequence().flatMap { it.allClasses() } 34 } 35 36 override fun type(): TypeItem? = null 37 38 val isDefault get() = qualifiedName().isEmpty() 39 40 override fun parent(): PackageItem? = if (qualifiedName().isEmpty()) null else containingPackage() 41 42 override fun containingPackage(strict: Boolean): PackageItem? { 43 if (!strict) { 44 return this 45 } 46 val name = qualifiedName() 47 val lastDot = name.lastIndexOf('.') 48 return if (lastDot != -1) { 49 codebase.findPackage(name.substring(0, lastDot)) 50 } else { 51 null 52 } 53 } 54 55 /** Whether this package is empty */ 56 fun empty() = topLevelClasses().none() 57 58 override fun accept(visitor: ItemVisitor) { 59 if (visitor.skipEmptyPackages && empty()) { 60 return 61 } 62 63 if (visitor is ApiVisitor) { 64 if (!emit) { 65 return 66 } 67 68 // For the API visitor packages are visited lazily; only when we encounter 69 // an unfiltered item within the class 70 topLevelClasses() 71 .asSequence() 72 .sortedWith(ClassItem.classNameSorter()) 73 .forEach { 74 tick() 75 it.accept(visitor) 76 } 77 78 if (visitor.visitingPackage) { 79 visitor.visitingPackage = false 80 visitor.afterVisitPackage(this) 81 visitor.afterVisitItem(this) 82 } 83 84 return 85 } 86 87 if (visitor.skip(this)) { 88 return 89 } 90 91 visitor.visitItem(this) 92 visitor.visitPackage(this) 93 94 for (cls in topLevelClasses()) { 95 cls.accept(visitor) 96 } 97 98 visitor.afterVisitPackage(this) 99 visitor.afterVisitItem(this) 100 } 101 102 override fun acceptTypes(visitor: TypeVisitor) { 103 if (visitor.skip(this)) { 104 return 105 } 106 107 for (unit in topLevelClasses()) { 108 unit.acceptTypes(visitor) 109 } 110 } 111 112 companion object { 113 val comparator: Comparator<PackageItem> = Comparator { a, b -> a.qualifiedName().compareTo(b.qualifiedName()) } 114 } 115 } 116