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

go/printer: comment before func output position wrong #54195

Closed
Mericusta opened this issue Aug 2, 2022 · 2 comments
Closed

go/printer: comment before func output position wrong #54195

Mericusta opened this issue Aug 2, 2022 · 2 comments

Comments

@Mericusta
Copy link

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

$ go version
go version go1.18.5 windows/amd64

Does this issue reproduce with the latest release?

Yes

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

go env Output
$ go env
set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Mericustar\AppData\Local\go-build
set GOENV=C:\Users\Mericustar\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set GOWORK=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\MERICU~1\AppData\Local\Temp\go-build1026855593=/tmp/go-build -gno-record-gcc-switches

What did you do?

package astfoo

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"os"
)

func FormatFoo(parseFilePath, outputFunction string) {
	fileContent := `
package algorithmfoo

import (
	"strings"
)

// ConvertCamelCase2SnakeCaseWithPhrase 将驼峰命名法转换为蛇形命名法:XxxYyyZzz -> xxx_yyy_zzz
// Abc 开头 | 中间 DONE
// ABC 开头 | 中间
func ConvertCamelCase2SnakeCaseWithPhrase(camelCase string, phraseMap map[string]struct{}) string {
	builder := strings.Builder{}
	// ...
	return builder.String()
}

`

	fileAST, err := parser.ParseFile(token.NewFileSet(), "", fileContent, parser.ParseComments)
	if err != nil {
		panic(err)
	}

	outputFile, err := os.OpenFile(fmt.Sprintf("%v.bak", parseFilePath), os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
	if err != nil {
		panic(err)
	}
	defer outputFile.Close()

	buffer := &bytes.Buffer{}
	if fileAST.Scope != nil {
		for name, object := range fileAST.Scope.Objects {
			if object.Kind == ast.Fun && name == outputFunction {
				decl := object.Decl.(*ast.FuncDecl)
				if declLen := decl.End() - decl.Pos(); buffer.Cap() < int(declLen) {
					buffer.Grow(int(declLen))
				}
				err = format.Node(buffer, token.NewFileSet(), decl)
				if err != nil {
					panic(err)
				}
				outputFile.Write(buffer.Bytes())
				buffer.Reset()
				break
			}
		}
	}
}

test file:

package astfoo

import (
	"io/fs"
	"reflect"
	"testing"
)

func TestFormatFoo(t *testing.T) {
	type args struct {
		parseFilePath  string
		outputFunction string
	}
	tests := []struct {
		name string
		args args
	}{
		// TODO: Add test cases.
		{
			"test case 1",
			args{
				parseFilePath:  ".\\tmp.go",
				outputFunction: "ConvertCamelCase2SnakeCaseWithPhrase",
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			FormatFoo(tt.args.parseFilePath, tt.args.outputFunction)
		})
	}
}

What did you expect to see?

output to file:

// ConvertCamelCase2SnakeCaseWithPhrase 将驼峰命名法转换为蛇形命名法:XxxYyyZzz -> xxx_yyy_zzz
// Abc 开头 | 中间 DONE
// ABC 开头 | 中间
func ConvertCamelCase2SnakeCaseWithPhrase(camelCase string, phraseMap map[string]struct{}) string {
	builder := strings.Builder{}
	return builder.String()
}

What did you see instead?

output to file:

func ConvertCamelCase2SnakeCaseWithPhrase(camelCase string, phraseMap map // ConvertCamelCase2SnakeCaseWithPhrase 将驼峰命名法转换为蛇形命名法:XxxYyyZzz -> xxx_yyy_zzz
// Abc 开头 | 中间 DONE
// ABC 开头 | 中间
[string]struct{}) string {
	builder := strings.Builder{}
	return builder.String()
}
@jacobishao
Copy link
Contributor

jacobishao commented Aug 2, 2022

`package main

import (
"bytes"
"fmt"
"go/ast"
"go/format"
"go/parser"
"go/token"
"os"
)

func FormatFoo(parseFilePath, outputFunction string) {
fileContent := `
package algorithmfoo

import (
"strings"
)

// ConvertCamelCase2SnakeCaseWithPhrase 将驼峰命名法转换为蛇形命名法:XxxYyyZzz -> xxx_yyy_zzz
// Abc 开头 | 中间 DONE
// ABC 开头 | 中间
func ConvertCamelCase2SnakeCaseWithPhrase(camelCase string, phraseMap map[string]struct{}) string {
builder := strings.Builder{}
// ...
return builder.String()
}

`
fs := token.NewFileSet()
fileAST, err := parser.ParseFile(fs, "", fileContent, parser.ParseComments)
if err != nil {
panic(err)
}

outputFile, err := os.OpenFile(fmt.Sprintf("%v.bak", parseFilePath), os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0644)
if err != nil {
	panic(err)
}
defer outputFile.Close()

buffer := &bytes.Buffer{}
if fileAST.Scope != nil {
	for name, object := range fileAST.Scope.Objects {
		if object.Kind == ast.Fun && name == outputFunction {
			decl := object.Decl.(*ast.FuncDecl)
			if declLen := decl.End() - decl.Pos(); buffer.Cap() < int(declLen) {
				buffer.Grow(int(declLen))
			}
			err = format.Node(buffer, fs, decl)
			if err != nil {
				panic(err)
			}
			outputFile.Write(buffer.Bytes())
			buffer.Reset()
			break
		}
	}
}

}

func main() {
FormatFoo("a.go", "ConvertCamelCase2SnakeCaseWithPhrase")
}
`

@Mericusta I think you use the wrong fileSet, this code is ok.

@Mericusta
Copy link
Author

Thanks for your reply, I got it.

@golang golang locked and limited conversation to collaborators Aug 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants