Skip to content

Commit

Permalink
x/tools/gopls: implement struct field generation quickfix
Browse files Browse the repository at this point in the history
  • Loading branch information
dennypenta committed Dec 3, 2024
1 parent c62da73 commit 788379a
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 329 deletions.
8 changes: 8 additions & 0 deletions gopls/doc/release/v0.17.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,11 @@ Since this feature is implemented by the server (gopls), it is compatible with
all LSP-compliant editors. VS Code users may continue to use the client-side
`Go: Generate Unit Tests For file/function/package` command which utilizes the
[gotests](https://github.com/cweill/gotests) tool.

## Generate missing struct field from access
When you attempt to access a field on a type that does not have the field,
the compiler will report an error like “type X has no field or method Y”.
Gopls now offers a new code action, “Declare missing field of T.f”,
where T is the concrete type and f is the undefined field.
The stub field's signature is inferred
from the context of the access.
12 changes: 0 additions & 12 deletions gopls/internal/analysis/yield/yield.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ import (
_ "embed"
"fmt"
"go/ast"
<<<<<<< HEAD
"go/constant"
=======
>>>>>>> 9b6e4f21d (gopls/internal/analysis/yield: analyzer for iterator (yield) mistakes)
"go/token"
"go/types"

Expand Down Expand Up @@ -123,7 +120,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
// In that case visit only the "if !yield()" block.
cond := instr.Cond
t, f := b.Succs[0], b.Succs[1]
<<<<<<< HEAD

// Strip off any NOT operator.
cond, t, f = unnegate(cond, t, f)
Expand Down Expand Up @@ -152,11 +148,6 @@ func run(pass *analysis.Pass) (interface{}, error) {
}
}

=======
if unop, ok := cond.(*ssa.UnOp); ok && unop.Op == token.NOT {
cond, t, f = unop.X, f, t
}
>>>>>>> 9b6e4f21d (gopls/internal/analysis/yield: analyzer for iterator (yield) mistakes)
if cond, ok := cond.(*ssa.Call); ok && ssaYieldCalls[cond] != nil {
// Skip the successor reached by "if yield() { ... }".
} else {
Expand All @@ -178,13 +169,10 @@ func run(pass *analysis.Pass) (interface{}, error) {

return nil, nil
}
<<<<<<< HEAD

func unnegate(cond ssa.Value, t, f *ssa.BasicBlock) (_ ssa.Value, _, _ *ssa.BasicBlock) {
if unop, ok := cond.(*ssa.UnOp); ok && unop.Op == token.NOT {
return unop.X, f, t
}
return cond, t, f
}
=======
>>>>>>> 9b6e4f21d (gopls/internal/analysis/yield: analyzer for iterator (yield) mistakes)
2 changes: 1 addition & 1 deletion gopls/internal/golang/assembly.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ew// Copyright 2024 The Go Authors. All rights reserved.
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

Expand Down
2 changes: 1 addition & 1 deletion gopls/internal/golang/codeaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ func (si *StructFieldInfo) Emit(out *bytes.Buffer, qual types.Qualifier) error {
}

// Get types from context at the selector expression position
typesFromContext := stubmethods.TypesFromContext(si.Info, si.Path, si.Expr.Pos())
typesFromContext := typesutil.TypesFromContext(si.Info, si.Path, si.Expr.Pos())

// Default to interface{} if we couldn't determine the type from context
var fieldType types.Type
Expand Down
Loading

0 comments on commit 788379a

Please sign in to comment.