// TestExampleSeparateAnalysis demonstrates the principle of separate // analysis, the distribution of units of type-checking and analysis // work across several processes, using serialized summaries to // communicate between them. // // It uses two different kinds of task, "manager" and "worker": // // - The manager computes the graph of package dependencies, and makes // a request to the worker for each package. It does not parse, // type-check, or analyze Go code. It is analogous "go vet". // // - The worker, which contains the Analyzers, reads each request, // loads, parses, and type-checks the files of one package, // applies all necessary analyzers to the package, then writes // its results to a file. It is a unitchecker-based driver, // analogous to the program specified by go vet -vettool= flag. // // In practice these would be separate executables, but for simplicity // of this example they are provided by one executable in two // different modes: the Example function is the manager, and the same // executable invoked with ENTRYPOINT=worker is the worker. // (See TestIntegration for how this happens.) // // Unfortunately this can't be a true Example because of the skip, // which requires a testing.T. func TestExampleSeparateAnalysis(t *testing.T) { … } // worker is the main entry point for a unitchecker-based driver // with only a single analyzer, for illustration. func worker() { … } func makeTypesImporter(cfg *unitchecker.Config, fset *token.FileSet) types.Importer { … } func exportTypes(cfg *unitchecker.Config, fset *token.FileSet, pkg *types.Package) error { … } type importerFunc … func (f importerFunc) Import(path string) (*types.Package, error) { … }