Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/go/analysis/analysistest: problem with Requires and structtag.Analyzer #52973

Closed
ccoVeille opened this issue May 18, 2022 · 3 comments
Closed
Labels
Analysis Issues related to static analysis (vet, x/tools/go/analysis) FrozenDueToAge Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@ccoVeille
Copy link

ccoVeille commented May 18, 2022

What version of Go are you using (go version)?

go version go1.18.1 linux/amd64

Does this issue reproduce with the latest release?

yes, I also tested in a docker instance with 1.18.2

root@8fd7dc46af41:/wd# go version
go version go1.18.2 linux/amd64

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.18.2"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/wd/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2693414172=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I worked on a branch available here

https://github.com/ccoVeille/tagliatelle/blob/golang-issue/

I'm trying to use an analyzer that requires on structtag.Analyzer to be validated
https://github.com/ccoVeille/tagliatelle/blob/golang-issue/tagliatelle.go

func New(config Config) *analysis.Analyzer {
	return &analysis.Analyzer{
		Name: "tagliatelle",
		Doc:  "Checks the struct tags.",
		Run: func(pass *analysis.Pass) (interface{}, error) {
			// uncomment structAnalyser.Run to fix the issue
			// but we shouldn't call it here, as structtag.Analyzer is in the Requires
			// I checked Requires was run and found the issue, the issue is simply not reported
			//_, _ = structtag.Analyzer.Run(pass)

			if len(config.Rules) == 0 {
				return nil, nil
			}

			return run(pass, config)
		},
		Requires: []*analysis.Analyzer{
			structtag.Analyzer,
			inspect.Analyzer,
		},
	}
}

I'm launching the code via go test -v ./...

I added this to the tests

https://github.com/ccoVeille/tagliatelle/blob/golang-issue/testdata/src/a/sample.go#L43-L52=

It's a struct that is not compatible with reflect.StructTag, I added to my testdata file, because I want to be able to detect such issue

type MessedUpTags struct {
	// an invalid tag listed in the rule is supported.
	Bad string `json:"bad` // want "struct field tag `json:\"bad` not compatible with reflect.StructTag.Get: bad syntax for struct tag value"

	// an invalid tag not in the rule is supported.
	Whatever string `foo:whatever` // want "struct field tag `foo:whatever` not compatible with reflect.StructTag.Get: bad syntax for struct tag value"

	// a invalid tag supported by the rule, is not hidden by another broken tag
	Mixed string `json:"mixed" foo:mixed` // want "struct field tag `json:\"mixed\" foo:mixed` not compatible with reflect.StructTag.Get: bad syntax for struct tag value"
}

I expect the Requires code to stop the code and execution, but also to print the errors.

I checked the structtag.Analyzer is launch and report the issue, the issues are reported, so appended to a.diagnosis

https://cs.opensource.google/go/x/tools/+/master:go/analysis/internal/checker/checker.go;l=684?q=ImportObjectFact&ss=go%2Fx%2Ftools

But then, they are not available.

I tried to edit the golang code locally, but failed to find a solution, I think it's a bug.

I also checked I'm using the latest version go tools
https://github.com/ccoVeille/tagliatelle/blob/golang-issue/go.mod#L7=

What did you expect to see?

I'm expecting the code to print the error returned by the structtag.Analyzer

$ go test -v ./...
root@8fd7dc46af41:/wd# go test -v ./...
=== RUN   TestAnalyzer
    analysistest.go:512: a/sample.go:45: no diagnostic was reported matching "struct field tag `json:\"bad` not compatible with reflect.StructTag.Get: bad syntax for struct tag value"
    analysistest.go:512: a/sample.go:48: no diagnostic was reported matching "struct field tag `foo:whatever` not compatible with reflect.StructTag.Get: bad syntax for struct tag value"
    analysistest.go:512: a/sample.go:51: no diagnostic was reported matching "struct field tag `json:\"mixed\" foo:mixed` not compatible with reflect.StructTag.Get: bad syntax for struct tag value"
--- FAIL: TestAnalyzer (0.01s)
FAIL
FAIL	github.com/ldez/tagliatelle	0.014s
?   	github.com/ldez/tagliatelle/cmd/tagliatelle	[no test files]
FAIL

What did you see instead?

root@8fd7dc46af41:/wd# go test -v ./...
=== RUN   TestAnalyzer
--- PASS: TestAnalyzer (0.01s)
PASS
ok  	github.com/ldez/tagliatelle	0.015s
?   	github.com/ldez/tagliatelle/cmd/tagliatelle	[no test files]
@ccoVeille ccoVeille changed the title golang.org/x/tools/go/analysis/analysistest: problem with Requires and structtag.Analyzer x/tools/go/analysis/analysistest: problem with Requires and structtag.Analyzer May 18, 2022
@gopherbot gopherbot added the Tools This label describes issues relating to any tools in the x/tools repository. label May 18, 2022
@gopherbot gopherbot added this to the Unreleased milestone May 18, 2022
@timothy-king timothy-king added the Analysis Issues related to static analysis (vet, x/tools/go/analysis) label May 18, 2022
@timothy-king
Copy link
Contributor

I believe this is a case of only root actions (Analyzer, Package) being reported. I am not seeing good documentation that this is the intended behavior but analysis is quite consistent about this:

Requires is really intended for communicating results not diagnostics.

You are requesting 1 root action (tagliatelle.New(...), "a"). The action the Requires creates for (structtag.Analyzer, "a") executes but generates no diagnostics.

So I believe this is WAI, but not very well documented. I am closing this as WAI. If you are not satisfied are 2 follow-ups folks can take:

  1. file a proposal to change printing diagnostics for non-root actions. This change requires one IMO.
  2. send a PR with suggested documentation improvements to clarify that only diagnostics for root actions are printed.

@ccoVeille
Copy link
Author

Thanks, I will check a bit further then

@ccoVeille
Copy link
Author

I checked, and you are right, it's a very common pattern. Also, almost no Analyzer returns results, so returning results might not be a good way to do it.

This is way above my understanding for now in "Golang internals", so I will pass. I'm not even sure what to suggest.

So I will simply consider calling the analyzer directly and not add it to Requires.

Thanks for your feedback, it helped me to go deeper in my understanding

@golang golang locked and limited conversation to collaborators May 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Analysis Issues related to static analysis (vet, x/tools/go/analysis) FrozenDueToAge Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

3 participants