Skip to content

A new task to build type usage report (ComputeTypeUsageTask).#1639

Open
Laimiux wants to merge 3 commits intoautonomousapps:mainfrom
Laimiux:laimonas/compute-type-usage-task
Open

A new task to build type usage report (ComputeTypeUsageTask).#1639
Laimiux wants to merge 3 commits intoautonomousapps:mainfrom
Laimiux:laimonas/compute-type-usage-task

Conversation

@Laimiux
Copy link

@Laimiux Laimiux commented Feb 10, 2026

Summary

A new task to build type usage report (#1637).

Introducing a new ComputeTypeUsageTask task. It generates type-usage.json reporting which types (classes) your code uses from each dependency. Designed for analyzing module dependency usage and complexity.

{
  "projectPath": ":app",
  "summary": {
    "totalTypes": 245,
    "totalFiles": 67,
    "internalTypes": 12,
    "projectDependencies": 3,
    "libraryDependencies": 18
  },
  "internal": {
    "com.example.MyClass": 5
  },
  "projectDependencies": {
    ":core": {
      "com.example.core.Utils": 2
    }
  },
  "libraryDependencies": {
    "org.apache.commons:commons-collections4": {
      "org.apache.commons.collections4.bag.HashBag": 3
    }
  }
}

Usage:

./gradlew computeTypeUsageMain

Output location:

build/reports/dependency-analysis/main/intermediates/type-usage.json

Configuration:

dependencyAnalysis {
  typeUsage {
    excludePackages("kotlin.jvm.internal")
    excludeTypes("kotlin.Unit")
    excludeRegex(".*_Factory$", ".*Companion$")
  }
}

Key design decisions:

  • Task runs on-demand only (not part of buildHealth or other critical paths)
  • Uses existing intermediate files (synthetic-project.json, exploded-jars.json.gz)
  • Tracks both annotation and non-annotation class usage
  • Sensible defaults exclude common generated/internal types

Laimiux and others added 2 commits February 10, 2026 12:33
Improves API clarity by making the property name match the excludePackages
and excludeTypes pattern. Also removes unnecessary dependsOn from
computeAdviceTask - the type usage task should only run when explicitly
invoked, not as part of buildHealth.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
public abstract class AbstractExtension {
ctor @javax.inject.Inject public AbstractExtension(org.gradle.api.model.ObjectFactory objects, org.gradle.api.invocation.Gradle gradle);
method public final org.gradle.api.file.RegularFileProperty adviceOutput();
method public final org.gradle.api.file.RegularFileProperty typeUsageOutput();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide guidance here - I've added this, but I'm not sure what should actually be included here.


import static com.autonomousapps.kit.gradle.dependencies.Dependencies.*

final class TypeUsageProject extends AbstractProject {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a functional test for this task (tried to follow project conventions)


import static com.autonomousapps.kit.gradle.dependencies.Dependencies.*

final class TypeUsageWithFiltersProject extends AbstractProject {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another functional test for the new task (tried to follow project conventions)

import static com.autonomousapps.utils.Runner.build
import static com.google.common.truth.Truth.assertThat

final class TypeUsageSpec extends AbstractJvmSpec {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following project convention to test computeTypeUsageMain task

// Excluded specific types
internal val excludedTypes: SetProperty<String> = objects.setProperty(String::class.java)
.convention(setOf(
"kotlin.Unit",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious if we should provide certain defaults here for exclusion out of the report

public fun getAllLibsVersionsTomlPath(): String = "$ROOT_DIR/allLibs.versions.toml"
public fun getResolvedDependenciesReport(): String = "$ROOT_DIR/resolved-dependencies-report.txt"
public fun getResolvedVersionsTomlPath(): String = "$ROOT_DIR/resolvedAllLibs.versions.toml"
public fun getTypeUsagePath(variantName: String = "main"): String = "$ROOT_DIR/$variantName/intermediates/type-usage.json"
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: it should probably not live in intermediates

* enabling coupling analysis and complexity metrics.
*/
@JsonClass(generateAdapter = false)
public data class ProjectTypeUsage(
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Json serialized models for type usage task.

}

// Computes type-level usage statistics for complexity analysis.
val computeTypeUsageTask = tasks.register("computeTypeUsage$taskNameSuffix", ComputeTypeUsageTask::class.java) { t ->
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New task registration

@@ -0,0 +1,94 @@
// Copyright (c) 2025. Tony Robalik.
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use 2025 or 2026?


// Count usage per class per dependency (both non-annotation and annotation classes)
project.codeSource.forEach { source ->
val allUsedClasses = source.usedNonAnnotationClasses + source.usedAnnotationClasses
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we include usedAnnotationClasses ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant