Skip to content

Commit f3da893

Browse files
committed
[gopls-release-branch.0.6] all: merge master into gopls-release-branch.0.6
11e8f6b internal/lsp: refactor codeAction 1523bb4 internal/lsp: fix time.Duration hover name check bcb2d7b internal/lsp: fix bad completion for variadic functions 7ee2955 internal/lsp/cache: refactor and improve go get quick fixes 1e524e2 internal/lsp/source: add the nilness analyzer d34cf35 internal/lsp/source: return nil for foldingRange in case of parse error c5f5f4b gopls/doc: clarify how to set remote.listen.timeout 3e1cb95 internal/lsp/source: correct workspace symbol logic for unpacking receivers 397283d internal/lsp/protocol/typescript: fix lint errors in .ts code d19d8cf internal/lsp/protocol/typecript: fix type merging 50ca8d0 all: recognize new error from go command when no go.mod is found 2cde57b internal/lsp: remove redundant didChange notifications 376db57 internal/lsp: use pre-existing quick fixes for analysis diagnostics 144d5ce internal/lsp: run type error analyzers as part of diagnostics 24439e3 internal/lsp/source: eliminate GetTypeCheckDiagnostics dafbee5 internal/lsp: show human-readable const time.Duration as a comment 9c452d8 internal/lsp/cache: don't rely on related diagnostics if unsupported 2ac05c8 internal/lsp: key GC details off package ID 303d8bb gopls/internal/hooks: compile URL regexp once 94327d3 internal/lsp/cache: show type errors on parse errors in other files 16b2c87 gopls/internal/regtest: add a failing test for issue 44736 7800253 internal/lsp/cache: split up sourceDiagnostics 47985cf internal/lsp/cache: refactor Go file parsing 6422c5c internal/lsp/cache: invalidate metadata on magic comment changes f9c628b gopls/internal/regtest: add test for bad embed rules 89a9cb6 internal/lsp/cache: parse filenames from go list errors correctly eb48d3f internal/lsp/cache: refactor diagnostic suppression 7a079fc internal/lsp/cache: fix related error processing f5a4005 cmd/eg: don't do rewrites within the template file itself 28e7a3b cmd/eg: use go/packages 54dc8c5 playground: remove /share registration, add Proxy 24aca17 cmd/guru: adjust describe qualifier function (fix describe test) 0150491 x/tools/internal/fastwalk: fixes "interrupted system call" error b4639cc internal/lsp/protocol: fix vet error in tsprotocol.go a43f69b go/expect: use parser.AllErrors when extracting Notes f48e60b add comment and check action type neovim goimports b8d1a33 internal/lsp/source: add the unusedwrite analyzer Change-Id: I3bf12fb1e4a6431ea32e879774dd6c5e525b1ff1
2 parents ede3382 + 11e8f6b commit f3da893

Some content is hidden

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

67 files changed

+2329
-1660
lines changed

cmd/eg/eg.go

Lines changed: 70 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ package main // import "golang.org/x/tools/cmd/eg"
1010
import (
1111
"flag"
1212
"fmt"
13-
"go/build"
13+
"go/ast"
1414
"go/format"
1515
"go/parser"
1616
"go/token"
17-
exec "golang.org/x/sys/execabs"
17+
"go/types"
18+
"io/ioutil"
1819
"os"
20+
"path/filepath"
1921
"strings"
2022

21-
"golang.org/x/tools/go/buildutil"
22-
"golang.org/x/tools/go/loader"
23+
exec "golang.org/x/sys/execabs"
24+
"golang.org/x/tools/go/packages"
2325
"golang.org/x/tools/refactor/eg"
2426
)
2527

@@ -32,13 +34,9 @@ var (
3234
verboseFlag = flag.Bool("v", false, "show verbose matcher diagnostics")
3335
)
3436

35-
func init() {
36-
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
37-
}
38-
3937
const usage = `eg: an example-based refactoring tool.
4038
41-
Usage: eg -t template.go [-w] [-transitive] <args>...
39+
Usage: eg -t template.go [-w] [-transitive] <packages>
4240
4341
-help show detailed help message
4442
-t template.go specifies the template file (use -help to see explanation)
@@ -47,7 +45,7 @@ Usage: eg -t template.go [-w] [-transitive] <args>...
4745
-v show verbose matcher diagnostics
4846
-beforeedit cmd a command to exec before each file is modified.
4947
"{}" represents the name of the file.
50-
` + loader.FromArgsUsage
48+
`
5149

5250
func main() {
5351
if err := doMain(); err != nil {
@@ -74,51 +72,73 @@ func doMain() error {
7472
return fmt.Errorf("no -t template.go file specified")
7573
}
7674

77-
conf := loader.Config{
78-
Fset: token.NewFileSet(),
79-
ParserMode: parser.ParseComments,
75+
tAbs, err := filepath.Abs(*templateFlag)
76+
if err != nil {
77+
return err
78+
}
79+
template, err := ioutil.ReadFile(tAbs)
80+
if err != nil {
81+
return err
8082
}
8183

82-
// The first Created package is the template.
83-
conf.CreateFromFilenames("template", *templateFlag)
84+
cfg := &packages.Config{
85+
Fset: token.NewFileSet(),
86+
Mode: packages.NeedTypesInfo | packages.NeedName | packages.NeedTypes | packages.NeedSyntax | packages.NeedImports | packages.NeedDeps | packages.NeedCompiledGoFiles,
87+
Tests: true,
88+
}
8489

85-
if _, err := conf.FromArgs(args, true); err != nil {
90+
pkgs, err := packages.Load(cfg, args...)
91+
if err != nil {
8692
return err
8793
}
8894

89-
// Load, parse and type-check the whole program.
90-
iprog, err := conf.Load()
95+
tFile, err := parser.ParseFile(cfg.Fset, tAbs, template, parser.ParseComments)
96+
if err != nil {
97+
return err
98+
}
99+
100+
// Type-check the template.
101+
tInfo := types.Info{
102+
Types: make(map[ast.Expr]types.TypeAndValue),
103+
Defs: make(map[*ast.Ident]types.Object),
104+
Uses: make(map[*ast.Ident]types.Object),
105+
Implicits: make(map[ast.Node]types.Object),
106+
Selections: make(map[*ast.SelectorExpr]*types.Selection),
107+
Scopes: make(map[ast.Node]*types.Scope),
108+
}
109+
conf := types.Config{
110+
Importer: pkgsImporter(pkgs),
111+
}
112+
tPkg, err := conf.Check("egtemplate", cfg.Fset, []*ast.File{tFile}, &tInfo)
91113
if err != nil {
92114
return err
93115
}
94116

95117
// Analyze the template.
96-
template := iprog.Created[0]
97-
xform, err := eg.NewTransformer(iprog.Fset, template.Pkg, template.Files[0], &template.Info, *verboseFlag)
118+
xform, err := eg.NewTransformer(cfg.Fset, tPkg, tFile, &tInfo, *verboseFlag)
98119
if err != nil {
99120
return err
100121
}
101122

102123
// Apply it to the input packages.
103-
var pkgs []*loader.PackageInfo
124+
var all []*packages.Package
104125
if *transitiveFlag {
105-
for _, info := range iprog.AllPackages {
106-
pkgs = append(pkgs, info)
107-
}
126+
packages.Visit(pkgs, nil, func(p *packages.Package) { all = append(all, p) })
108127
} else {
109-
pkgs = iprog.InitialPackages()
128+
all = pkgs
110129
}
111130
var hadErrors bool
112131
for _, pkg := range pkgs {
113-
if pkg == template {
114-
continue
115-
}
116-
for _, file := range pkg.Files {
117-
n := xform.Transform(&pkg.Info, pkg.Pkg, file)
132+
for i, filename := range pkg.CompiledGoFiles {
133+
if filename == tAbs {
134+
// Don't rewrite the template file.
135+
continue
136+
}
137+
file := pkg.Syntax[i]
138+
n := xform.Transform(pkg.TypesInfo, pkg.Types, file)
118139
if n == 0 {
119140
continue
120141
}
121-
filename := iprog.Fset.File(file.Pos()).Name()
122142
fmt.Fprintf(os.Stderr, "=== %s (%d matches)\n", filename, n)
123143
if *writeFlag {
124144
// Run the before-edit command (e.g. "chmod +w", "checkout") if any.
@@ -138,17 +158,34 @@ func doMain() error {
138158
args, err)
139159
}
140160
}
141-
if err := eg.WriteAST(iprog.Fset, filename, file); err != nil {
161+
if err := eg.WriteAST(cfg.Fset, filename, file); err != nil {
142162
fmt.Fprintf(os.Stderr, "eg: %s\n", err)
143163
hadErrors = true
144164
}
145165
} else {
146-
format.Node(os.Stdout, iprog.Fset, file)
166+
format.Node(os.Stdout, cfg.Fset, file)
147167
}
148168
}
149169
}
150170
if hadErrors {
151171
os.Exit(1)
152172
}
173+
153174
return nil
154175
}
176+
177+
type pkgsImporter []*packages.Package
178+
179+
func (p pkgsImporter) Import(path string) (tpkg *types.Package, err error) {
180+
packages.Visit([]*packages.Package(p), func(pkg *packages.Package) bool {
181+
if pkg.PkgPath == path {
182+
tpkg = pkg.Types
183+
return false
184+
}
185+
return true
186+
}, nil)
187+
if tpkg != nil {
188+
return tpkg, nil
189+
}
190+
return nil, fmt.Errorf("package %q not found", path)
191+
}

cmd/godoc/handlers.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ import (
1414
"golang.org/x/tools/godoc"
1515
"golang.org/x/tools/godoc/redirect"
1616
"golang.org/x/tools/godoc/vfs"
17-
)
1817

19-
// This package registers "/compile" and "/share" handlers
20-
// that redirect to the golang.org playground.
21-
import _ "golang.org/x/tools/playground"
18+
_ "golang.org/x/tools/playground" // register "/compile" playground redirect
19+
)
2220

2321
var (
2422
pres *godoc.Presentation

cmd/guru/describe.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,22 @@ func formatMember(obj types.Object, maxname int) string {
738738
}
739739
}
740740
if typestr == "" {
741+
// The fix for #44515 changed the printing of unsafe.Pointer
742+
// such that it uses a qualifier if one is provided. Using
743+
// the types.RelativeTo qualifier provided here, the output
744+
// is just "Pointer" rather than "unsafe.Pointer". This is
745+
// consistent with the printing of non-type objects but it
746+
// breaks an existing test which needs to work with older
747+
// versions of Go. Re-establish the original output by not
748+
// using a qualifier at all if we're printing a type from
749+
// package unsafe - there's only unsafe.Pointer (#44596).
750+
// NOTE: This correction can be removed (and the test's
751+
// golden file adjusted) once we only run against go1.17
752+
// or bigger.
753+
qualifier := qualifier
754+
if obj.Pkg() == types.Unsafe {
755+
qualifier = nil
756+
}
741757
typestr = types.TypeString(typ, qualifier)
742758
}
743759
buf.WriteString(typestr)

cmd/present/play.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"golang.org/x/tools/playground/socket"
1919
"golang.org/x/tools/present"
2020

21-
// This will register handlers at /compile and /share that will proxy to the
21+
// This will register a handler at /compile that will proxy to the
2222
// respective endpoints at play.golang.org. This allows the frontend to call
2323
// these endpoints without needing cross-origin request sharing (CORS).
2424
// Note that this is imported regardless of whether the endpoints are used or

go/expect/extract.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func Parse(fset *token.FileSet, filename string, content []byte) ([]*Note, error
4242
// there are ways you can break the parser such that it will not add all the
4343
// comments to the ast, which may result in files where the tests are silently
4444
// not run.
45-
file, err := parser.ParseFile(fset, filename, src, parser.ParseComments)
45+
file, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.AllErrors)
4646
if file == nil {
4747
return nil, err
4848
}

go/internal/packagesdriver/sizes.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func GetSizesGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *
2222
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
2323
var goarch, compiler string
2424
if rawErr != nil {
25-
if strings.Contains(rawErr.Error(), "cannot find main module") {
25+
if rawErrMsg := rawErr.Error(); strings.Contains(rawErrMsg, "cannot find main module") || strings.Contains(rawErrMsg, "go.mod file not found") {
2626
// User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc.
2727
// TODO(matloob): Is this a problem in practice?
2828
inv.Verb = "env"

go/packages/golist.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
584584
// golang/go#38990: go list silently fails to do cgo processing
585585
pkg.CompiledGoFiles = nil
586586
pkg.Errors = append(pkg.Errors, Error{
587-
Msg: "go list failed to return CompiledGoFiles; https://golang.org/issue/38990?",
587+
Msg: "go list failed to return CompiledGoFiles. This may indicate failure to perform cgo processing; try building at the command line. See https://golang.org/issue/38990.",
588588
Kind: ListError,
589589
})
590590
}

godoc/static/playground.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ function PlaygroundOutput(el) {
517517
sharing = true;
518518

519519
var sharingData = body();
520-
$.ajax('/share', {
520+
$.ajax('https://play.golang.org/share', {
521521
processData: false,
522522
data: sharingData,
523523
type: 'POST',

godoc/static/static.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gopls/doc/analyzers.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,46 @@ A useless comparison is one like f == nil as opposed to f() == nil.
208208

209209
**Enabled by default.**
210210

211+
## **nilness**
212+
213+
check for redundant or impossible nil comparisons
214+
215+
The nilness checker inspects the control-flow graph of each function in
216+
a package and reports nil pointer dereferences, degenerate nil
217+
pointers, and panics with nil values. A degenerate comparison is of the form
218+
x==nil or x!=nil where x is statically known to be nil or non-nil. These are
219+
often a mistake, especially in control flow related to errors. Panics with nil
220+
values are checked because they are not detectable by
221+
222+
if r := recover(); r != nil {
223+
224+
This check reports conditions such as:
225+
226+
if f == nil { // impossible condition (f is a function)
227+
}
228+
229+
and:
230+
231+
p := &v
232+
...
233+
if p != nil { // tautological condition
234+
}
235+
236+
and:
237+
238+
if p == nil {
239+
print(*p) // nil dereference
240+
}
241+
242+
and:
243+
244+
if p == nil {
245+
panic(p)
246+
}
247+
248+
249+
**Disabled by default. Enable it by setting `"analyses": {"nilness": true}`.**
250+
211251
## **printf**
212252

213253
check consistency of Printf format strings and arguments
@@ -468,6 +508,35 @@ The set of functions may be controlled using flags.
468508

469509
**Enabled by default.**
470510

511+
## **unusedwrite**
512+
513+
checks for unused writes
514+
515+
The analyzer reports instances of writes to struct fields and
516+
arrays that are never read. Specifically, when a struct object
517+
or an array is copied, its elements are copied implicitly by
518+
the compiler, and any element write to this copy does nothing
519+
with the original object.
520+
521+
For example:
522+
523+
type T struct { x int }
524+
func f(input []T) {
525+
for i, v := range input { // v is a copy
526+
v.x = i // unused write to field x
527+
}
528+
}
529+
530+
Another example is about non-pointer receiver:
531+
532+
type T struct { x int }
533+
func (t T) f() { // t is a copy
534+
t.x = i // unused write to field x
535+
}
536+
537+
538+
**Disabled by default. Enable it by setting `"analyses": {"unusedwrite": true}`.**
539+
471540
## **fillreturns**
472541

473542
suggested fixes for "wrong number of return values (want %d, got %d)"

0 commit comments

Comments
 (0)