src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

edit.go (2042B)


      1 // Package edit contains helpers for creating suggested fixes.
      2 package edit
      3 
      4 import (
      5 	"bytes"
      6 	"go/ast"
      7 	"go/format"
      8 	"go/token"
      9 
     10 	"golang.org/x/tools/go/analysis"
     11 	"honnef.co/go/tools/pattern"
     12 )
     13 
     14 // Ranger describes values that have a start and end position.
     15 // In most cases these are either ast.Node or manually constructed ranges.
     16 type Ranger interface {
     17 	Pos() token.Pos
     18 	End() token.Pos
     19 }
     20 
     21 // Range implements the Ranger interface.
     22 type Range [2]token.Pos
     23 
     24 func (r Range) Pos() token.Pos { return r[0] }
     25 func (r Range) End() token.Pos { return r[1] }
     26 
     27 // ReplaceWithString replaces a range with a string.
     28 func ReplaceWithString(old Ranger, new string) analysis.TextEdit {
     29 	return analysis.TextEdit{
     30 		Pos:     old.Pos(),
     31 		End:     old.End(),
     32 		NewText: []byte(new),
     33 	}
     34 }
     35 
     36 // ReplaceWithNode replaces a range with an AST node.
     37 func ReplaceWithNode(fset *token.FileSet, old Ranger, new ast.Node) analysis.TextEdit {
     38 	buf := &bytes.Buffer{}
     39 	if err := format.Node(buf, fset, new); err != nil {
     40 		panic("internal error: " + err.Error())
     41 	}
     42 	return analysis.TextEdit{
     43 		Pos:     old.Pos(),
     44 		End:     old.End(),
     45 		NewText: buf.Bytes(),
     46 	}
     47 }
     48 
     49 // ReplaceWithPattern replaces a range with the result of executing a pattern.
     50 func ReplaceWithPattern(fset *token.FileSet, old Ranger, new pattern.Pattern, state pattern.State) analysis.TextEdit {
     51 	r := pattern.NodeToAST(new.Root, state)
     52 	buf := &bytes.Buffer{}
     53 	format.Node(buf, fset, r)
     54 	return analysis.TextEdit{
     55 		Pos:     old.Pos(),
     56 		End:     old.End(),
     57 		NewText: buf.Bytes(),
     58 	}
     59 }
     60 
     61 // Delete deletes a range of code.
     62 func Delete(old Ranger) analysis.TextEdit {
     63 	return analysis.TextEdit{
     64 		Pos:     old.Pos(),
     65 		End:     old.End(),
     66 		NewText: nil,
     67 	}
     68 }
     69 
     70 func Fix(msg string, edits ...analysis.TextEdit) analysis.SuggestedFix {
     71 	return analysis.SuggestedFix{
     72 		Message:   msg,
     73 		TextEdits: edits,
     74 	}
     75 }
     76 
     77 // Selector creates a new selector expression.
     78 func Selector(x, sel string) *ast.SelectorExpr {
     79 	return &ast.SelectorExpr{
     80 		X:   &ast.Ident{Name: x},
     81 		Sel: &ast.Ident{Name: sel},
     82 	}
     83 }