deadfunc

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2026 License: MIT Imports: 8 Imported by: 0

README

deadfunc

CI Go Report Card Go Reference

A Go linter that detects functions declared but never called or referenced in production code. Test files (_test.go) are excluded from both declaration scanning and usage tracking — so a function used only in tests is flagged as dead code.

What it catches

Scenario Flagged?
Function declared, never called anywhere Yes
Function declared, called only in _test.go Yes
Function declared, called in production code No
Function passed as a value (callback) No
init() / main() No (entry points)
Methods implementing known interfaces (error, fmt.Stringer, json.Marshaler, io.Reader, etc.) No
Methods implementing package-local interfaces No
Exported functions (default mode) No (use -exported flag)
Code in generated files (// Code generated) No

Install

Standalone CLI
go install github.com/OrlovEvgeny/deadfunc/cmd/deadfunc@latest

Add to your .custom-gcl.yml:

version: v1.64.0
plugins:
  - module: "github.com/OrlovEvgeny/deadfunc"
    import: "github.com/OrlovEvgeny/deadfunc/plugin"
    version: latest

Build your custom binary:

custom-gcl

Enable in .golangci.yml:

linters:
  enable:
    - deadfunc
Legacy .so plugin
go build -buildmode=plugin -o deadfunc.so ./plugin

Add to .golangci.yml:

linters-settings:
  custom:
    deadfunc:
      path: ./deadfunc.so
      description: "Reports unused production functions"
      original-url: github.com/OrlovEvgeny/deadfunc

Usage

# Check unexported functions only (safe default)
deadfunc ./...

# Also check exported functions (use for binaries / main packages)
deadfunc -exported ./...

# Skip method checking
deadfunc -methods=false ./...

# Include generated files
deadfunc -skip-generated=false ./...

Flags

Flag Default Description
-exported false Also check exported functions. Risky for library packages since they may be used by external consumers.
-methods true Check methods, not just top-level functions.
-skip-generated true Skip files with // Code generated ... DO NOT EDIT header.

How it works

  1. Collect declarations — walks all *ast.FuncDecl nodes in non-test files, building a set of types.Object identifiers.
  2. Collect usage — walks all *ast.Ident and *ast.SelectorExpr nodes in non-test files, resolving them to types.Object via TypesInfo.Uses and TypesInfo.Selections.
  3. Diff — any declared function whose types.Object was never seen in the usage pass is reported.

Using types.Object identity (not string names) means it correctly handles shadowing, different packages, and method sets.

Limitations

  • Cross-package analysis: the linter works per-package. A function in package A used only by package B will NOT be flagged (the Go type checker resolves cross-package references). However, go vet-style tools run per-package, so this is the expected behavior.
  • Reflection: functions called only via reflect will be falsely flagged.
  • go:linkname: functions referenced via //go:linkname will be falsely flagged.
  • Interface implementations: a heuristic is used — the linter checks package-scoped interfaces + a set of well-known stdlib interfaces. Exotic interfaces from dependencies may be missed.

Nolint

Use the standard //nolint:deadfunc directive (if using golangci-lint) or add a comment:

//nolint:deadfunc // used via reflection
func myReflectionHandler() {}

License

MIT

Documentation

Overview

Package deadfunc implements a Go linter that detects functions declared but never used in production code (test files are excluded from both declaration and usage analysis).

Index

Constants

This section is empty.

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:     "deadfunc",
	Doc:      "reports functions that are declared but never called/referenced in production code (tests excluded)",
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

Analyzer is the deadfunc analysis.Analyzer.

Functions

This section is empty.

Types

type Config

type Config struct {
	// IncludeExported checks exported functions too.
	// By default only unexported functions are checked, because exported
	// functions in library packages may be used by external consumers.
	IncludeExported bool

	// IncludeMethods checks methods (not just top-level functions).
	IncludeMethods bool

	// SkipGenerated skips files with "// Code generated" header.
	SkipGenerated bool
}

Config holds linter configuration.

Directories

Path Synopsis
cmd
deadfunc command
Command deadfunc runs the deadfunc analyzer.
Command deadfunc runs the deadfunc analyzer.
Package plugin provides golangci-lint module plugin integration for deadfunc.
Package plugin provides golangci-lint module plugin integration for deadfunc.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL