Skip to content

Commit 62e0536

Browse files
committed
chore: isolate code from x/tools
1 parent a7c5baf commit 62e0536

File tree

2 files changed

+94
-93
lines changed

2 files changed

+94
-93
lines changed

pkg/goanalysis/runner_action.go

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
package goanalysis
22

33
import (
4-
"errors"
54
"fmt"
65
"go/types"
76
"reflect"
87
"runtime/debug"
9-
"time"
108

119
"golang.org/x/tools/go/analysis"
1210
"golang.org/x/tools/go/packages"
1311

1412
"github.com/golangci/golangci-lint/internal/errorutil"
15-
"github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors"
1613
)
1714

1815
type actionAllocator struct {
@@ -89,96 +86,6 @@ func (act *action) analyzeSafe() {
8986
act.r.sw.TrackStage(act.a.Name, act.analyze)
9087
}
9188

92-
func (act *action) analyze() {
93-
defer close(act.analysisDoneCh) // unblock actions depending on this action
94-
95-
if !act.needAnalyzeSource {
96-
return
97-
}
98-
99-
defer func(now time.Time) {
100-
analyzeDebugf("go/analysis: %s: %s: analyzed package %q in %s", act.r.prefix, act.a.Name, act.pkg.Name, time.Since(now))
101-
}(time.Now())
102-
103-
// Report an error if any dependency failures.
104-
var depErrors error
105-
for _, dep := range act.deps {
106-
if dep.err == nil {
107-
continue
108-
}
109-
110-
depErrors = errors.Join(depErrors, errors.Unwrap(dep.err))
111-
}
112-
if depErrors != nil {
113-
act.err = fmt.Errorf("failed prerequisites: %w", depErrors)
114-
return
115-
}
116-
117-
// Plumb the output values of the dependencies
118-
// into the inputs of this action. Also facts.
119-
inputs := make(map[*analysis.Analyzer]any)
120-
startedAt := time.Now()
121-
for _, dep := range act.deps {
122-
if dep.pkg == act.pkg {
123-
// Same package, different analysis (horizontal edge):
124-
// in-memory outputs of prerequisite analyzers
125-
// become inputs to this analysis pass.
126-
inputs[dep.a] = dep.result
127-
} else if dep.a == act.a { // (always true)
128-
// Same analysis, different package (vertical edge):
129-
// serialized facts produced by prerequisite analysis
130-
// become available to this analysis pass.
131-
inheritFacts(act, dep)
132-
}
133-
}
134-
factsDebugf("%s: Inherited facts in %s", act, time.Since(startedAt))
135-
136-
// Run the analysis.
137-
pass := &analysis.Pass{
138-
Analyzer: act.a,
139-
Fset: act.pkg.Fset,
140-
Files: act.pkg.Syntax,
141-
OtherFiles: act.pkg.OtherFiles,
142-
Pkg: act.pkg.Types,
143-
TypesInfo: act.pkg.TypesInfo,
144-
TypesSizes: act.pkg.TypesSizes,
145-
ResultOf: inputs,
146-
Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
147-
ImportObjectFact: act.importObjectFact,
148-
ExportObjectFact: act.exportObjectFact,
149-
ImportPackageFact: act.importPackageFact,
150-
ExportPackageFact: act.exportPackageFact,
151-
AllObjectFacts: act.allObjectFacts,
152-
AllPackageFacts: act.allPackageFacts,
153-
}
154-
act.pass = pass
155-
act.r.passToPkgGuard.Lock()
156-
act.r.passToPkg[pass] = act.pkg
157-
act.r.passToPkgGuard.Unlock()
158-
159-
if act.pkg.IllTyped {
160-
// It looks like there should be !pass.Analyzer.RunDespiteErrors
161-
// but govet's cgocall crashes on it. Govet itself contains !pass.Analyzer.RunDespiteErrors condition here,
162-
// but it exits before it if packages.Load have failed.
163-
act.err = fmt.Errorf("analysis skipped: %w", &pkgerrors.IllTypedError{Pkg: act.pkg})
164-
} else {
165-
startedAt = time.Now()
166-
act.result, act.err = pass.Analyzer.Run(pass)
167-
analyzedIn := time.Since(startedAt)
168-
if analyzedIn > time.Millisecond*10 {
169-
debugf("%s: run analyzer in %s", act, analyzedIn)
170-
}
171-
}
172-
173-
// disallow calls after Run
174-
pass.ExportObjectFact = nil
175-
pass.ExportPackageFact = nil
176-
177-
if err := act.persistFactsToCache(); err != nil {
178-
act.r.log.Warnf("Failed to persist facts to cache: %s", err)
179-
}
180-
}
181-
18289
// importPackageFact implements Pass.ImportPackageFact.
18390
// Given a non-nil pointer ptr of type *T, where *T satisfies Fact,
18491
// fact copies the fact value to *ptr.

pkg/goanalysis/runner_base.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,107 @@ package goanalysis
1010
import (
1111
"bytes"
1212
"encoding/gob"
13+
"errors"
1314
"fmt"
1415
"go/types"
1516
"reflect"
17+
"time"
1618

19+
"github.com/golangci/golangci-lint/pkg/goanalysis/pkgerrors"
1720
"golang.org/x/tools/go/analysis"
1821
)
1922

23+
// NOTE(ldez) altered version of `func (act *action) execOnce()`.
24+
func (act *action) analyze() {
25+
defer close(act.analysisDoneCh) // unblock actions depending on this action
26+
27+
if !act.needAnalyzeSource {
28+
return
29+
}
30+
31+
defer func(now time.Time) {
32+
analyzeDebugf("go/analysis: %s: %s: analyzed package %q in %s", act.r.prefix, act.a.Name, act.pkg.Name, time.Since(now))
33+
}(time.Now())
34+
35+
// Report an error if any dependency failures.
36+
var depErrors error
37+
for _, dep := range act.deps {
38+
if dep.err == nil {
39+
continue
40+
}
41+
42+
depErrors = errors.Join(depErrors, errors.Unwrap(dep.err))
43+
}
44+
if depErrors != nil {
45+
act.err = fmt.Errorf("failed prerequisites: %w", depErrors)
46+
return
47+
}
48+
49+
// Plumb the output values of the dependencies
50+
// into the inputs of this action. Also facts.
51+
inputs := make(map[*analysis.Analyzer]any)
52+
startedAt := time.Now()
53+
for _, dep := range act.deps {
54+
if dep.pkg == act.pkg {
55+
// Same package, different analysis (horizontal edge):
56+
// in-memory outputs of prerequisite analyzers
57+
// become inputs to this analysis pass.
58+
inputs[dep.a] = dep.result
59+
} else if dep.a == act.a { // (always true)
60+
// Same analysis, different package (vertical edge):
61+
// serialized facts produced by prerequisite analysis
62+
// become available to this analysis pass.
63+
inheritFacts(act, dep)
64+
}
65+
}
66+
factsDebugf("%s: Inherited facts in %s", act, time.Since(startedAt))
67+
68+
// Run the analysis.
69+
pass := &analysis.Pass{
70+
Analyzer: act.a,
71+
Fset: act.pkg.Fset,
72+
Files: act.pkg.Syntax,
73+
OtherFiles: act.pkg.OtherFiles,
74+
Pkg: act.pkg.Types,
75+
TypesInfo: act.pkg.TypesInfo,
76+
TypesSizes: act.pkg.TypesSizes,
77+
ResultOf: inputs,
78+
Report: func(d analysis.Diagnostic) { act.diagnostics = append(act.diagnostics, d) },
79+
ImportObjectFact: act.importObjectFact,
80+
ExportObjectFact: act.exportObjectFact,
81+
ImportPackageFact: act.importPackageFact,
82+
ExportPackageFact: act.exportPackageFact,
83+
AllObjectFacts: act.allObjectFacts,
84+
AllPackageFacts: act.allPackageFacts,
85+
}
86+
act.pass = pass
87+
act.r.passToPkgGuard.Lock()
88+
act.r.passToPkg[pass] = act.pkg
89+
act.r.passToPkgGuard.Unlock()
90+
91+
if act.pkg.IllTyped {
92+
// It looks like there should be !pass.Analyzer.RunDespiteErrors
93+
// but govet's cgocall crashes on it. Govet itself contains !pass.Analyzer.RunDespiteErrors condition here,
94+
// but it exits before it if packages.Load have failed.
95+
act.err = fmt.Errorf("analysis skipped: %w", &pkgerrors.IllTypedError{Pkg: act.pkg})
96+
} else {
97+
startedAt = time.Now()
98+
act.result, act.err = pass.Analyzer.Run(pass)
99+
analyzedIn := time.Since(startedAt)
100+
if analyzedIn > time.Millisecond*10 {
101+
debugf("%s: run analyzer in %s", act, analyzedIn)
102+
}
103+
}
104+
105+
// disallow calls after Run
106+
pass.ExportObjectFact = nil
107+
pass.ExportPackageFact = nil
108+
109+
if err := act.persistFactsToCache(); err != nil {
110+
act.r.log.Warnf("Failed to persist facts to cache: %s", err)
111+
}
112+
}
113+
20114
// NOTE(ldez) altered: logger; serialize.
21115
// inheritFacts populates act.facts with
22116
// those it obtains from its dependency, dep.

0 commit comments

Comments
 (0)