Modifying AST and preserving comments

584 views
Skip to first unread message

Traun Leyden

unread,
Mar 26, 2018, 11:32:17 PM3/26/18
to golang-nuts

I'm trying to modify a source file and replace some function parameters based on their names.  I was able to get some basics working by following this tutorial, however when I write the new file, it's deleting the existing comments.

It looks like just the act of reading in the source and rewriting it is stripping the comments:


func main() {

      // --------------- Start test file contents
	testFileContents := `
      //  Licensed under the Apache License...
      package main
      const (
        kMaxRecentSequences = 20 // Maximum number of sequences stored in RecentSequences before pruning is triggered
      )
      //////// READING DOCUMENTS:
      func fakeFunc(docid string) string {
        return docid
      }
      func main() {
        fakeFunc("foo")  // Call fakeFunc
      }`
      // --------------- End test file contents

	err := ioutil.WriteFile("/tmp/source.go", []byte(testFileContents), 0644)
	if err != nil {
		log.Fatal(err)
	}

	fset := token.NewFileSet()
	node, err := parser.ParseFile(fset, "/tmp/source.go", nil, 0)
	if err != nil {
		log.Fatal(err)
	}

	ast.Inspect(node, func(n ast.Node) bool {
		return true
	})

	f, err := os.Create("/tmp/source_modified.go")
	defer f.Close()
	if err := printer.Fprint(f, fset, node); err != nil {
		log.Fatal(err)
	}

}

The rewritten source code in /tmp/source_modified.go is:

package main

const (
	kMaxRecentSequences = 20
)

func fakeFunc(docid string) string {
	return docid
}

func main() {
	fakeFunc("foo")
}


What's the best way to manipulate the AST while preserving comments?  Would using https://godoc.org/golang.org/x/tools/go/ast/astutil#Apply improve the situation?


Fatih Arslan

unread,
Mar 27, 2018, 7:29:56 AM3/27/18
to Traun Leyden, golang-nuts
Best way I found is to print the whole file and then substract the parts you're interested. The reason for that is that comments are two fold. Some of the comments are part of the node, some of them are part of *ast.File (also called lossy comments). If you just print the node, you'll don't get the ones that are part of the file. Here is an example how I use this technique for gomodifytags: https://github.com/fatih/gomodifytags/blob/master/main.go#L470 


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Fatih Arslan
Reply all
Reply to author
Forward
0 new messages