Skip to content

Commit

Permalink
Merge branch 'golang:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
GSmithApps authored Feb 4, 2025
2 parents a7be2b0 + 0abda08 commit 0e0bba1
Show file tree
Hide file tree
Showing 180 changed files with 3,652 additions and 1,177 deletions.
2 changes: 1 addition & 1 deletion cmd/file2fuzz/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// output to stdout. If any position arguments are provided stdin is ignored
// and the arguments are assumed to be input files to convert.
//
// The -o flag provides an path to write output files to. If only one positional
// The -o flag provides a path to write output files to. If only one positional
// argument is specified it may be a file path or an existing directory, if there are
// multiple inputs specified it must be a directory. If a directory is provided
// the name of the file will be the SHA-256 hash of its contents.
Expand Down
5 changes: 4 additions & 1 deletion go/analysis/analysistest/analysistest.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
act := result.Action

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

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

// TODO(adonovan): factor in common with go/analysis/internal/checker.validateEdits.

for _, edit := range fix.TextEdits {
start, end := edit.Pos, edit.End
if !end.IsValid() {
Expand Down Expand Up @@ -275,7 +278,7 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
}
} else {
// all suggested fixes are represented by a single file

// TODO(adonovan): fix: this makes no sense if len(fixes) > 1.
var catchallEdits []diff.Edit
for _, edits := range fixes {
catchallEdits = append(catchallEdits, edits...)
Expand Down
20 changes: 16 additions & 4 deletions go/analysis/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
"go/types"
"io"
"log"
"os"
"reflect"
"sort"
"strings"
Expand All @@ -55,9 +56,10 @@ type Options struct {
SanityCheck bool // check fact encoding is ok and deterministic
FactLog io.Writer // if non-nil, log each exported fact to it

// TODO(adonovan): add ReadFile so that an Overlay specified
// TODO(adonovan): expose ReadFile so that an Overlay specified
// in the [packages.Config] can be communicated via
// Pass.ReadFile to each Analyzer.
readFile analysisinternal.ReadFileFunc
}

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

ResultOf: inputs,
Report: func(d analysis.Diagnostic) { act.Diagnostics = append(act.Diagnostics, d) },
ResultOf: inputs,
Report: func(d analysis.Diagnostic) {
// Assert that SuggestedFixes are well formed.
if err := analysisinternal.ValidateFixes(act.Package.Fset, act.Analyzer, d.SuggestedFixes); err != nil {
panic(err)
}
act.Diagnostics = append(act.Diagnostics, d)
},
ImportObjectFact: act.ObjectFact,
ExportObjectFact: act.exportObjectFact,
ImportPackageFact: act.PackageFact,
ExportPackageFact: act.exportPackageFact,
AllObjectFacts: act.AllObjectFacts,
AllPackageFacts: act.AllPackageFacts,
}
pass.ReadFile = analysisinternal.MakeReadFile(pass)
readFile := os.ReadFile
if act.opts.readFile != nil {
readFile = act.opts.readFile
}
pass.ReadFile = analysisinternal.CheckedReadFile(pass, readFile)
act.pass = pass

act.Result, act.Err = func() (any, error) {
Expand Down
4 changes: 3 additions & 1 deletion go/analysis/diagnostic.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@ type RelatedInformation struct {
// user can choose to apply to their code. Usually the SuggestedFix is
// meant to fix the issue flagged by the diagnostic.
//
// The TextEdits must not overlap, nor contain edits for other packages.
// The TextEdits must not overlap, nor contain edits for other
// packages. Edits need not be totally ordered, but the order
// determines how insertions at the same point will be applied.
type SuggestedFix struct {
// A verb phrase describing the fix, to be shown to
// a user trying to decide whether to accept it.
Expand Down
4 changes: 4 additions & 0 deletions go/analysis/internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"go/token"
"io"
"io/ioutil"

"log"
"os"
"runtime"
Expand Down Expand Up @@ -139,6 +140,9 @@ func Run(args []string, analyzers []*analysis.Analyzer) int {
return 1
}

// TODO(adonovan): simplify exit code logic by using a single
// exit code variable and applying "code = max(code, X)" each
// time an error of code X occurs.
pkgsExitCode := 0
// Print package and module errors regardless of RunDespiteErrors.
// Do not exit if there are errors, yet.
Expand Down
48 changes: 42 additions & 6 deletions go/analysis/internal/checker/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

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

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

func run(pass *analysis.Pass) (interface{}, error) {
// TODO(adonovan): replace this entangled test with something completely data-driven.
const (
from = "bar"
to = "baz"
Expand All @@ -108,16 +110,46 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
switch pass.Pkg.Name() {
case conflict:
edits = append(edits, []analysis.TextEdit{
{Pos: ident.Pos() - 1, End: ident.End(), NewText: []byte(to)},
{Pos: ident.Pos(), End: ident.End() - 1, NewText: []byte(to)},
{Pos: ident.Pos(), End: ident.End(), NewText: []byte("lorem ipsum")},
}...)
// Conflicting edits are legal, so long as they appear in different fixes.
pass.Report(analysis.Diagnostic{
Pos: ident.Pos(),
End: ident.End(),
Message: msg,
SuggestedFixes: []analysis.SuggestedFix{{
Message: msg, TextEdits: []analysis.TextEdit{
{Pos: ident.Pos() - 1, End: ident.End(), NewText: []byte(to)},
},
}},
})
pass.Report(analysis.Diagnostic{
Pos: ident.Pos(),
End: ident.End(),
Message: msg,
SuggestedFixes: []analysis.SuggestedFix{{
Message: msg, TextEdits: []analysis.TextEdit{
{Pos: ident.Pos(), End: ident.End() - 1, NewText: []byte(to)},
},
}},
})
pass.Report(analysis.Diagnostic{
Pos: ident.Pos(),
End: ident.End(),
Message: msg,
SuggestedFixes: []analysis.SuggestedFix{{
Message: msg, TextEdits: []analysis.TextEdit{
{Pos: ident.Pos(), End: ident.End(), NewText: []byte("lorem ipsum")},
},
}},
})
return

case duplicate:
// Duplicate (non-insertion) edits are disallowed,
// so this is a buggy analyzer, and validatedFixes should reject it.
edits = append(edits, edits...)
case other:
if pass.Analyzer.Name == other {
edits[0].Pos = edits[0].Pos + 1 // shift by one to mismatch analyzer and other
edits[0].Pos++ // shift by one to mismatch analyzer and other
}
}
pass.Report(analysis.Diagnostic{
Expand All @@ -133,6 +165,7 @@ func run(pass *analysis.Pass) (interface{}, error) {

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

files := map[string]string{
"rderr/test.go": `package rderr
Expand Down Expand Up @@ -360,4 +393,7 @@ hello from other
if !ran {
t.Error("analyzer did not run")
}

// TODO(adonovan): test that fixes are applied to the
// pass.ReadFile virtual file tree.
}
Loading

0 comments on commit 0e0bba1

Please sign in to comment.