Skip to main content
Codegen pre-computes dependencies and usages for all symbols in the codebase, enabling constant-time queries for these relationships.

Overview

Codegen provides two main ways to track relationships between symbols: Dependencies and usages are inverses of each other. For example, given the following input code:
The following assertions will hold in the Codegen API:
If A depends on B, then B is used by A. This relationship is tracked in both directions, allowing you to navigate the codebase from either perspective.
  • MyClass.dependencies answers the question: “which symbols in the codebase does MyClass depend on?”
  • BaseClass.usages answers the question: “which symbols in the codebase use BaseClass?”

Usage Types

Both APIs use the UsageType enum to specify different kinds of relationships:

DIRECT Usage

A direct usage occurs when a symbol is used in the same file where it’s defined, without going through any imports or attribute access.

CHAINED Usage

A chained usage occurs when a symbol is accessed through module or object attribute access, using dot notation.

INDIRECT Usage

An indirect usage happens when a symbol is used through a non-aliased import statement.

ALIASED Usage

An aliased usage occurs when a symbol is used through an import with an alias.

Dependencies API

The dependencies API lets you find what symbols a given symbol depends on.

Basic Usage

Combining Usage Types

You can combine usage types using the bitwise OR operator:

Common Patterns

  1. Finding dead code (symbols with no usages):
See Deleting Dead Code to learn more about finding unused code.
  1. Finding all imports that a symbol uses:

Traversing the Dependency Graph

Sometimes you need to analyze not just direct dependencies, but the entire dependency graph up to a certain depth. The dependencies method allows you to traverse the dependency graph and collect all dependencies up to a specified depth level.

Basic Usage

The method returns a dictionary mapping each symbol to its list of direct dependencies. This makes it easy to analyze the dependency structure:

Example: Analyzing Class Inheritance

Here’s an example of using dependencies to analyze a class inheritance chain:

Handling Cyclic Dependencies

The method properly handles cyclic dependencies in the codebase:
The max_depth parameter helps prevent excessive recursion in large codebases or when there are cycles in the dependency graph.