Skip to content

Commit

Permalink
fix: generate supergraph just once per variant (source set).
Browse files Browse the repository at this point in the history
  • Loading branch information
autonomousapps committed Feb 10, 2025
1 parent 160cf75 commit a56b5a9
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.autonomousapps.internal.graph.supers
import com.autonomousapps.internal.graph.newGraphBuilder
import com.autonomousapps.model.Coordinates
import com.autonomousapps.model.internal.BinaryClassCapability
import com.autonomousapps.model.internal.Dependency
import com.autonomousapps.visitor.GraphViewVisitor
import com.google.common.graph.Graph

Expand Down Expand Up @@ -42,10 +43,10 @@ internal class SuperClassGraphBuilder {

companion object {
/** Builds a graph from child classes up through super classes and interfaces, up to `java.lang.Object`. */
fun of(context: GraphViewVisitor.Context): Graph<SuperNode> {
fun of(dependencies: Set<Dependency>): Graph<SuperNode> {
val builder = SuperClassGraphBuilder()

context.dependencies.forEach { dep ->
dependencies.forEach { dep ->
dep.findCapability<BinaryClassCapability>()?.let { capability ->
capability.binaryClasses.map { bin ->
val from = SuperNode(bin.className).apply {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@
package com.autonomousapps.model.internal

import com.autonomousapps.internal.unsafeLazy
import com.autonomousapps.internal.utils.flatMapToOrderedSet
import com.autonomousapps.internal.utils.flatMapToSet
import com.autonomousapps.internal.utils.fromJson
import com.autonomousapps.model.internal.CodeSource.Kind
import com.autonomousapps.internal.utils.*
import com.autonomousapps.model.Coordinates
import com.autonomousapps.model.ProjectCoordinates
import com.autonomousapps.model.declaration.Variant
import com.autonomousapps.model.internal.intermediates.consumer.MemberAccess
import com.autonomousapps.model.internal.CodeSource.Kind
import com.squareup.moshi.JsonClass
import org.gradle.api.file.Directory

Expand Down Expand Up @@ -86,6 +83,22 @@ internal data class ProjectVariant(
usedNonAnnotationClasses - exposedClasses
}

/**
* The set of super classes and interfaces not available from [codeSource] (therefore "external" to "this" module).
*/
val externalSupers: Set<String> by unsafeLazy {
val supers = codeSource.mapNotNullToOrderedSet { src -> src.superClass }
val interfaces = codeSource.flatMapToOrderedSet { src -> src.interfaces }
// These are all the super classes and interfaces in "this" module
val localClasses = codeSource.mapToOrderedSet { src -> src.className }
// These super classes and interfaces are not available from "this" module, so must come from dependencies.
val externalSupers = supers - localClasses
val externalInterfaces = interfaces - localClasses
val externals = externalSupers + externalInterfaces

externals
}

val androidResSource: List<AndroidResSource> by unsafeLazy {
sources.filterIsInstance<AndroidResSource>()
}
Expand Down
9 changes: 2 additions & 7 deletions src/main/kotlin/com/autonomousapps/tasks/ComputeUsagesTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package com.autonomousapps.tasks
import com.autonomousapps.graph.Graphs.parents
import com.autonomousapps.graph.Graphs.reachableNodes
import com.autonomousapps.graph.Graphs.root
import com.autonomousapps.internal.graph.supers.SuperClassGraphHolder
import com.autonomousapps.internal.graph.supers.SuperNode
import com.autonomousapps.internal.utils.*
import com.autonomousapps.model.Coordinates
Expand Down Expand Up @@ -122,8 +121,6 @@ private class GraphVisitor(
private val kapt: Boolean,
) : GraphViewVisitor {

private lateinit var superClassGraphHolder: SuperClassGraphHolder

val report: DependencyTraceReport get() = reportBuilder.build()

private val reportBuilder = DependencyTraceReport.Builder(
Expand All @@ -134,7 +131,6 @@ private class GraphVisitor(

override fun visit(dependency: Dependency, context: GraphViewVisitor.Context) {
val dependencyCoordinates = dependency.coordinates
superClassGraphHolder = SuperClassGraphHolder(context)

var isAnnotationProcessor = false
var isAnnotationProcessorCandidate = false
Expand Down Expand Up @@ -371,16 +367,15 @@ private class GraphVisitor(
}
}

// TODO(tsr): consider providing an opt-out or even an opt-in for this (very expensive) analysis.
private fun isForMissingSuperclass(
coordinates: Coordinates,
capability: BinaryClassCapability,
context: GraphViewVisitor.Context,
): Boolean {
val superGraph = superClassGraphHolder.superGraph
val superGraph = context.superGraph

// collect all the dependencies associated with external supers
val requiredExternalClasses = superClassGraphHolder.externals.asSequence()
val requiredExternalClasses = context.project.externalSupers.asSequence()
.flatMap { external -> superGraph.reachableNodes(false) { it.className == external } }
.mapNotNull { node ->
val deps = node.deps.filterToOrderedSet { dep ->
Expand Down
15 changes: 12 additions & 3 deletions src/main/kotlin/com/autonomousapps/visitor/GraphViewReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
package com.autonomousapps.visitor

import com.autonomousapps.internal.graph.supers.SuperClassGraphBuilder
import com.autonomousapps.internal.graph.supers.SuperNode
import com.autonomousapps.internal.unsafeLazy
import com.autonomousapps.model.DuplicateClass
import com.autonomousapps.model.declaration.internal.Declaration
import com.autonomousapps.model.internal.Dependency
import com.autonomousapps.model.internal.DependencyGraphView
import com.autonomousapps.model.DuplicateClass
import com.autonomousapps.model.internal.ProjectVariant
import com.autonomousapps.model.declaration.internal.Declaration
import com.google.common.graph.Graph

internal class GraphViewReader(
private val project: ProjectVariant,
Expand All @@ -30,4 +34,9 @@ internal class DefaultContext(
override val graph: DependencyGraphView,
override val declarations: Set<Declaration>,
override val duplicateClasses: Set<DuplicateClass>,
) : GraphViewVisitor.Context
) : GraphViewVisitor.Context {

override val superGraph: Graph<SuperNode> by unsafeLazy {
SuperClassGraphBuilder.of(dependencies)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// SPDX-License-Identifier: Apache-2.0
package com.autonomousapps.visitor

import com.autonomousapps.internal.graph.supers.SuperNode
import com.autonomousapps.model.internal.Dependency
import com.autonomousapps.model.internal.DependencyGraphView
import com.autonomousapps.model.DuplicateClass
import com.autonomousapps.model.internal.ProjectVariant
import com.autonomousapps.model.declaration.internal.Declaration
import com.google.common.graph.Graph

internal interface GraphViewVisitor {
fun visit(dependency: Dependency, context: Context)
Expand All @@ -17,5 +19,8 @@ internal interface GraphViewVisitor {
val graph: DependencyGraphView
val declarations: Set<Declaration>
val duplicateClasses: Set<DuplicateClass>

/** Graph from child classes up through super classes and interfaces, up to `java/lang/Object`. */
val superGraph: Graph<SuperNode>
}
}

0 comments on commit a56b5a9

Please sign in to comment.