From 5cec639030af3a6ada2732d9bfa1d3731ed55106 Mon Sep 17 00:00:00 2001 From: Michael Matloob Date: Mon, 29 Apr 2019 16:34:09 -0400 Subject: [PATCH] go/analysis: proposed fact enumeration API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updates golang/go#29616 Change-Id: Ibaf10526ea35f06b853ad55451a50750c764fab4 Reviewed-on: https://go-review.googlesource.com/c/tools/+/174379 Run-TryBot: Michael Matloob Reviewed-by: Daniel Martí Reviewed-by: Ian Cottrell TryBot-Result: Gobot Gobot --- go/analysis/analysis.go | 22 ++++++++++++++++++++++ go/analysis/internal/checker/checker.go | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/go/analysis/analysis.go b/go/analysis/analysis.go index 4d8a6e5e..8eb73162 100644 --- a/go/analysis/analysis.go +++ b/go/analysis/analysis.go @@ -128,10 +128,32 @@ type Pass struct { // See comments for ExportObjectFact. ExportPackageFact func(fact Fact) + // AllPackageFacts returns a new slice containing all package facts in unspecified order. + // WARNING: This is an experimental API and may change in the future. + AllPackageFacts func() []PackageFact + + // AllObjectFacts returns a new slice containing all object facts in unspecified order. + // WARNING: This is an experimental API and may change in the future. + AllObjectFacts func() []ObjectFact + /* Further fields may be added in future. */ // For example, suggested or applied refactorings. } +// PackageFact is a package together with an associated fact. +// WARNING: This is an experimental API and may change in the future. +type PackageFact struct { + Package *types.Package + Fact Fact +} + +// ObjectFact is an object together with an associated fact. +// WARNING: This is an experimental API and may change in the future. +type ObjectFact struct { + Object types.Object + Fact Fact +} + // Reportf is a helper function that reports a Diagnostic using the // specified position and formatted error message. func (pass *Pass) Reportf(pos token.Pos, format string, args ...interface{}) { diff --git a/go/analysis/internal/checker/checker.go b/go/analysis/internal/checker/checker.go index bd8474c9..4cade777 100644 --- a/go/analysis/internal/checker/checker.go +++ b/go/analysis/internal/checker/checker.go @@ -503,6 +503,8 @@ func (act *action) execOnce() { ExportObjectFact: act.exportObjectFact, ImportPackageFact: act.importPackageFact, ExportPackageFact: act.exportPackageFact, + AllObjectFacts: act.allObjectFacts, + AllPackageFacts: act.allPackageFacts, } act.pass = pass @@ -666,6 +668,15 @@ func (act *action) exportObjectFact(obj types.Object, fact analysis.Fact) { } } +// allObjectFacts implements Pass.AllObjectFacts. +func (act *action) allObjectFacts() []analysis.ObjectFact { + facts := make([]analysis.ObjectFact, 0, len(act.objectFacts)) + for k := range act.objectFacts { + facts = append(facts, analysis.ObjectFact{k.obj, act.objectFacts[k]}) + } + return facts +} + // importPackageFact implements Pass.ImportPackageFact. // Given a non-nil pointer ptr of type *T, where *T satisfies Fact, // fact copies the fact value to *ptr. @@ -703,4 +714,13 @@ func factType(fact analysis.Fact) reflect.Type { return t } +// allObjectFacts implements Pass.AllObjectFacts. +func (act *action) allPackageFacts() []analysis.PackageFact { + facts := make([]analysis.PackageFact, 0, len(act.packageFacts)) + for k := range act.packageFacts { + facts = append(facts, analysis.PackageFact{k.pkg, act.packageFacts[k]}) + } + return facts +} + func dbg(b byte) bool { return strings.IndexByte(Debug, b) >= 0 }