Skip to content

Commit 0e0bba1

Browse files
authored
Merge branch 'golang:master' into master
2 parents a7be2b0 + 0abda08 commit 0e0bba1

File tree

180 files changed

+3652
-1177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+3652
-1177
lines changed

cmd/file2fuzz/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// output to stdout. If any position arguments are provided stdin is ignored
1414
// and the arguments are assumed to be input files to convert.
1515
//
16-
// The -o flag provides an path to write output files to. If only one positional
16+
// The -o flag provides a path to write output files to. If only one positional
1717
// argument is specified it may be a file path or an existing directory, if there are
1818
// multiple inputs specified it must be a directory. If a directory is provided
1919
// the name of the file will be the SHA-256 hash of its contents.

go/analysis/analysistest/analysistest.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
167167
act := result.Action
168168

169169
// file -> message -> edits
170+
// TODO(adonovan): this mapping assumes fix.Messages are unique across analyzers.
170171
fileEdits := make(map[*token.File]map[string][]diff.Edit)
171172
fileContents := make(map[*token.File][]byte)
172173

@@ -179,6 +180,8 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
179180
t.Errorf("missing Diagnostic.Category for SuggestedFix without TextEdits (gopls requires the category for the name of the fix command")
180181
}
181182

183+
// TODO(adonovan): factor in common with go/analysis/internal/checker.validateEdits.
184+
182185
for _, edit := range fix.TextEdits {
183186
start, end := edit.Pos, edit.End
184187
if !end.IsValid() {
@@ -275,7 +278,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
275278
}
276279
} else {
277280
// all suggested fixes are represented by a single file
278-
281+
// TODO(adonovan): fix: this makes no sense if len(fixes) > 1.
279282
var catchallEdits []diff.Edit
280283
for _, edits := range fixes {
281284
catchallEdits = append(catchallEdits, edits...)

go/analysis/checker/checker.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"go/types"
3636
"io"
3737
"log"
38+
"os"
3839
"reflect"
3940
"sort"
4041
"strings"
@@ -55,9 +56,10 @@ type Options struct {
5556
SanityCheck bool // check fact encoding is ok and deterministic
5657
FactLog io.Writer // if non-nil, log each exported fact to it
5758

58-
// TODO(adonovan): add ReadFile so that an Overlay specified
59+
// TODO(adonovan): expose ReadFile so that an Overlay specified
5960
// in the [packages.Config] can be communicated via
6061
// Pass.ReadFile to each Analyzer.
62+
readFile analysisinternal.ReadFileFunc
6163
}
6264

6365
// Graph holds the results of a round of analysis, including the graph
@@ -335,16 +337,26 @@ func (act *Action) execOnce() {
335337
TypeErrors: act.Package.TypeErrors,
336338
Module: module,
337339

338-
ResultOf: inputs,
339-
Report: func(d analysis.Diagnostic) { act.Diagnostics = append(act.Diagnostics, d) },
340+
ResultOf: inputs,
341+
Report: func(d analysis.Diagnostic) {
342+
// Assert that SuggestedFixes are well formed.
343+
if err := analysisinternal.ValidateFixes(act.Package.Fset, act.Analyzer, d.SuggestedFixes); err != nil {
344+
panic(err)
345+
}
346+
act.Diagnostics = append(act.Diagnostics, d)
347+
},
340348
ImportObjectFact: act.ObjectFact,
341349
ExportObjectFact: act.exportObjectFact,
342350
ImportPackageFact: act.PackageFact,
343351
ExportPackageFact: act.exportPackageFact,
344352
AllObjectFacts: act.AllObjectFacts,
345353
AllPackageFacts: act.AllPackageFacts,
346354
}
347-
pass.ReadFile = analysisinternal.MakeReadFile(pass)
355+
readFile := os.ReadFile
356+
if act.opts.readFile != nil {
357+
readFile = act.opts.readFile
358+
}
359+
pass.ReadFile = analysisinternal.CheckedReadFile(pass, readFile)
348360
act.pass = pass
349361

350362
act.Result, act.Err = func() (any, error) {

go/analysis/diagnostic.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ type RelatedInformation struct {
6565
// user can choose to apply to their code. Usually the SuggestedFix is
6666
// meant to fix the issue flagged by the diagnostic.
6767
//
68-
// The TextEdits must not overlap, nor contain edits for other packages.
68+
// The TextEdits must not overlap, nor contain edits for other
69+
// packages. Edits need not be totally ordered, but the order
70+
// determines how insertions at the same point will be applied.
6971
type SuggestedFix struct {
7072
// A verb phrase describing the fix, to be shown to
7173
// a user trying to decide whether to accept it.

go/analysis/internal/checker/checker.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"go/token"
2121
"io"
2222
"io/ioutil"
23+
2324
"log"
2425
"os"
2526
"runtime"
@@ -139,6 +140,9 @@ func Run(args []string, analyzers []*analysis.Analyzer) int {
139140
return 1
140141
}
141142

143+
// TODO(adonovan): simplify exit code logic by using a single
144+
// exit code variable and applying "code = max(code, X)" each
145+
// time an error of code X occurs.
142146
pkgsExitCode := 0
143147
// Print package and module errors regardless of RunDespiteErrors.
144148
// Do not exit if there are errors, yet.

go/analysis/internal/checker/checker_test.go

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525

2626
func TestApplyFixes(t *testing.T) {
2727
testenv.NeedsGoPackages(t)
28+
testenv.RedirectStderr(t) // associated checker.Run output with this test
2829

2930
files := map[string]string{
3031
"rename/test.go": `package rename
@@ -83,6 +84,7 @@ var otherAnalyzer = &analysis.Analyzer{ // like analyzer but with a different Na
8384
}
8485

8586
func run(pass *analysis.Pass) (interface{}, error) {
87+
// TODO(adonovan): replace this entangled test with something completely data-driven.
8688
const (
8789
from = "bar"
8890
to = "baz"
@@ -108,16 +110,46 @@ func run(pass *analysis.Pass) (interface{}, error) {
108110
}
109111
switch pass.Pkg.Name() {
110112
case conflict:
111-
edits = append(edits, []analysis.TextEdit{
112-
{Pos: ident.Pos() - 1, End: ident.End(), NewText: []byte(to)},
113-
{Pos: ident.Pos(), End: ident.End() - 1, NewText: []byte(to)},
114-
{Pos: ident.Pos(), End: ident.End(), NewText: []byte("lorem ipsum")},
115-
}...)
113+
// Conflicting edits are legal, so long as they appear in different fixes.
114+
pass.Report(analysis.Diagnostic{
115+
Pos: ident.Pos(),
116+
End: ident.End(),
117+
Message: msg,
118+
SuggestedFixes: []analysis.SuggestedFix{{
119+
Message: msg, TextEdits: []analysis.TextEdit{
120+
{Pos: ident.Pos() - 1, End: ident.End(), NewText: []byte(to)},
121+
},
122+
}},
123+
})
124+
pass.Report(analysis.Diagnostic{
125+
Pos: ident.Pos(),
126+
End: ident.End(),
127+
Message: msg,
128+
SuggestedFixes: []analysis.SuggestedFix{{
129+
Message: msg, TextEdits: []analysis.TextEdit{
130+
{Pos: ident.Pos(), End: ident.End() - 1, NewText: []byte(to)},
131+
},
132+
}},
133+
})
134+
pass.Report(analysis.Diagnostic{
135+
Pos: ident.Pos(),
136+
End: ident.End(),
137+
Message: msg,
138+
SuggestedFixes: []analysis.SuggestedFix{{
139+
Message: msg, TextEdits: []analysis.TextEdit{
140+
{Pos: ident.Pos(), End: ident.End(), NewText: []byte("lorem ipsum")},
141+
},
142+
}},
143+
})
144+
return
145+
116146
case duplicate:
147+
// Duplicate (non-insertion) edits are disallowed,
148+
// so this is a buggy analyzer, and validatedFixes should reject it.
117149
edits = append(edits, edits...)
118150
case other:
119151
if pass.Analyzer.Name == other {
120-
edits[0].Pos = edits[0].Pos + 1 // shift by one to mismatch analyzer and other
152+
edits[0].Pos++ // shift by one to mismatch analyzer and other
121153
}
122154
}
123155
pass.Report(analysis.Diagnostic{
@@ -133,6 +165,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
133165

134166
func TestRunDespiteErrors(t *testing.T) {
135167
testenv.NeedsGoPackages(t)
168+
testenv.RedirectStderr(t) // associate checker.Run output with this test
136169

137170
files := map[string]string{
138171
"rderr/test.go": `package rderr
@@ -360,4 +393,7 @@ hello from other
360393
if !ran {
361394
t.Error("analyzer did not run")
362395
}
396+
397+
// TODO(adonovan): test that fixes are applied to the
398+
// pass.ReadFile virtual file tree.
363399
}

0 commit comments

Comments
 (0)