blob: fea596b9eed862964eb6023590efcc84d56027f3 [file] [edit]
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package inline defines an analyzer that inlines calls to functions
and uses of constants marked with a "//go:fix inline" directive.
# Analyzer inline
inline: apply fixes based on 'go:fix inline' comment directives
The inline analyzer inlines functions, constants, and type aliases
that are marked for inlining.
Use this command to apply (just) inline fixes en masse:
$ go fix -inline ./...
## Functions
Given a function that is marked for inlining, like this one:
//go:fix inline
func Square(x int) int { return Pow(x, 2) }
this analyzer will recommend that calls to the function elsewhere, in the same
or other packages, should be inlined.
Inlining can be used to move off of a deprecated function:
// Deprecated: prefer Pow(x, 2).
//go:fix inline
func Square(x int) int { return Pow(x, 2) }
It can also be used to move off of an obsolete package,
as when the import path has changed or a higher major version is available:
package pkg
import pkg2 "pkg/v2"
//go:fix inline
func F() { pkg2.F(nil) }
Replacing a call pkg.F() by pkg2.F(nil) can have no effect on the program,
so this mechanism provides a low-risk way to update large numbers of calls.
We recommend, where possible, expressing the old API in terms of the new one
to enable automatic migration.
The inliner takes care to avoid behavior changes, even subtle ones,
such as changes to the order in which argument expressions are
evaluated. When it cannot safely eliminate all parameter variables,
it may introduce a "binding declaration" of the form
var params = args
to evaluate argument expressions in the correct order and bind them to
parameter variables. Since the resulting code transformation may be
stylistically suboptimal, such inlinings may be disabled by specifying
the -inline.allow_binding_decl=false flag to the analyzer driver.
(In cases where it is not safe to "reduce" a call—that is, to replace
a call f(x) by the body of function f, suitably substituted—the
inliner machinery is capable of replacing f by a function literal,
func(){...}(). However, the inline analyzer discards all such
"literalizations" unconditionally, again on grounds of style.)
## Constants
Given a constant that is marked for inlining, like this one:
//go:fix inline
const Ptr = Pointer
this analyzer will recommend that uses of Ptr should be replaced with Pointer.
As with functions, inlining can be used to replace deprecated constants and
constants in obsolete packages.
A constant definition can be marked for inlining only if it refers to another
named constant.
The "//go:fix inline" comment must appear before a single const declaration on its own,
as above; before a const declaration that is part of a group, as in this case:
const (
C = 1
//go:fix inline
Ptr = Pointer
)
or before a group, applying to every constant in the group:
//go:fix inline
const (
Ptr = Pointer
Val = Value
)
## Type aliases
Similar to named constants, a type alias can also be marked for inlining:
//go:fix inline
type A = newpkg.A
The analyzer will replace all references to the annotated type
(A) by the type on the right-hand side of the declaration (newpkg.A).
## Tests
A use of a function, named constant, or type alias X from its
dedicated test (TestX), is not inlined, since the purpose of the test
is to exercise X itself, even if it is deprecated and other uses of it
should be inlined.
This applies to benchmarks and examples too, and follows the usual
conventions of test function naming.
Similarly, if the symbol X is declared in a file named foo.go, any use
of it within a file named foo_test.go will also not be inlined.
# Analyzer gofixdirective
gofixdirective: validate uses of //go:fix comment directives
The gofixdirective analyzer checks "//go:fix inline" directives for correctness.
See the documentation for the gofix analyzer for more about "/go:fix inline".
*/
package inline