Skip to content

Commit d03849b

Browse files
committed
gopls/internal: add code action "move to a new file"
This code action moves selected code sections to a newly created file within the same package. The created filename is chosen as the first {function, type, const, var} name encountered. In addition, import declarations are added or removed as needed. Fixes golang/go#65707
1 parent c111c4d commit d03849b

File tree

11 files changed

+844
-11
lines changed

11 files changed

+844
-11
lines changed

gopls/go.sum

-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
1818
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y=
1919
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
2020
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
21-
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
2221
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
2322
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
2423
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
@@ -27,12 +26,8 @@ golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
2726
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
2827
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2928
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
30-
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
3129
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
3230
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
33-
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509 h1:Nr7eTQpQZ/ytesxDJpQgaf0t4sdLnnDtAbmtViTrSUo=
34-
golang.org/x/telemetry v0.0.0-20240201224847-0a1d30dda509/go.mod h1:ZthVHHkOi8rlMEsfFr3Ie42Ym1NonbFNNRKW3ci0UrU=
35-
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808 h1:+Kc94D8UVEVxJnLXp/+FMfqQARZtWHfVrcRtcG8aT3g=
3631
golang.org/x/telemetry v0.0.0-20240208230135-b75ee8823808/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ=
3732
golang.org/x/telemetry v0.0.0-20240209200032-7b892fcb8a78 h1:vcVnuftN4J4UKLRcgetjzfU9FjjgXUUYUc3JhFplgV4=
3833
golang.org/x/telemetry v0.0.0-20240209200032-7b892fcb8a78/go.mod h1:KG1lNk5ZFNssSZLrpVb4sMXKMpGwGXOxSG3rnu2gZQQ=

gopls/internal/cache/snapshot.go

+16
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,22 @@ func inVendor(uri protocol.DocumentURI) bool {
16581658
return found && strings.Contains(after, "/")
16591659
}
16601660

1661+
// Sandbox clones the reciever, applying given file modfications as overlays.
1662+
func (s *Snapshot) Sandbox(ctx, bgCtx context.Context, modifications []file.Modification) *Snapshot {
1663+
updatedFiles := make(map[protocol.DocumentURI]file.Handle)
1664+
for _, m := range modifications {
1665+
updatedFiles[m.URI] = &overlay{
1666+
uri: m.URI,
1667+
content: m.Text,
1668+
}
1669+
}
1670+
cloned, _ := s.clone(ctx, bgCtx, StateChange{
1671+
Modifications: modifications,
1672+
Files: updatedFiles,
1673+
}, func() {})
1674+
return cloned
1675+
}
1676+
16611677
// clone copies state from the receiver into a new Snapshot, applying the given
16621678
// state changes.
16631679
//

gopls/internal/golang/codeaction.go

+5
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ func CodeActions(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
8686
return nil, err
8787
}
8888
actions = append(actions, extractions...)
89+
moves, err := getMoveToNewFileCodeAction(pgf, rng, snapshot.Options())
90+
if err != nil {
91+
return nil, err
92+
}
93+
actions = append(actions, moves)
8994
}
9095
}
9196

gopls/internal/golang/format.go

+32
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,38 @@ func Format(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle) ([]pr
9292
return computeTextEdits(ctx, pgf, formatted)
9393
}
9494

95+
func formatImportsBytes(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle) ([]byte, error) {
96+
_, done := event.Start(ctx, "golang.formatImportsBytes")
97+
defer done()
98+
99+
errorPrefix := "formatImportsBytes"
100+
101+
text, err := fh.Content()
102+
if err != nil {
103+
return nil, fmt.Errorf("%s: %w", errorPrefix, err)
104+
}
105+
106+
var out []byte
107+
if err := snapshot.RunProcessEnvFunc(ctx, func(ctx context.Context, opts *imports.Options) error {
108+
fixes, err := imports.FixImports(ctx, fh.URI().Path(), text, opts)
109+
if err != nil {
110+
return fmt.Errorf("%s: %w", errorPrefix, err)
111+
}
112+
out, err = imports.ApplyFixes(fixes, fh.URI().Path(), text, opts, parsego.Full)
113+
if err != nil {
114+
return fmt.Errorf("%s: %w", errorPrefix, err)
115+
}
116+
return nil
117+
}); err != nil {
118+
return nil, fmt.Errorf("%s: %w", errorPrefix, err)
119+
}
120+
out, err = format.Source(out)
121+
if err != nil {
122+
return nil, fmt.Errorf("%s: %w", errorPrefix, err)
123+
}
124+
return out, nil
125+
}
126+
95127
func formatSource(ctx context.Context, fh file.Handle) ([]byte, error) {
96128
_, done := event.Start(ctx, "golang.formatSource")
97129
defer done()

0 commit comments

Comments
 (0)