Dead Code Analysis

Builder can detect unused variables and functions in your R package with the -deadcode flag. This helps identify code that may be safe to remove or indicates potential bugs.

⚠️ Warning: this feature is vibe-coded to some extent and static analysis of R code is notoriously difficult given the capabilities of the language, these are the reasons this feature is not enabled by default. False positive may be reported.

Usage

builder -input srcr -output R -deadcode

When enabled, Builder performs a two-pass analysis after preprocessing:

  1. Pass 1: Collects all variable and function declarations across all files
  2. Pass 2: Marks variables and functions as used when they are referenced

After both passes, any declarations that were never referenced are reported as warnings.

Example

Input files:

# srcr/utils.R
helper_used <- function(x) {
  x + 1
}

helper_unused <- function(x) {
  x * 2
}
# srcr/main.R
result <- helper_used(5)
print(result)

Command:

builder -input srcr -output R -deadcode

Output:

[INFO] Running dead code analysis...
[WARNING] Unused function 'helper_unused' at line 2 in R/utils.R
[WARNING] Found 1 unused variable(s)/function(s)

Cross-File Detection

The analysis works across all files in your package. A function defined in one file and used in another will be correctly identified as used:

# File A: defines foo()
foo <- function() { 42 }

# File B: uses foo()
x <- foo()

In this case, foo is not flagged because it’s used in File B.

Nested Scopes

Builder respects R’s lexical scoping rules. Variables in nested functions can reference outer scopes:

outer <- function() {
  helper <- function(x) { x + 1 }  # Used below
  unused <- 42                      # Flagged as unused
  
  helper(10)
}

Exclusions

Certain names are automatically excluded from dead code detection:

These are typically package lifecycle functions or internal variables that may not have explicit callers in user code.

Limitations

Best Practices