本文整理匯總了Golang中rsc/io/grind/grinder.EditBuffer類的典型用法代碼示例。如果您正苦於以下問題:Golang EditBuffer類的具體用法?Golang EditBuffer怎麽用?Golang EditBuffer使用的例子?那麽, 這裏精選的類代碼示例或許可以為您提供幫助。
在下文中一共展示了EditBuffer類的9個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: grindFunc
func grindFunc(ctxt *grinder.Context, pkg *grinder.Package, edit *grinder.EditBuffer, fn *ast.FuncDecl) {
if fn.Name.Name == "evconst" {
old := debug
debug = true
defer func() { debug = old }()
}
if pkg.TypesError != nil {
// Without scoping information, we can't be sure code moves are okay.
fmt.Printf("%s: cannot inline gotos without type information\n", fn.Name)
return
}
if fn.Body == nil {
return
}
blocks := block.Build(pkg.FileSet, fn.Body)
for labelname, gotos := range blocks.Goto {
target, ok := findTargetBlock(pkg, edit, fn, blocks, labelname)
if debug {
println("TARGET", ok, labelname, len(gotos), target.dead, target.short)
}
if ok && (len(gotos) == 1 && target.dead || target.short) {
numReplaced := 0
for _, g := range gotos {
code := edit.TextAt(target.comment, target.start) + target.code
if !objsMatch(pkg, fn, g.Pos(), target.objs, target.start, target.end) {
if debug {
println("OBJS DO NOT MATCH")
}
// Cannot inline code here; needed identifiers have different meanings.
continue
}
if target.needReturn {
// NOTE: Should really check to see if function results are shadowed.
// If we screw up, the code won't compile, so we can put it off.
code += "; return"
}
if target.needGoto != "" {
code += "; goto " + target.needGoto
}
edit.Replace(g.Pos(), g.End(), code)
numReplaced++
}
if numReplaced == len(gotos) {
if len(gotos) == 1 && target.dead {
edit.Delete(target.comment, target.end)
} else {
edit.DeleteLine(target.start, target.endLabel)
}
}
// The code we move might itself have gotos to inline,
// and we can't make that change until we get new line
// number position, so return after each label change.
if numReplaced > 0 {
return
}
}
}
}
示例2: hasType
func hasType(pkg *grinder.Package, fn *ast.FuncDecl, edit *grinder.EditBuffer, x, v ast.Expr) bool {
// Does x (by itself) default to v's type?
// Find the scope in which x appears.
xScope := pkg.Info.Scopes[fn.Type]
ast.Inspect(fn.Body, func(z ast.Node) bool {
if z == nil {
return false
}
if x.Pos() < z.Pos() || z.End() <= x.Pos() {
return false
}
scope := pkg.Info.Scopes[z]
if scope != nil {
xScope = scope
}
return true
})
xs := edit.TextAt(x.Pos(), x.End())
xt, err := types.Eval(pkg.FileSet, pkg.Types, xScope.Pos(), xs)
if err != nil {
return false
}
vt := pkg.Info.Types[v]
if types.Identical(xt.Type, vt.Type) {
return true
}
// Might be untyped.
vb, ok1 := vt.Type.(*types.Basic)
xb, ok2 := xt.Type.(*types.Basic)
if ok1 && ok2 {
switch xb.Kind() {
case types.UntypedInt:
return vb.Kind() == types.Int
case types.UntypedBool:
return vb.Kind() == types.Bool
case types.UntypedRune:
return vb.Kind() == types.Rune
case types.UntypedFloat:
return vb.Kind() == types.Float64
case types.UntypedComplex:
return vb.Kind() == types.Complex128
case types.UntypedString:
return vb.Kind() == types.String
}
}
return false
}
示例3: placeInit
func placeInit(edit *grinder.EditBuffer, start token.Pos, obj *ast.Object, decl *ast.DeclStmt, list []ast.Stmt) ast.Node {
declPos := -1
i := 0
for i < len(list) && edit.End(list[i]) < start {
if unlabel(list[i]) == decl {
declPos = i
}
i++
}
if i >= len(list) {
panic(fmt.Sprintf("unexpected start position"))
}
switch x := unlabel(list[i]).(type) {
case *ast.AssignStmt:
if canDeclare(x, obj) {
return x
}
}
if declPos >= 0 && allSimple(list[declPos:i]) {
return decl
}
for j := i + 1; j < len(list); j++ {
if unlabel(list[j]) == decl {
if allSimple(list[i:j]) {
return decl
}
break
}
}
x := list[i]
for {
xx, ok := x.(*ast.LabeledStmt)
if !ok || xx.Stmt.Pos() > start {
break
}
x = xx.Stmt
}
return &ast.EmptyStmt{
Semicolon: x.Pos(),
}
}
示例4: isNilPtr
func isNilPtr(pkg *grinder.Package, edit *grinder.EditBuffer, x ast.Expr) (typ string, ok bool) {
conv, ok := x.(*ast.CallExpr)
if !ok || len(conv.Args) != 1 {
return "", false
}
id, ok := unparen(conv.Args[0]).(*ast.Ident)
if !ok || id.Name != "nil" {
return "", false
}
if obj := pkg.Info.Uses[id]; obj == nil || obj.Pkg() != nil {
return "", false
}
fn := unparen(conv.Fun)
tv, ok := pkg.Info.Types[fn]
if !ok || !tv.IsType() {
return "", false
}
return edit.TextAt(fn.Pos(), fn.End()), true
}
示例5: isStructOrArrayLiteral
func isStructOrArrayLiteral(pkg *grinder.Package, edit *grinder.EditBuffer, x ast.Expr) (typ string, ok bool) {
lit, ok := x.(*ast.CompositeLit)
if !ok || len(lit.Elts) > 0 {
return "", false
}
tv, ok := pkg.Info.Types[x]
if !ok {
return "", false
}
t := tv.Type
if name, ok := t.(*types.Named); ok {
t = name.Underlying()
}
switch t.(type) {
default:
return "", false
case *types.Struct, *types.Array:
// ok
}
return edit.TextAt(lit.Type.Pos(), lit.Type.End()), true
}
示例6: grindFunc
func grindFunc(ctxt *grinder.Context, pkg *grinder.Package, edit *grinder.EditBuffer, fn *ast.FuncDecl) {
if fn.Body == nil {
return
}
blocks := block.Build(pkg.FileSet, fn.Body)
ast.Inspect(fn.Body, func(x ast.Node) bool {
var list []ast.Stmt
switch x := x.(type) {
default:
return true
case *ast.BlockStmt:
list = x.List
case *ast.CommClause:
list = x.Body
case *ast.CaseClause:
list = x.Body
}
for i := 0; i < len(list); i++ {
x := list[i]
if grinder.IsTerminatingStmt(blocks, x) {
end := i + 1
for end < len(list) && !isGotoTarget(blocks, list[end]) {
end++
}
if end > i+1 {
edit.Delete(edit.End(x), edit.End(list[end-1]))
i = end - 1 // after i++, next iteration starts at end
}
}
}
return true
})
}
示例7: initToDecl
func initToDecl(ctxt *grinder.Context, pkg *grinder.Package, edit *grinder.EditBuffer, fn *ast.FuncDecl) {
// Rewrite x := T{} (for struct or array type T) and x := (*T)(nil) to var x T.
ast.Inspect(fn.Body, func(x ast.Node) bool {
list := grinder.BlockList(x)
for _, stmt := range list {
as, ok := stmt.(*ast.AssignStmt)
if !ok || len(as.Lhs) > 1 || as.Tok != token.DEFINE {
continue
}
var typ string
if t, ok := isNilPtr(pkg, edit, as.Rhs[0]); ok {
typ = t
} else if t, ok := isStructOrArrayLiteral(pkg, edit, as.Rhs[0]); ok {
typ = t
}
if typ != "" {
edit.Replace(stmt.Pos(), stmt.End(), "var "+as.Lhs[0].(*ast.Ident).Name+" "+typ)
}
}
return true
})
}
示例8: grindFunc
func grindFunc(ctxt *grinder.Context, pkg *grinder.Package, edit *grinder.EditBuffer, fn *ast.FuncDecl) {
vars := analyzeFunc(pkg, edit, fn.Body)
// fmt.Printf("%s", vardecl.PrintVars(conf.Fset, vars))
for _, v := range vars {
spec := v.Decl.Decl.(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
if len(spec.Names) > 1 {
// TODO: Handle decls with multiple variables
continue
}
if pkg.FileSet.Position(v.Decl.Pos()).Line != pkg.FileSet.Position(v.Decl.End()).Line {
// Declaration spans line. Maybe not great to move or duplicate?
continue
}
keepDecl := false
for _, d := range v.Defs {
if d.Init == v.Decl {
keepDecl = true
continue
}
switch x := d.Init.(type) {
default:
panic("unexpected init")
case *ast.EmptyStmt:
edit.CopyLine(v.Decl.Pos(), v.Decl.End(), x.Semicolon)
case *ast.AssignStmt:
edit.Insert(x.TokPos, ":")
if !hasType(pkg, fn, edit, x.Rhs[0], x.Lhs[0]) {
typ := edit.TextAt(spec.Type.Pos(), spec.Type.End())
if strings.Contains(typ, " ") || typ == "interface{}" || typ == "struct{}" || strings.HasPrefix(typ, "*") {
typ = "(" + typ + ")"
}
edit.Insert(x.Rhs[0].Pos(), typ+"(")
edit.Insert(x.Rhs[0].End(), ")")
}
}
}
if !keepDecl {
edit.DeleteLine(v.Decl.Pos(), v.Decl.End())
}
}
if edit.NumEdits() == 0 {
initToDecl(ctxt, pkg, edit, fn)
}
}
示例9: findTargetBlock
func findTargetBlock(pkg *grinder.Package, edit *grinder.EditBuffer, fn *ast.FuncDecl, blocks *block.Graph, labelname string) (target targetBlock, ok bool) {
if debug {
println("FINDTARGET", labelname)
}
lstmt := blocks.Label[labelname]
if lstmt == nil {
return
}
list := grinder.BlockList(blocks.Map[lstmt].Root)
if list == nil {
return
}
ulstmt := grinder.Unlabel(lstmt)
for i := 0; i < len(list); i++ {
if grinder.Unlabel(list[i]) == ulstmt {
// Found statement. Find extent of block.
if debug {
println("FOUND")
}
end := i
for ; ; end++ {
if end >= len(list) {
if debug {
println("EARLY END")
}
// List ended without terminating statement.
// Unless this is the top-most block, we can't hoist this code.
if blocks.Map[lstmt].Root != fn.Body {
return
}
// Top-most block. Implicit return at end of list.
target.needReturn = true
break
}
if end > i && grinder.IsGotoTarget(blocks, list[end]) {
if debug {
println("FOUND TARGET")
}
target.needGoto = list[end].(*ast.LabeledStmt).Label.Name
break
}
if grinder.IsTerminatingStmt(blocks, list[end]) {
if debug {
println("TERMINATING")
}
end++
break
}
}
if end <= i {
if debug {
println("NOTHING")
}
return
}
if debug {
println("OK")
}
target.dead = i > 0 && grinder.IsTerminatingStmt(blocks, list[i-1])
target.start = lstmt.Pos()
target.comment = edit.BeforeComments(target.start)
target.endLabel = lstmt.Colon + 1
target.end = edit.End(list[end-1])
target.code = strings.TrimSpace(edit.TextAt(lstmt.Colon+1, target.end))
target.short = end == i+1 && (isReturn(grinder.Unlabel(list[i])) || isEmpty(grinder.Unlabel(list[i])) && target.needReturn)
target.objs = gatherObjs(pkg, fn, lstmt.Pos(), list[i:end])
return target, true
}
}
return
}