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

Feature request: expose file names of files loaded through decorator.Load #46

Closed
mejibyte opened this issue Jun 6, 2020 · 2 comments
Closed

Comments

@mejibyte
Copy link

mejibyte commented Jun 6, 2020

Hi there! Thank you so much for this awesome library!

I want to write a small refactoring tool. The idea is to load a package, move some things around using dst, and then write the changes back to disk. I am able to load my package, do changes and print the result of each file to stdout with code like this:

func featureRequest() {
	dir := "/tmp/t"
	pkgs, err := decorator.Load(&packages.Config{Dir: dir, Mode: packages.LoadSyntax}, "root")
	if err != nil {
		panic(err)
	}
	p := pkgs[0]
	fmt.Printf("parsed %d files\n", len(p.Syntax))
	for _, f := range p.Syntax {
		b := f.Decls[0].(*dst.FuncDecl).Body
		b.List = append(b.List, &dst.ExprStmt{
			X: &dst.CallExpr{
				Fun: &dst.Ident{Path: "fmt", Name: "Println"},
				Args: []dst.Expr{
					&dst.BasicLit{Kind: token.STRING, Value: strconv.Quote("Hello, World!")},
				},
			},
		})

		fmt.Println("=====================================")
		r := decorator.NewRestorerWithImports("root", gopackages.New(dir))
		if err := r.Print(f); err != nil {
			panic(err)
		}
	}
}

This successfully loads the files, applies changes and resolves the imports (great!). Here's the output of calling the function above (I have these files in my /tmp/t directory: main.go, sum.go and go.mod):

$ go run ./cmd/refactorer/main.go 
parsed 2 files
=====================================
package main

import "fmt"

func sum(int x, int y) {
	_ = x + y
	fmt.Println("Hello, World!")
}
=====================================
package main

import "fmt"

func main() { fmt.Println("Hello, World!") }

However, as far as I could see, the paths of .go files that were loaded are not exposed anywhere. This means at the moment I can't write the changes back to disk because I don't know which parsed file inside p.Syntax corresponds to which path.

It would be awesome if we could expose the file names in the struct returned by decorator.Load, perhaps by converting Syntax:

Syntax []*dst.File
to a map where keys are filenames, similar to:

dst/dst.go

Line 674 in ce1c8af

Files map[string]*File // Go source files by filename
.

@dave
Copy link
Owner

dave commented Jun 6, 2020

I think Decorator.Filenames is what you're looking for?

so:

...
	for _, f := range p.Syntax {
		fmt.Println("Filename:", p.Decorator.Filenames[f]) // <---- ADD THIS
...

@mejibyte
Copy link
Author

@dave yup, that worked! I can't believe I missed that one. Thanks a lot!

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

2 participants