Moving some logic into ApiVisitor.kt so it can be more easily modified by ComparisonVisitor.kt
Bug: 131633221
Test: ./gradlew test
Change-Id: Ie15c1890f4a141ffa46879367a1f28319f945a26
diff --git a/src/main/java/com/android/tools/metalava/model/ClassItem.kt b/src/main/java/com/android/tools/metalava/model/ClassItem.kt
index 768f648..f7c905e 100644
--- a/src/main/java/com/android/tools/metalava/model/ClassItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/ClassItem.kt
@@ -298,9 +298,6 @@
}
fun accept(visitor: ApiVisitor) {
- if (visitor.skip(this)) {
- return
- }
if (!visitor.include(this)) {
return
@@ -757,8 +754,8 @@
fun addMethod(method: MethodItem): Unit = codebase.unsupported()
}
-class VisitCandidate(private val cls: ClassItem, private val visitor: ApiVisitor) {
- private val innerClasses: Sequence<VisitCandidate>
+class VisitCandidate(val cls: ClassItem, private val visitor: ApiVisitor) {
+ public val innerClasses: Sequence<VisitCandidate>
private val constructors: Sequence<MethodItem>
private val methods: Sequence<MethodItem>
private val fields: Sequence<FieldItem>
@@ -810,48 +807,17 @@
.map { VisitCandidate(it, visitor) }
}
- /** Will this class emit anything? */
- private fun emit(): Boolean {
- val emit = emitClass()
- if (emit) {
- return true
- }
-
- return emitInner()
- }
-
- private fun emitInner(): Boolean {
- return innerClasses.any { it.emit() }
- }
-
- /** Does the body of this class (everything other than the inner classes) emit anything? */
- private fun emitClass(): Boolean {
- val classEmpty = (constructors.none() && methods.none() && enums.none() && fields.none() && properties.none())
- return if (visitor.filterEmit.test(cls)) {
- true
- } else if (!classEmpty) {
- visitor.filterReference.test(cls)
- } else {
- false
- }
+ /** Whether the class body contains any Item's (other than inner Classes) */
+ public fun nonEmpty(): Boolean {
+ return !(constructors.none() && methods.none() && enums.none() && fields.none() && properties.none())
}
fun accept() {
- if (visitor.skip(cls)) {
+ if (!visitor.include(this)) {
return
}
- if (!visitor.include(cls)) {
- return
- }
-
- val emitClass = emitClass()
- val emit = emitClass || emitInner()
- if (!emit) {
- return
- }
-
- val emitThis = cls.emit && if (visitor.includeEmptyOuterClasses) emit else emitClass
+ val emitThis = visitor.shouldEmitClass(this)
if (emitThis) {
if (!visitor.visitingPackage) {
visitor.visitingPackage = true
diff --git a/src/main/java/com/android/tools/metalava/model/visitors/ApiVisitor.kt b/src/main/java/com/android/tools/metalava/model/visitors/ApiVisitor.kt
index 76b4a34..411f008 100644
--- a/src/main/java/com/android/tools/metalava/model/visitors/ApiVisitor.kt
+++ b/src/main/java/com/android/tools/metalava/model/visitors/ApiVisitor.kt
@@ -21,6 +21,7 @@
import com.android.tools.metalava.model.FieldItem
import com.android.tools.metalava.model.Item
import com.android.tools.metalava.model.MethodItem
+import com.android.tools.metalava.model.VisitCandidate
import com.android.tools.metalava.options
import java.util.function.Predicate
@@ -109,7 +110,13 @@
// this property keeps track of whether we've already visited the current package
var visitingPackage = false
+ /**
+ * @return Whether this class is generally one that we want to recurse into
+ */
open fun include(cls: ClassItem): Boolean {
+ if (skip(cls)) {
+ return false
+ }
val filter = options.stubPackages
if (filter != null && !filter.matches(cls.containingPackage())) {
return false
@@ -117,4 +124,50 @@
return cls.emit || cls.codebase.preFiltered
}
+
+ /**
+ * @return Whether the given VisitCandidate's visitor should recurse into the given
+ * VisitCandidate's class
+ */
+ fun include(vc: VisitCandidate): Boolean {
+ if (!include(vc.cls)) {
+ return false
+ }
+ return shouldEmitClassBody(vc) || shouldEmitInnerClasses(vc)
+ }
+
+ /**
+ * @return Whether this class should be visited
+ * Note that if [include] returns true then we will still visit classes that are contained by this one
+ */
+ open fun shouldEmitClass(vc: VisitCandidate): Boolean {
+ return vc.cls.emit && (includeEmptyOuterClasses || shouldEmitClassBody(vc))
+ }
+
+ /**
+ * @return Whether the body of this class (everything other than the inner classes) emits anything
+ */
+ fun shouldEmitClassBody(vc: VisitCandidate): Boolean {
+ return if (filterEmit.test(vc.cls)) {
+ true
+ } else if (vc.nonEmpty()) {
+ filterReference.test(vc.cls)
+ } else {
+ false
+ }
+ }
+
+ /**
+ * @return Whether the inner classes of this class will emit anything
+ */
+ fun shouldEmitInnerClasses(vc: VisitCandidate): Boolean {
+ return vc.innerClasses.any { shouldEmitAnyClass(it) }
+ }
+
+ /**
+ * @return Whether this class will emit anything
+ */
+ fun shouldEmitAnyClass(vc: VisitCandidate): Boolean {
+ return shouldEmitClassBody(vc) || shouldEmitInnerClasses(vc)
+ }
}