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

dst removes line break between /* … */ comments and package statement #69

Closed
stapelberg opened this issue Sep 23, 2022 · 8 comments
Closed

Comments

@stapelberg
Copy link

When taking the example program from the README, and adding a /* single line comment */ like so:

package main

import "github.com/dave/dst/decorator"

func main() {
	code := `/* single line comment */
package a

func main(){
	var a int    // foo
	var b string // bar
}
`
	f, err := decorator.Parse(code)
	if err != nil {
		panic(err)
	}
	if err := decorator.Print(f); err != nil {
		panic(err)
	}
}

…the output is:

/* single line comment */package a

func main() {
	var a int    // foo
	var b string // bar
}

Note how package a is now at the end of the previous line.

The same issue is reproducible with multi-line /* … */ comments.

I tested this with github.com/dave/dst v0.27.0, which is current at the time of writing.

@stapelberg
Copy link
Author

When setting a breakpoint on

r.applySpace(n, "Before", n.Decs.Before)
in gdb and print n.Decs, I can see that Before is set to 0.

When I manually change the code to hard-code dst.NewLine, the rewrite works as expected:

		r.applySpace(n, "Before", dst.NewLine) // n.Decs.Before)

So I think the question is: why does the dst.File not get its Decs.Before set correctly?

@stapelberg
Copy link
Author

Looking at this some more with the following test program:

package main

import "github.com/dave/dst/decorator"

func main() {
	code := `/*
first line
second line
last line
*/
package a

func main(){
	var a int
	/* first main line
	second main line
	last main line */
	var b string
}
`
	f, err := decorator.Parse(code)
	if err != nil {
		panic(err)
	}
	if err := decorator.Print(f); err != nil {
		panic(err)
	}
}

I see that for the FileRestorer.applyDecorations call for the second ast.DeclStmt in func main, the decorations look like this:

(dlv) p decorations
github.com/dave/dst.Decorations len: 2, cap: 2, [
	"/* first main line\n\tsecond main line\n\tlast main line */",
	"\n",
]

For comparison, the decorations for the ast.File node look like this:

(dlv) p decorations
github.com/dave/dst.Decorations len: 2, cap: 2, [
	"/*\nfirst line\nsecond line\nlast line\n*/",
	"\n",
]

So it seems like the \n is part of the dst.Decorations for multi-line comments, and n.Decs.Before being empty might be correct after all.

Maybe the issue is with restoring the decorations, then.

@dave dave closed this as completed in 5fa8d6e Dec 9, 2022
@dave dave reopened this Dec 9, 2022
@dave
Copy link
Owner

dave commented Dec 9, 2022

I just pushed a fix to master... can you give it a try?

@dave
Copy link
Owner

dave commented Dec 9, 2022

I haven't worked on this codebase for several years so I'm not exactly familiar with the micro details... but I found incrementing the cursor after the decoration for any package comment fixed this problem, and didn't fail any of the other tests... If I can find some time in the next few days I'll spend a bit longer to do a little bit more research, because I'd love to understand a bit more before tagging this as a release.

@dave
Copy link
Owner

dave commented Dec 9, 2022

... and yes you're right, I believe the decorator is working correctly by treating an inline comment on the preceding line to the node as a comment decoration then a newline decoration (this is how it treats this type of comment elsewhere in the code).

@stapelberg
Copy link
Author

I just pushed a fix to master... can you give it a try?

Thank you for the fix! I just tested it and successfully verified that it fixes the issue for me :)

@matthewhughes934
Copy link

Thanks for fixing this! I was wondering if there was any chance for a new tag to include the fix? I'm asking because I found this addresses a downstream bug I found: segmentio/golines#110

@dave
Copy link
Owner

dave commented Oct 15, 2023

OK done. v0.27.3

This has been sitting at the bottom of my todo list since I pushed that change!

@dave dave closed this as completed Oct 15, 2023
matthewhughes934 added a commit to matthewhughes934/golines-fork that referenced this issue Oct 8, 2024
Due to an upstream bug[1] if `golines` were to reformat (i.e. it
actually found a line that was too long) a file with a block comment
before the package directive, the newline before the package directive
would be stripped, e.g.

    /*
    this is a comment
    */
    package foo

Would become

    /*
    this is a comment
    */ package foo

The underlying issue has been fixed upstream, so fix here by bumping the
version of `github.com/dave/dst` to include that fix. Here's a summary of
the changes in that package from the previously used version:

    $ git log --no-merges --format='%h %s' v0.27.0..v0.27.3
    5fa8d6e Fixes segmentio#69
    bc71a76 Upgrade golang.org/x/tools to v0.1.12
    b6f3447 decorator: make an error more verbose

[1] dave/dst#69
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants