Skip to content

Commit 65b14ec

Browse files
committed
all: merge master (03562de) into gopls-release-branch.0.13
Also add back the x/tools replace directive to the gopls module. For golang/go#61583 Merge List: + 2023-07-27 03562de refactor/satisfy/find: composite lits may have type parameter type + 2023-07-27 bacac14 gopls/internal/lsp/source: Add SuggestedFix for embeddirective Analyzer + 2023-07-27 38606b3 gopls/internal/lsp/cache: keep analysis progress reports on one line Change-Id: I8338e1afa66ddd4985ddd1e4c520aa15e81c92c4
2 parents 0ea602e + 03562de commit 65b14ec

File tree

18 files changed

+220
-64
lines changed

18 files changed

+220
-64
lines changed

gopls/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ require (
2525
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
2626
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 // indirect
2727
)
28+
29+
replace golang.org/x/tools => ../

gopls/go.sum

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -42,91 +42,47 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
4242
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
4343
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
4444
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
45-
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
46-
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
4745
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
48-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
49-
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
50-
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
5146
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
5247
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
5348
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
5449
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
5550
golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
5651
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338 h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y=
5752
golang.org/x/exp/typeparams v0.0.0-20221212164502-fae10dda9338/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
58-
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
59-
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
6053
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
6154
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
6255
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
6356
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
6457
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
6558
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
66-
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
67-
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
68-
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
6959
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
70-
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
71-
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
72-
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
73-
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
7460
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
7561
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
76-
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
77-
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
7862
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
79-
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8063
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8164
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
8265
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
8366
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
84-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
85-
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
86-
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
8767
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
88-
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
89-
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
9068
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9169
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9270
golang.org/x/sys v0.0.0-20211213223007-03aa0b5f6827/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
93-
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
94-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9571
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9672
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9773
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9874
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
9975
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
10076
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
10177
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
102-
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
103-
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
104-
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
10578
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
10679
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
107-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
10880
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
109-
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
110-
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
111-
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
112-
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
11381
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
11482
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
11583
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
116-
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
117-
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
118-
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
119-
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
120-
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
121-
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
122-
golang.org/x/tools v0.4.1-0.20221208213631-3f74d914ae6d/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
123-
golang.org/x/tools v0.4.1-0.20221217013628-b4dfc36097e2/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
124-
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
125-
golang.org/x/tools v0.11.1-0.20230726135247-3ff6127f8513 h1:2f53pFbfRYUtasosi3HXbdmGayUzfqcm5AAnrl00vAE=
126-
golang.org/x/tools v0.11.1-0.20230726135247-3ff6127f8513/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
12784
golang.org/x/vuln v0.0.0-20230110180137-6ad3e3d07815 h1:A9kONVi4+AnuOr1dopsibH6hLi1Huy54cbeJxnq4vmU=
12885
golang.org/x/vuln v0.0.0-20230110180137-6ad3e3d07815/go.mod h1:XJiVExZgoZfrrxoTeVsFYrSSk1snhfpOEC95JL+A4T0=
129-
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
13086
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
13187
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
13288
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

gopls/internal/lsp/analysis/embeddirective/embeddirective.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// Package embeddirective defines an Analyzer that validates import for //go:embed directive.
5+
// Package embeddirective defines an Analyzer that validates //go:embed directives.
6+
// The analyzer defers fixes to it's parent source.Analyzer.
67
package embeddirective
78

89
import (
@@ -26,6 +27,10 @@ var Analyzer = &analysis.Analyzer{
2627
RunDespiteErrors: true,
2728
}
2829

30+
// source.fixedByImportingEmbed relies on this message to filter
31+
// out fixable diagnostics from this Analyzer.
32+
const MissingImportMessage = `must import "embed" when using go:embed directives`
33+
2934
func run(pass *analysis.Pass) (interface{}, error) {
3035
for _, f := range pass.Files {
3136
comments := embedDirectiveComments(f)
@@ -51,7 +56,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
5156
}
5257

5358
if !hasEmbedImport {
54-
report(`must import "embed" when using go:embed directives`)
59+
report(MissingImportMessage)
5560
}
5661

5762
spec := nextVarSpec(c, f)

gopls/internal/lsp/cache/analysis.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,7 @@ func (snapshot *snapshot) Analyze(ctx context.Context, pkgs map[PackageID]unit,
354354
if now.Sub(lastReport) > reportEvery {
355355
lastReport = now
356356
// Trailing space is intentional: some LSP clients strip newlines.
357-
msg := fmt.Sprintf(`Constructing index of analysis facts... (%d/%d packages).
358-
(Set "analysisProgressReporting" to false to disable notifications.)`,
357+
msg := fmt.Sprintf(`Indexed %d/%d packages. (Set "analysisProgressReporting" to false to disable notifications.)`,
359358
completed, len(nodes))
360359
pct := 100 * float64(completed) / float64(len(nodes))
361360
wd.Report(ctx, msg, pct)

gopls/internal/lsp/cache/errors.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -339,17 +339,20 @@ func toSourceDiagnostic(srcAnalyzer *source.Analyzer, gobDiag *gobDiagnostic) *s
339339
}
340340

341341
diag := &source.Diagnostic{
342-
URI: gobDiag.Location.URI.SpanURI(),
343-
Range: gobDiag.Location.Range,
344-
Severity: severity,
345-
Code: gobDiag.Code,
346-
CodeHref: gobDiag.CodeHref,
347-
Source: source.AnalyzerErrorKind(gobDiag.Source),
348-
Message: gobDiag.Message,
349-
Related: related,
350-
SuggestedFixes: fixes,
351-
Tags: srcAnalyzer.Tag,
342+
URI: gobDiag.Location.URI.SpanURI(),
343+
Range: gobDiag.Location.Range,
344+
Severity: severity,
345+
Code: gobDiag.Code,
346+
CodeHref: gobDiag.CodeHref,
347+
Source: source.AnalyzerErrorKind(gobDiag.Source),
348+
Message: gobDiag.Message,
349+
Related: related,
350+
Tags: srcAnalyzer.Tag,
351+
}
352+
if srcAnalyzer.FixesDiagnostic(diag) {
353+
diag.SuggestedFixes = fixes
352354
}
355+
353356
// If the fixes only delete code, assume that the diagnostic is reporting dead code.
354357
if onlyDeletions(fixes) {
355358
diag.Tags = append(diag.Tags, protocol.Unnecessary)

gopls/internal/lsp/source/fix.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ import (
1313

1414
"golang.org/x/tools/go/analysis"
1515
"golang.org/x/tools/gopls/internal/bug"
16+
"golang.org/x/tools/gopls/internal/lsp/analysis/embeddirective"
1617
"golang.org/x/tools/gopls/internal/lsp/analysis/fillstruct"
1718
"golang.org/x/tools/gopls/internal/lsp/analysis/undeclaredname"
1819
"golang.org/x/tools/gopls/internal/lsp/protocol"
1920
"golang.org/x/tools/gopls/internal/span"
21+
"golang.org/x/tools/internal/imports"
2022
)
2123

2224
type (
@@ -41,6 +43,7 @@ const (
4143
ExtractFunction = "extract_function"
4244
ExtractMethod = "extract_method"
4345
InvertIfCondition = "invert_if_condition"
46+
AddEmbedImport = "add_embed_import"
4447
)
4548

4649
// suggestedFixes maps a suggested fix command id to its handler.
@@ -52,6 +55,7 @@ var suggestedFixes = map[string]SuggestedFixFunc{
5255
ExtractMethod: singleFile(extractMethod),
5356
InvertIfCondition: singleFile(invertIfCondition),
5457
StubMethods: stubSuggestedFixFunc,
58+
AddEmbedImport: addEmbedImport,
5559
}
5660

5761
// singleFile calls analyzers that expect inputs for a single file
@@ -138,3 +142,50 @@ func ApplyFix(ctx context.Context, fix string, snapshot Snapshot, fh FileHandle,
138142
}
139143
return edits, nil
140144
}
145+
146+
// fixedByImportingEmbed returns true if diag can be fixed by addEmbedImport.
147+
func fixedByImportingEmbed(diag *Diagnostic) bool {
148+
if diag == nil {
149+
return false
150+
}
151+
return diag.Message == embeddirective.MissingImportMessage
152+
}
153+
154+
// addEmbedImport adds a missing embed "embed" import with blank name.
155+
func addEmbedImport(ctx context.Context, snapshot Snapshot, fh FileHandle, rng protocol.Range) (*token.FileSet, *analysis.SuggestedFix, error) {
156+
pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI())
157+
if err != nil {
158+
return nil, nil, fmt.Errorf("narrow pkg: %w", err)
159+
}
160+
161+
// Like source.AddImport, but with _ as Name and using our pgf.
162+
protoEdits, err := ComputeOneImportFixEdits(snapshot, pgf, &imports.ImportFix{
163+
StmtInfo: imports.ImportInfo{
164+
ImportPath: "embed",
165+
Name: "_",
166+
},
167+
FixType: imports.AddImport,
168+
})
169+
if err != nil {
170+
return nil, nil, fmt.Errorf("compute edits: %w", err)
171+
}
172+
173+
var edits []analysis.TextEdit
174+
for _, e := range protoEdits {
175+
start, end, err := pgf.RangePos(e.Range)
176+
if err != nil {
177+
return nil, nil, fmt.Errorf("map range: %w", err)
178+
}
179+
edits = append(edits, analysis.TextEdit{
180+
Pos: start,
181+
End: end,
182+
NewText: []byte(e.NewText),
183+
})
184+
}
185+
186+
fix := &analysis.SuggestedFix{
187+
Message: "Add embed import",
188+
TextEdits: edits,
189+
}
190+
return pkg.FileSet(), fix, nil
191+
}

gopls/internal/lsp/source/options.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1574,8 +1574,13 @@ func defaultAnalyzers() map[string]*Analyzer {
15741574
unusedparams.Analyzer.Name: {Analyzer: unusedparams.Analyzer, Enabled: false},
15751575
unusedwrite.Analyzer.Name: {Analyzer: unusedwrite.Analyzer, Enabled: false},
15761576
useany.Analyzer.Name: {Analyzer: useany.Analyzer, Enabled: false},
1577-
embeddirective.Analyzer.Name: {Analyzer: embeddirective.Analyzer, Enabled: true},
15781577
timeformat.Analyzer.Name: {Analyzer: timeformat.Analyzer, Enabled: true},
1578+
embeddirective.Analyzer.Name: {
1579+
Analyzer: embeddirective.Analyzer,
1580+
Enabled: true,
1581+
Fix: AddEmbedImport,
1582+
fixesDiagnostic: fixedByImportingEmbed,
1583+
},
15791584

15801585
// gofmt -s suite:
15811586
simplifycompositelit.Analyzer.Name: {

gopls/internal/lsp/source/view.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,10 @@ type Analyzer struct {
879879
// the analyzer's suggested fixes through a Command, not a TextEdit.
880880
Fix string
881881

882+
// fixesDiagnostic reports if a diagnostic from the analyzer can be fixed by Fix.
883+
// If nil then all diagnostics from the analyzer are assumed to be fixable.
884+
fixesDiagnostic func(*Diagnostic) bool
885+
882886
// ActionKind is the kind of code action this analyzer produces. If
883887
// unspecified the type defaults to quickfix.
884888
ActionKind []protocol.CodeActionKind
@@ -908,6 +912,14 @@ func (a Analyzer) IsEnabled(options *Options) bool {
908912
return a.Enabled
909913
}
910914

915+
// FixesDiagnostic returns true if Analyzer.Fix can fix the Diagnostic.
916+
func (a Analyzer) FixesDiagnostic(d *Diagnostic) bool {
917+
if a.fixesDiagnostic == nil {
918+
return true
919+
}
920+
return a.fixesDiagnostic(d)
921+
}
922+
911923
// Declare explicit types for package paths, names, and IDs to ensure that we
912924
// never use an ID where a path belongs, and vice versa. If we confused these,
913925
// it would result in confusing errors because package IDs often look like
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
text
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2023 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package embeddirective
6+
7+
import (
8+
"io"
9+
"os"
10+
)
11+
12+
//go:embed embed.txt //@suggestedfix("//go:embed", "quickfix", "")
13+
var t string
14+
15+
func unused() {
16+
_ = os.Stdin
17+
_ = io.EOF
18+
}

0 commit comments

Comments
 (0)