I want to create an analysis.Analyzer
and define a run
function on it that runs once per all the codebase, and not once per package.
If I check the documentation of the Run field, I see:
// Run applies the analyzer to a package.
but in my case I want that it runs once, not once per package. I declared my Analyzer
as:
a := &analysis.Analyzer{
Name: "mylinter",
Doc: "my documentation.",
Run: run,
Requires: []*analysis.Analyzer{inspect.Analyzer},
}
...
func run(pass *analysis.Pass) (any, error) {
...
// here I need all the structs declared in the whole codebase
// because I want to do some checks when those structs are instantiated in other packages.
}
One thing I have tried, it's to keep the state after every call to run
. In my case I need to keep all the stuct declarations, so on each call to run I am storing the structs declared in that package, and then performing the lint operations. But this is not working, because the results depends on what packages are processed first.
So, ideally, I need to get all the structs declaration (node ast.TypeSpec
), and then check the struct instantiation with all the info of the struct declaration.
The Analyzer
just statically describes an analysis function to a driver, it does not run on anything.
What you are concerned with is that the analysis driver runs a single unit of work per package, a Pass.
If you want to communicate over packages, you need to use Facts, see also the documentation of Analyzer
:
FactTypes
establishes a "vertical" dependency between analysis passes (same analyzer, different packages).