func DeleteNode(fset *token.FileSet, filename string, file *ast.File, posStart, posEnd token.Position) (bool, *errors.GoRefactorError) { tokFile := GetFileFromFileSet(fset, filename) if tokFile == nil { return false, errors.PrinterError("couldn't find file " + filename + " in fileset") } node := FindNode(fset, file, posStart, posEnd) if node == nil { return false, errors.PrinterError("couldn't find node with given positions") } lines := GetLines(tokFile) for i, offset := range lines { fmt.Printf("%d -> %s(%d)\n", i+1, fset.Position(tokFile.Pos(offset)), offset) } nodeLines, firstLine := GetRangeLines(tokFile, node.Pos(), node.End(), tokFile.Size()) if _, ok := deleteNode(fset, posStart, posEnd, file); !ok { return false, errors.PrinterError("didn't find node to delete") } deleteCommentsInRange(file, node.Pos(), node.End()) inc := -int(node.End() - node.Pos()) fmt.Printf("\n%v, %v, mod = %v\n", nodeLines, firstLine, inc) FixPositions(node.Pos(), inc, file, true) tokFile.SetLines(removeLinesOfRange(tokFile.Offset(node.Pos()), tokFile.Offset(node.End()), lines, nodeLines, firstLine)) return true, nil }
func AddDecl(fset *token.FileSet, filename string, file *ast.File, withFileSet *token.FileSet, withFileName string, withFile *ast.File, withPosStart, withPosEnd token.Position, identMap st.IdentifierMap) (bool, *token.FileSet, *ast.File, *errors.GoRefactorError) { withNode := FindNode(withFileSet, withFile, withPosStart, withPosEnd) if withNode == nil { return false, nil, nil, errors.PrinterError("couldn't find node with given positions") } if _, ok := withNode.(ast.Decl); !ok { return false, nil, nil, errors.PrinterError("node is not a declaration") } withTokFile := GetFileFromFileSet(withFileSet, withFileName) withOldSize := withTokFile.Size() l := int(withNode.End() - withNode.Pos()) fset, file = ReparseFile(file, filename, l, identMap) if filename == withFileName { withFileSet, withFile = fset, file withNode = FindNode(withFileSet, withFile, withPosStart, withPosEnd) } withNode = utils.CopyAstNode(withNode) tokFile := GetFileFromFileSet(fset, filename) withTokFile = GetFileFromFileSet(withFileSet, withFileName) if tokFile == nil || withTokFile == nil { return false, nil, nil, errors.PrinterError("couldn't find file " + filename + " in fileset") } lines := GetLines(tokFile) fmt.Printf("linesCount = %d\n", len(lines)) tokFile.SetLines(lines[:len(lines)-(l)]) lines = GetLines(tokFile) for i, offset := range lines { fmt.Printf("%d -> %s(%d)\n", i+1, fset.Position(tokFile.Pos(offset)), offset) } withNodeLines, _ := GetRangeLines(withTokFile, withNode.Pos(), withNode.End(), withOldSize) withMod := int(tokFile.Offset(file.Decls[len(file.Decls)-1].End()) + 1 - withTokFile.Offset(withNode.Pos())) fmt.Printf("withMod: %v\n", withMod) for i, _ := range withNodeLines { withNodeLines[i] += withMod } tokFile.SetLines(addLinesOfRange(withTokFile.Offset(withNode.Pos()), withTokFile.Offset(withNode.End()), lines, withNodeLines, -1)) //to the end file.Decls = append(file.Decls, withNode.(ast.Decl)) return true, fset, file, nil }
func RenameIdents(fset *token.FileSet, identMap st.IdentifierMap, filename string, file *ast.File, positions []token.Position, name string) (bool, *token.FileSet, *ast.File, *errors.GoRefactorError) { l := len(positions) id, ok := FindIdentByPos(fset, file, positions[0]) if !ok { return false, nil, nil, errors.PrinterError("couldn't find ident at " + positions[0].String()) } delta := len(name) - len(id.Name) if delta > 0 { fset, file = ReparseFile(file, filename, delta*l, identMap) } for _, p := range positions { if p.Filename != filename { return false, nil, nil, errors.PrinterError("positions array contain position with wrong filename") } if id, ok := FindIdentByPos(fset, file, p); ok { id.Name = name } else { return false, nil, nil, errors.PrinterError("couldn't find ident at " + p.String()) } } return true, fset, file, nil }
func DeleteNodeList(fset *token.FileSet, filename string, file *ast.File, list interface{}) (bool, *errors.GoRefactorError) { tokFile := GetFileFromFileSet(fset, filename) if tokFile == nil { return false, errors.PrinterError("couldn't find file " + filename + " in fileset") } lines := GetLines(tokFile) for i, offset := range lines { fmt.Printf("%d -> %s(%d)\n", i+1, fset.Position(tokFile.Pos(offset)), offset) } var pos, end token.Pos switch t := list.(type) { case []ast.Stmt: pos, end = t[0].Pos(), t[len(t)-1].End() fmt.Printf("list pos,end = %d,%d\n", pos, end) } rangeLines, firstLine := GetRangeLines(tokFile, pos, end, tokFile.Size()) switch t := list.(type) { case []ast.Stmt: for _, n := range t { if _, ok := deleteNode(fset, fset.Position(n.Pos()), fset.Position(n.End()), file); !ok { return false, errors.PrinterError("didn't find node to delete") } } } deleteCommentsInRange(file, pos, end) inc := -int(end - pos) fmt.Printf("\n%v, %v, mod = %v\n", rangeLines, firstLine, inc) FixPositions(pos, inc, file, true) tokFile.SetLines(removeLinesOfRange(tokFile.Offset(pos), tokFile.Offset(end), lines, rangeLines, firstLine)) return true, nil }
func ReplaceNode(fset *token.FileSet, filename string, file *ast.File, posStart, posEnd token.Position, withFileSet *token.FileSet, withFileName string, withFile *ast.File, withPosStart, withPosEnd token.Position, identMap st.IdentifierMap) (bool, *token.FileSet, *ast.File, *errors.GoRefactorError) { tokFile := GetFileFromFileSet(fset, filename) withTokFile := GetFileFromFileSet(withFileSet, withFileName) if tokFile == nil { return false, nil, nil, errors.PrinterError("couldn't find file " + filename + " in fileset") } if withTokFile == nil { return false, nil, nil, errors.PrinterError("couldn't find file " + withFileName + " in fileset") } node := FindNode(fset, file, posStart, posEnd) withNode := FindNode(withFileSet, withFile, withPosStart, withPosEnd) if node == nil || withNode == nil { return false, nil, nil, errors.PrinterError("couldn't find node with given positions") } printDecls(tokFile, file) oldSize := tokFile.Size() withOldSize := withTokFile.Size() l, wl := int(node.End()-node.Pos()), int(withNode.End()-withNode.Pos()) if wl > l { fmt.Printf("length to add = %d\n", wl-l) inc := 1 - tokFile.Base() fmt.Printf("inc = %d\n", inc) fset, file = ReparseFile(file, filename, wl-l, identMap) node = FindNode(fset, file, posStart, posEnd) tokFile = GetFileFromFileSet(fset, filename) if filename == withFileName { withFileSet, withFile, withTokFile = fset, file, tokFile withNode = FindNode(withFileSet, withFile, withPosStart, withPosEnd) } lines := GetLines(tokFile) fmt.Printf("linesCount = %d\n", len(lines)) tokFile.SetLines(lines[:len(lines)-(wl-l)]) } withNode = utils.CopyAstNode(withNode) lines := GetLines(tokFile) for i, offset := range lines { fmt.Printf("%d -> %s(%d)\n", i+1, fset.Position(tokFile.Pos(offset)), offset) } nodeLines, firstLine := GetRangeLines(tokFile, node.Pos(), node.End(), oldSize) withNodeLines, _ := GetRangeLines(withTokFile, withNode.Pos(), withNode.End(), withOldSize) fmt.Printf("withnodeLines: %v\n", withNodeLines) mod := wl - l withMod := int(tokFile.Offset(node.Pos()) - withTokFile.Offset(withNode.Pos())) fmt.Printf("withMod: %v\n", withMod) for i, _ := range withNodeLines { withNodeLines[i] += withMod } newLines := removeLinesOfRange(tokFile.Offset(node.Pos()), tokFile.Offset(node.End()), lines, nodeLines, firstLine) tokFile.SetLines(addLinesOfRange(withTokFile.Offset(withNode.Pos()), withTokFile.Offset(withNode.End()), newLines, withNodeLines, firstLine)) printDecls(tokFile, file) fmt.Printf("node -------- %d %d --------- %d %d\n", node.Pos(), node.End(), tokFile.Offset(node.Pos()), tokFile.Offset(node.End())) fmt.Printf("with -------- %d %d --------- %d %d\n", withNode.Pos(), withNode.End(), withTokFile.Offset(withNode.Pos()), withTokFile.Offset(withNode.End())) FixPositions(0, withMod, withNode, true) fmt.Printf("node -------- %d %d --------- %d %d\n", node.Pos(), node.End(), tokFile.Offset(node.Pos()), tokFile.Offset(node.End())) fmt.Printf("with -------- %d %d --------- %d %d\n", withNode.Pos(), withNode.End(), withTokFile.Offset(withNode.Pos()), withTokFile.Offset(withNode.End())) printDecls(tokFile, file) if _, ok := replaceNode(fset, posStart, posEnd, file, withNode); !ok { return false, nil, nil, errors.PrinterError("didn't find node to replace") } except := map[ast.Node]bool{withNode: true} FixPositionsExcept(withNode.Pos(), mod, file, true, except) printDecls(tokFile, file) return true, fset, file, nil }