Skip to content

Commit

Permalink
cmd/fillstruct: add option to select by line number.
Browse files Browse the repository at this point in the history
Fixes #3.
  • Loading branch information
davidrjenni committed Oct 13, 2017
1 parent 2fa96e6 commit fbb6762
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
1 change: 1 addition & 0 deletions cmd/fillstruct/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ Flags:
-file: filename
-modified: read an archive of modified files from stdin
-offset: byte offset of the struct literal
-line: line number of the struct literal, can be used instead of -offset
59 changes: 58 additions & 1 deletion cmd/fillstruct/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
//
// -offset: byte offset of the struct literal
//
// -line: line number of the struct literal, can be used instead of -offset
//
package main

import (
Expand Down Expand Up @@ -302,10 +304,11 @@ func main() {
filename = flag.String("file", "", "filename")
modified = flag.Bool("modified", false, "read an archive of modified files from stdin")
offset = flag.Int("offset", 0, "byte offset of the struct literal")
line = flag.Int("line", 0, "line number of the struct literal, can be used instead of -offset")
)
flag.Parse()

if *offset == 0 || *filename == "" {
if (*offset == 0 && *line == 0) || *filename == "" {
flag.PrintDefaults()
os.Exit(1)
}
Expand All @@ -321,6 +324,18 @@ func main() {
}
pkg := lprog.InitialPackages()[0]

// --- selection by line

if *line > 0 {
err = byLine(lprog, path, pkg, *line)
if err != nil {
log.Fatal(err)
}
return
}

// --- selection by offset

f, pos, err := findPos(lprog, path, *offset)
if err != nil {
log.Fatal(err)
Expand Down Expand Up @@ -390,6 +405,48 @@ func findPos(lprog *loader.Program, filename string, off int) (*ast.File, token.
return nil, 0, fmt.Errorf("could not find file %q", filename)
}

func byLine(lprog *loader.Program, filename string, pkg *loader.PackageInfo, line int) (err error) {
var f *ast.File
for _, af := range lprog.InitialPackages()[0].Files {
if file := lprog.Fset.File(af.Pos()); file.Name() == filename {
f = af
}
}
if f == nil {
return fmt.Errorf("could not find file %q", filename)
}

ast.Inspect(f, func(n ast.Node) bool {
lit, ok := n.(*ast.CompositeLit)
if !ok {
return true
}
startLine := lprog.Fset.Position(lit.Pos()).Line
endLine := lprog.Fset.Position(lit.End()).Line
if !(startLine <= line && line <= endLine) {
return true
}

name, _ := pkg.Types[lit].Type.(*types.Named)
typ, ok := pkg.Types[lit].Type.Underlying().(*types.Struct)
if !ok {
err = errors.New("no struct literal found at selection")
return false
}

startOff := lprog.Fset.Position(lit.Pos()).Offset
endOff := lprog.Fset.Position(lit.End()).Offset

newlit, lines := zeroValue(pkg.Pkg, lit, typ, name)
if err = print(newlit, lines, startOff, endOff); err != nil {
return false
}

return false
})
return err
}

func findCompositeLit(f *ast.File, info types.Info, pos token.Pos) (*ast.CompositeLit, *types.Struct, *types.Named, error) {
path, _ := astutil.PathEnclosingInterval(f, pos, pos)
for _, n := range path {
Expand Down

0 comments on commit fbb6762

Please sign in to comment.