mirror of https://github.com/golang/go.git
internal/lsp/analysis: analyzer for //go:embed directive
This CL adds a new analyzer for //go:embed directive, which checks for the "embed" import. Along with it, it improves doc for analysistest.Run for comments of the the form "//...// want..." or "//...// want..." Updates #50262 Change-Id: I60ef0ab740feadd4fff3a4d758123b27ceda0bc6 Reviewed-on: https://go-review.googlesource.com/c/tools/+/400854 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Peter Weinberger <pjw@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Run-TryBot: Nooras Saba <saba@golang.org> gopls-CI: kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
033cbfc76d
commit
28c754d415
|
|
@ -249,7 +249,8 @@ func RunWithSuggestedFixes(t Testing, dir string, a *analysis.Analyzer, patterns
|
|||
// directory using golang.org/x/tools/go/packages, runs the analysis on
|
||||
// them, and checks that each analysis emits the expected diagnostics
|
||||
// and facts specified by the contents of '// want ...' comments in the
|
||||
// package's source files.
|
||||
// package's source files. It treats a comment of the form
|
||||
// "//...// want..." or "/*...// want... */" as if it starts at 'want'
|
||||
//
|
||||
// An expectation of a Diagnostic is specified by a string literal
|
||||
// containing a regular expression that must match the diagnostic
|
||||
|
|
|
|||
|
|
@ -108,6 +108,15 @@ errors is discouraged.
|
|||
|
||||
**Enabled by default.**
|
||||
|
||||
## **embed**
|
||||
|
||||
check for //go:embed directive import
|
||||
|
||||
This analyzer checks that the embed package is imported when source code contains //go:embed comment directives.
|
||||
The embed package must be imported for //go:embed directives to function.import _ "embed".
|
||||
|
||||
**Enabled by default.**
|
||||
|
||||
## **errorsas**
|
||||
|
||||
report passing non-pointer or non-error values to errors.As
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright 2022 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.
|
||||
|
||||
// Package embeddirective defines an Analyzer that validates import for //go:embed directive.
|
||||
package embeddirective
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
)
|
||||
|
||||
const Doc = `check for //go:embed directive import
|
||||
|
||||
This analyzer checks that the embed package is imported when source code contains //go:embed comment directives.
|
||||
The embed package must be imported for //go:embed directives to function.import _ "embed".`
|
||||
|
||||
var Analyzer = &analysis.Analyzer{
|
||||
Name: "embed",
|
||||
Doc: Doc,
|
||||
Requires: []*analysis.Analyzer{},
|
||||
Run: run,
|
||||
RunDespiteErrors: true,
|
||||
}
|
||||
|
||||
func run(pass *analysis.Pass) (interface{}, error) {
|
||||
for _, f := range pass.Files {
|
||||
com := hasEmbedDirectiveComment(f)
|
||||
if com != nil {
|
||||
assertEmbedImport(pass, com, f)
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Check if comment contains //go:embed directive.
|
||||
func hasEmbedDirectiveComment(f *ast.File) *ast.Comment {
|
||||
for _, cg := range f.Comments {
|
||||
for _, c := range cg.List {
|
||||
if strings.HasPrefix(c.Text, "//go:embed ") {
|
||||
return c
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Verifies that "embed" import exists for //go:embed directive.
|
||||
func assertEmbedImport(pass *analysis.Pass, com *ast.Comment, f *ast.File) {
|
||||
for _, imp := range f.Imports {
|
||||
if "\"embed\"" == imp.Path.Value {
|
||||
return
|
||||
}
|
||||
}
|
||||
pass.Report(analysis.Diagnostic{Pos: com.Pos(), End: com.Pos() + 10, Message: "The \"embed\" package must be imported when using go:embed directives."})
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2022 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.
|
||||
|
||||
package embeddirective
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/analysis/analysistest"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
testdata := analysistest.TestData()
|
||||
tests := []string{"a"}
|
||||
if typeparams.Enabled {
|
||||
tests = append(tests)
|
||||
}
|
||||
|
||||
analysistest.RunWithSuggestedFixes(t, testdata, Analyzer, tests...)
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package a
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
//go:embed embedText // want "The \"embed\" package must be imported when using go:embed directives"
|
||||
var s string
|
||||
|
||||
// This is main function
|
||||
func main() {
|
||||
fmt.Println(s)
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package a
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
//go:embed embedText // ok
|
||||
var s string
|
||||
|
||||
// This is main function
|
||||
func main() {
|
||||
fmt.Println(s)
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
Hello World
|
||||
|
|
@ -268,6 +268,11 @@ var GeneratedAPIJSON = &APIJSON{
|
|||
Doc: "check for calls of reflect.DeepEqual on error values\n\nThe deepequalerrors checker looks for calls of the form:\n\n reflect.DeepEqual(err1, err2)\n\nwhere err1 and err2 are errors. Using reflect.DeepEqual to compare\nerrors is discouraged.",
|
||||
Default: "true",
|
||||
},
|
||||
{
|
||||
Name: "\"embed\"",
|
||||
Doc: "check for //go:embed directive import\n\nThis analyzer checks that the embed package is imported when source code contains //go:embed comment directives.\nThe embed package must be imported for //go:embed directives to function.import _ \"embed\".",
|
||||
Default: "true",
|
||||
},
|
||||
{
|
||||
Name: "\"errorsas\"",
|
||||
Doc: "report passing non-pointer or non-error values to errors.As\n\nThe errorsas analysis reports calls to errors.As where the type\nof the second argument is not a pointer to a type implementing error.",
|
||||
|
|
@ -804,6 +809,11 @@ var GeneratedAPIJSON = &APIJSON{
|
|||
Doc: "check for calls of reflect.DeepEqual on error values\n\nThe deepequalerrors checker looks for calls of the form:\n\n reflect.DeepEqual(err1, err2)\n\nwhere err1 and err2 are errors. Using reflect.DeepEqual to compare\nerrors is discouraged.",
|
||||
Default: true,
|
||||
},
|
||||
{
|
||||
Name: "embed",
|
||||
Doc: "check for //go:embed directive import\n\nThis analyzer checks that the embed package is imported when source code contains //go:embed comment directives.\nThe embed package must be imported for //go:embed directives to function.import _ \"embed\".",
|
||||
Default: true,
|
||||
},
|
||||
{
|
||||
Name: "errorsas",
|
||||
Doc: "report passing non-pointer or non-error values to errors.As\n\nThe errorsas analysis reports calls to errors.As where the type\nof the second argument is not a pointer to a type implementing error.",
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import (
|
|||
"golang.org/x/tools/go/analysis/passes/unusedresult"
|
||||
"golang.org/x/tools/go/analysis/passes/unusedwrite"
|
||||
"golang.org/x/tools/go/packages"
|
||||
"golang.org/x/tools/internal/lsp/analysis/embeddirective"
|
||||
"golang.org/x/tools/internal/lsp/analysis/fillreturns"
|
||||
"golang.org/x/tools/internal/lsp/analysis/fillstruct"
|
||||
"golang.org/x/tools/internal/lsp/analysis/infertypeargs"
|
||||
|
|
@ -1308,6 +1309,7 @@ func defaultAnalyzers() map[string]*Analyzer {
|
|||
unusedwrite.Analyzer.Name: {Analyzer: unusedwrite.Analyzer, Enabled: false},
|
||||
useany.Analyzer.Name: {Analyzer: useany.Analyzer, Enabled: false},
|
||||
infertypeargs.Analyzer.Name: {Analyzer: infertypeargs.Analyzer, Enabled: true},
|
||||
embeddirective.Analyzer.Name: {Analyzer: embeddirective.Analyzer, Enabled: true},
|
||||
|
||||
// gofmt -s suite:
|
||||
simplifycompositelit.Analyzer.Name: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue