Skip to content

Commit 788379a

Browse files
committed
x/tools/gopls: implement struct field generation quickfix
1 parent c62da73 commit 788379a

File tree

6 files changed

+177
-329
lines changed

6 files changed

+177
-329
lines changed

gopls/doc/release/v0.17.0.md

+8
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,11 @@ Since this feature is implemented by the server (gopls), it is compatible with
122122
all LSP-compliant editors. VS Code users may continue to use the client-side
123123
`Go: Generate Unit Tests For file/function/package` command which utilizes the
124124
[gotests](https://github.com/cweill/gotests) tool.
125+
126+
## Generate missing struct field from access
127+
When you attempt to access a field on a type that does not have the field,
128+
the compiler will report an error like “type X has no field or method Y”.
129+
Gopls now offers a new code action, “Declare missing field of T.f”,
130+
where T is the concrete type and f is the undefined field.
131+
The stub field's signature is inferred
132+
from the context of the access.

gopls/internal/analysis/yield/yield.go

-12
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ import (
2020
_ "embed"
2121
"fmt"
2222
"go/ast"
23-
<<<<<<< HEAD
2423
"go/constant"
25-
=======
26-
>>>>>>> 9b6e4f21d (gopls/internal/analysis/yield: analyzer for iterator (yield) mistakes)
2724
"go/token"
2825
"go/types"
2926

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

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

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

179170
return nil, nil
180171
}
181-
<<<<<<< HEAD
182172

183173
func unnegate(cond ssa.Value, t, f *ssa.BasicBlock) (_ ssa.Value, _, _ *ssa.BasicBlock) {
184174
if unop, ok := cond.(*ssa.UnOp); ok && unop.Op == token.NOT {
185175
return unop.X, f, t
186176
}
187177
return cond, t, f
188178
}
189-
=======
190-
>>>>>>> 9b6e4f21d (gopls/internal/analysis/yield: analyzer for iterator (yield) mistakes)

gopls/internal/golang/assembly.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
ew// Copyright 2024 The Go Authors. All rights reserved.
1+
// Copyright 2024 The Go Authors. All rights reserved.
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

gopls/internal/golang/codeaction.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ func (si *StructFieldInfo) Emit(out *bytes.Buffer, qual types.Qualifier) error {
408408
}
409409

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

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

0 commit comments

Comments
 (0)