-
Notifications
You must be signed in to change notification settings - Fork 41
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
fix: use adjusted position #156
Conversation
Thanks! How will this work with |
No, this is not related because currently, wsl doesn't work with cgo. When using cgo, the non-adjusted file is never a Lines 85 to 88 in c862f08
Currently, 95% of the linters don't work with yacc. golangci/golangci-lint#1779 (comment) And wsl is a part of the 95%. Now, I think it's better to support cgo first, and the yacc topic will be handled after with all the other linters. |
FYI, I don't know if this is expected but some of your test files inside |
Nope, that doesn't sound expected at all, will have a look.
Sounds good to me, but if the Either way, I'm happy to just merge this because this but feels better to understand the full context so hence why I'm asking. |
I just used this as an example because it's easy to see the problem, but the positions should also be adjusted for cgo to have the right positions because when using cgo the file content is not a real file content but a generated file. for example: // Code generated by cmd/cgo; DO NOT EDIT.
//line /home/ldez/sources/golangci/golangci-lint/pkg/golinters/goimports/testdata/goimports_cgo.go:1:1
//golangcitest:args -Egoimports
package testdata
/*
#include <stdio.h>
#include <stdlib.h>
void myprint(char* s) {
printf("%d\n", s);
}
*/
import _ "unsafe"
import (
"unsafe"
)
import (
"fmt" // want "File is not `goimports`-ed"
"github.com/golangci/golangci-lint/pkg/config"
)
func _() {
cs := ( /*line :24:8*/_Cfunc_CString /*line :24:16*/)("Hello from stdio\n")
( /*line :25:2*/_Cfunc_myprint /*line :25:10*/)(cs)
func() { _cgo0 := /*line :26:9*/unsafe.Pointer(cs); _cgoCheckPointer(_cgo0, nil); /*line :26:28*/_Cfunc_free(_cgo0); }()
}
func Bar() {
fmt.Print("x")
_ = config.Config{}
} instead of //golangcitest:args -Egoimports
package testdata
/*
#include <stdio.h>
#include <stdlib.h>
void myprint(char* s) {
printf("%d\n", s);
}
*/
import "C"
import (
"unsafe"
)
import (
"fmt" // want "File is not `goimports`-ed"
"github.com/golangci/golangci-lint/pkg/config"
)
func _() {
cs := C.CString("Hello from stdio\n")
C.myprint(cs)
C.free(unsafe.Pointer(cs))
}
func Bar() {
fmt.Print("x")
_ = config.Config{}
}
You are not slow, this is not trivial to understand. |
Cool, thanks! I'm still not sure about the I think the same code path exist in other linters such as The thing is, in a lot of cases I don't want to analyze non go files. I actually created golang/go#41771 back in 2020 but closed it since it wasn't really right and then again golang/go#64436 a year ago but closed it as a duplicate. I closed it because the comments in golang/go#43481 suggested that filtering in or out specific files was the facto the recommended way. |
Yes I recommend removing it because this is not required. |
I used your snippet, added logs, added a package with cgo content and line directive. code
package main
import (
"go/ast"
"log"
"strings"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/singlechecker"
)
var Analyzer = &analysis.Analyzer{
Name: "example",
Doc: "example",
Run: run,
}
func run(pass *analysis.Pass) (interface{}, error) {
for _, file := range pass.Files {
filename := pass.Fset.PositionFor(file.Pos(), false).Filename
log.Println("Is .go?", strings.HasSuffix(filename, ".go"), ":", "IsGenerated", ast.IsGenerated(file), ":", filename)
}
return nil, nil
}
func main() {
singlechecker.Main(Analyzer)
} package cgo
/*
#include "math.h"
double add(double a, double b) {
return a + b;
}
*/
import "C"
import "fmt"
func Foo() {
fmt.Println(C.floor(C.add(1, 2.1)))
} //line hello.tmpl:1
package line
import (
"fmt"
"golang.org/x/tools/go/analysis"
)
func _() {
var x int
_ = x
x = 0 // x
}
func main() {
a()
b()
wsl()
}
func a() {
fmt.Println("foo")
}
func b() {
fmt.Println("foo")
}
func c() {
_ = analysis.Analyzer{}
}
func wsl() bool {
return true
}
func notFormatted() {
} # This is a template file for some code generator, and is not a valid go source file. output# adjusted: false
$ go run . ./...
example: Is .go? false : IsGenerated true : /home/ldez/.cache/go-build/42/42102fe476e4a606613a5b565e71218d109f6b06a5dfb121e376f66de471497b-d
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/line/line.go
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main.go
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main_test.go
example: Is .go? false : IsGenerated true : /home/ldez/.cache/go-build/62/6248342cd6ede467fbde8a115d730d771a2fcb65488a2bf6ac6dd981cfcf0e6b-d
example: Is .go? false : IsGenerated true : /home/ldez/.cache/go-build/d2/d202ddb4ff2eb75186fb85b2d45b3abbede18e343180e149a0ae28f0849fa877-d
example: Is .go? false : IsGenerated false : /home/ldez/.cache/go-build/52/52709e04346f162eeabb16dbe9df656d978effaafca09c371368789c95dd32d3-d
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main.go # adjusted: true
$ go run . ./...
example: Is .go? false : IsGenerated true : /home/ldez/.cache/go-build/42/42102fe476e4a606613a5b565e71218d109f6b06a5dfb121e376f66de471497b-d
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main.go
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main.go
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main_test.go
example: Is .go? false : IsGenerated true : /home/ldez/.cache/go-build/62/6248342cd6ede467fbde8a115d730d771a2fcb65488a2bf6ac6dd981cfcf0e6b-d
example: Is .go? true : IsGenerated true : /home/ldez/sources/golangci/sandbox/cgo/cgo.go
example: Is .go? false : IsGenerated false : /home/ldez/.cache/go-build/52/52709e04346f162eeabb16dbe9df656d978effaafca09c371368789c95dd32d3-d
example: Is .go? false : IsGenerated false : /home/ldez/sources/golangci/sandbox/line/hello.tmpl About cgo: First, the So when using non-adjusted positions cgo files are skipped by About line directives: First, the Second, when using adjusted positions, the template comes in the files, and the So to handle both elements: codepackage main
import (
"go/ast"
"go/token"
"log"
"strings"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/singlechecker"
)
var Analyzer = &analysis.Analyzer{
Name: "example",
Doc: "example",
Run: run,
}
func run(pass *analysis.Pass) (interface{}, error) {
for _, file := range pass.Files {
GetFilename(pass.Fset, file)
filename := GetFilename(pass.Fset, file)
log.Println("Is .go?", strings.HasSuffix(filename, ".go"), ":", "IsGenerated", ast.IsGenerated(file), ":", filename)
}
return nil, nil
}
func GetFilename(fset *token.FileSet, file *ast.File) string {
filename := fset.PositionFor(file.Pos(), true).Filename // same as fset.Position()
if !strings.HasSuffix(filename, ".go") {
return fset.PositionFor(file.Pos(), false).Filename
}
return filename
}
func main() {
singlechecker.Main(Analyzer)
} output$ go run . ./...
example: Is .go? false : IsGenerated true : /home/ldez/.cache/go-build/42/42102fe476e4a606613a5b565e71218d109f6b06a5dfb121e376f66de471497b-d
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main.go
example: Is .go? false : IsGenerated true : /home/ldez/.cache/go-build/62/6248342cd6ede467fbde8a115d730d771a2fcb65488a2bf6ac6dd981cfcf0e6b-d
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main_test.go
example: Is .go? true : IsGenerated true : /home/ldez/sources/golangci/sandbox/cgo/cgo.go
example: Is .go? false : IsGenerated false : /home/ldez/.cache/go-build/52/52709e04346f162eeabb16dbe9df656d978effaafca09c371368789c95dd32d3-d
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/main.go
example: Is .go? true : IsGenerated false : /home/ldez/sources/golangci/sandbox/line/line.go Now it's possible to see all the files (go, cgo, line). So now you can understand why I said the line directive/yacc is a dedicated topic. Also, I think that using I have learned a lot with the suggested fixes PR, but I'm still not an expert, I'm still learning. |
The position must be adjusted to work with cgo.