Advanced utility for golang refactor based on DSL transformations provided by bblfsh/sdk
- Go 1.13+
Build the CLI:
- clone
gofactor
repo
git clone https://github.com/lwsanty/gofactor
- build CLI
go install ./cmd/gofactor
Imagine you have a piece of code
package main
import "fmt"
func main() {
var (
i int
X int
j int
)
if i%2 == 0 {
i = 5
}
if X%2 == 0 {
X = 5
}
fmt.Println(i)
if i%2 == 0 {
i = 5
}
if j%2 == 0 {
j = 5
}
}
func a(i, X int) {
if i%2 == 0 {
i = 5
}
if X%2 == 0 {
X = 5
}
fmt.Println(i)
if i%2 == 0 {
i = 5
}
if X%2 == 0 {
X = 5
}
}
And you want to replace all code patterns like
if i%2 == 0 {
i = 5
}
if X%2 == 0 {
X = 5
}
to
if i%2 == 1 {
i = 1
} else {
X = 1
}
Here's where gofactor
tool comes for help.
Save the "before" snippet to before.txt
, "after" snippet to an after.txt
file, and run:
gofactor --before before.txt --after after.txt some_file.go
Result
package main
import "fmt"
func main() {
var (
i int
X int
j int
)
if i%2 == 1 {
i = 1
} else {
X = 1
}
fmt.Println(i)
if i%2 == 1 {
i = 1
} else {
j = 1
}
}
func a(i, X int) {
if i%2 == 1 {
i = 1
} else {
X = 1
}
fmt.Println(i)
if i%2 == 1 {
i = 1
} else {
X = 1
}
}
It is also possible to use the tools as a library.
- Init refactor object
refactor, err := gofactor.NewRefactor(beforeSnippet, afterSnippet)
if err != nil {
log.Error(err)
os.Exit(1)
}
- Apply generated transformations to the desired code
code, err := refactor.Apply(desiredCode)
if err != nil {
log.Error(err)
os.Exit(1)
}
See fixtures
- both input and output patterns are converted to go
AST
nodes - both input and output nodes converted to
bblfsh
uast.Node
s - define mapping of transformation operations from input to output node
- apply transformation mapping to the desired code: traverse over the
uast.Node
s tree and transform matching nodes - convert transformed tree back to golang
AST
- convert golang
AST
to string
- currently library copy-pastes a part fo the
bblfsh/go-driver
because of the dependency issue, fix this part - support functions refactor
- handle cases with cascade
if
s,switch
es and tail recursions - during the transformations we are forced to drop nodes positions, need to investigate the possibilities of preserving/reconstructing them(probably using DST nodes could help, related issue dave/dst#38)