예제 #1
0
파일: field.go 프로젝트: rwl/gorf
func (this *FieldDeclFinder) Visit(node ast.Node) ast.Visitor {
	if this.Obj != nil {
		return nil
	}
	switch n := node.(type) {
	case *ast.BlockStmt:
		return nil
	case *ast.TypeSpec:
		if n.Name.Name == this.typename {
			if st, ok := n.Type.(*ast.StructType); ok {
				for _, field := range st.Fields.List {
					for _, nid := range field.Names {
						if nid.Name == this.newname {
							this.NameExists = true
							return nil
						}
						if nid.Name == this.oldname {
							nid.Name = this.newname
							this.Obj, _ = types.ExprType(nid, LocalImporter)
							this.Updated = true
							this.Name = nid
							return nil
						}
					}
				}
			}
			return this
		}
		return nil
	}
	return this
}
예제 #2
0
파일: dscan.go 프로젝트: rwl/gorf
func (this DepthWalker) Visit(node ast.Node) ast.Visitor {
	if node == nil {
		return this + 1
	}

	buffer := ""
	for i := 0; i < int(this); i++ {
		buffer += " "
	}

	fmt.Printf("%sPos: %d %s\n", buffer, node.Pos(), AllSources.Position(node.Pos()))
	fmt.Printf("%sEnd: %d %s\n", buffer, node.End(), AllSources.Position(node.End()))
	fmt.Printf("%s%T\n", buffer, node)
	fmt.Printf("%s%v\n", buffer, node)
	if e, ok := node.(ast.Expr); ok {
		obj, typ := types.ExprType(e, LocalImporter)
		fmt.Printf("%s%v\n", buffer, obj)
		fmt.Printf("%s%v\n", buffer, typ)
	}
	fmt.Println()

	switch n := node.(type) {

	}

	return this + 1
}
예제 #3
0
func done(obj *ast.Object, typ types.Type) {
	defer os.Exit(0)
	pos := types.FileSet.Position(types.DeclPos(obj))
	fmt.Printf("%v\n", pos)
	if typ.Kind == ast.Bad || !*tflag {
		return
	}
	fmt.Printf("%s\n", strings.Replace(typeStr(obj, typ), "\n", "\n\t", -1))
	if *aflag || *Aflag {
		var m orderedObjects
		for obj := range typ.Iter(types.DefaultImporter) {
			m = append(m, obj)
		}
		sort.Sort(m)
		for _, obj := range m {
			// Ignore unexported members unless Aflag is set.
			if !*Aflag && (typ.Pkg != "" || !ast.IsExported(obj.Name)) {
				continue
			}
			id := ast.NewIdent(obj.Name)
			id.Obj = obj
			_, mt := types.ExprType(id, types.DefaultImporter)
			fmt.Printf("\t%s\n", strings.Replace(typeStr(obj, mt), "\n", "\n\t\t", -1))
			fmt.Printf("\t\t%v\n", types.FileSet.Position(types.DeclPos(obj)))
		}
	}
}
예제 #4
0
파일: singlemover.go 프로젝트: rwl/gorf
func (this *SingleMover) CollectUnexportedObjs() {
	this.unexportedObjs = make(map[*ast.Object]bool)
	for node, obj := range this.moveNodes {
		//printer.Fprint(os.Stdout, token.NewFileSet(), node)
		//fmt.Printf("\n%v %T\n", obj, node)

		if !unicode.IsUpper([]rune(obj.Name)[0] /*utf8.NewString(obj.Name).At(0)*/) {
			this.unexportedObjs[obj] = true
		}

		if ts, ok := node.(*ast.TypeSpec); ok {
			if st, ok := ts.Type.(*ast.StructType); ok {
				for _, field := range st.Fields.List {
					for _, name := range field.Names {
						if !name.IsExported() {
							obj, _ := types.ExprType(name, LocalImporter)
							this.unexportedObjs[obj] = true
						}
					}
				}
			}
		}
	}
	return
}
예제 #5
0
파일: rename.go 프로젝트: rwl/gorf
func (this *RenameWalker) Visit(node ast.Node) ast.Visitor {
	switch n := node.(type) {
	case *ast.Ident:
		obj, _ := types.ExprType(n, LocalImporter)
		if obj == this.Obj {
			this.Updated = true
			n.Name = this.NewName
		}
	case *ast.SelectorExpr:
		obj, _ := types.ExprType(n, LocalImporter)
		if obj == this.Obj {
			this.Updated = true
			n.Sel.Name = this.NewName
		}
	}
	return this
}
예제 #6
0
파일: list.go 프로젝트: juanman2/dot-emacs
func (c *listCmd) visit(info *sym.Info, kindMask uint) bool {
	if (1<<uint(info.ReferObj.Kind))&kindMask == 0 {
		return true
	}
	if info.Universe {
		return true
	}
	if !c.all && !isExported(info.Ident.Name) {
		return true
	}
	eposition := c.ctxt.position(info.Pos)
	exprPkg := c.ctxt.positionToImportPath(eposition)
	var referPkg string
	if info.Universe {
		referPkg = "universe"
	} else {
		referPkg = c.ctxt.positionToImportPath(c.ctxt.position(info.ReferPos))
	}
	name := info.Ident.Name
	if e, ok := info.Expr.(*ast.SelectorExpr); ok {
		_, xt := types.ExprType(e.X, func(path string) *ast.Package {
			return c.ctxt.Import(path)
		})
		//		c.ctxt.print("exprtype %s\n", pretty(e.X))
		name = e.Sel.Name
		switch xn := depointer(xt.Node).(type) {
		case nil:
			if c.verbose {
				log.Printf("%v: no type for %s", c.ctxt.position(e.Pos()), pretty(e.X))
			}
			return true
		case *ast.Ident:
			name = xn.Name + "." + name
		case *ast.ImportSpec:
			// don't qualify with package identifier
		default:
			// literal struct or interface expression.
			name = "_." + name
		}
	}
	line := &symLine{
		long:     true,
		pos:      eposition,
		referPos: c.ctxt.position(info.ReferPos),
		exprPkg:  exprPkg,
		referPkg: referPkg,
		local:    info.Local && info.ReferPos == info.Pos,
		kind:     info.ReferObj.Kind,
		plus:     info.ReferPos == info.Pos,
		expr:     name,
	}
	if c.printType {
		line.exprType = pretty(info.ExprType.Node)
	}
	c.ctxt.printf("%s\n", line)
	return true
}
예제 #7
0
파일: rename.go 프로젝트: rwl/gorf
func (this *DeclFinder) Visit(node ast.Node) ast.Visitor {
	if this.Obj != nil {
		return nil
	}
	switch n := node.(type) {
	case *ast.BlockStmt:
		return nil
	case *ast.ValueSpec:
		for _, name := range n.Names {
			if name.Name == this.newname {
				this.NameExists = true
				return nil
			}
			if name.Name == this.oldname {
				//this.Name = name
				this.Obj, _ = types.ExprType(name, LocalImporter)
				this.Node = node
				return nil
			}
		}
		return nil
	case *ast.FuncDecl:
		if n.Name.Name == this.newname {
			this.NameExists = true
		}
		if n.Name.Name == this.oldname {
			//this.Name = n.Name
			this.Node = node
			this.Obj, _ = types.ExprType(n.Name, LocalImporter)
		}
		return nil
	case *ast.TypeSpec:
		if n.Name.Name == this.newname {
			this.NameExists = true
		}
		if n.Name.Name == this.oldname {
			//this.Name = n.Name
			this.Node = node
			this.Obj, _ = types.ExprType(n.Name, LocalImporter)
		}
		return nil
	}
	return this
}
예제 #8
0
파일: ast.go 프로젝트: hdpe/ident
func getDefPosition(expr ast.Expr) *token.Position {
	obj, _ := types.ExprType(expr, types.DefaultImporter)
	if obj == nil {
		return nil
	}
	pos := fileset.Position(types.DeclPos(obj))
	if realname, err := filepath.EvalSymlinks(pos.Filename); err == nil {
		pos.Filename = realname
	}
	return &pos
}
예제 #9
0
파일: move.go 프로젝트: rwl/gorf
func (this AllDeclFinder) Visit(node ast.Node) ast.Visitor {
	switch n := node.(type) {
	case *ast.BlockStmt:
		return nil
	case *ast.ValueSpec:
		for _, name := range n.Names {
			obj, _ := types.ExprType(name, LocalImporter)
			this[obj] = node
		}
		return nil
	case *ast.FuncDecl:
		obj, _ := types.ExprType(n.Name, LocalImporter)
		this[obj] = node
		return nil
	case *ast.TypeSpec:
		obj, _ := types.ExprType(n.Name, LocalImporter)
		this[obj] = node
		return nil
	}
	return this
}
예제 #10
0
파일: move.go 프로젝트: rwl/gorf
func (this *MethodFinder) Visit(node ast.Node) ast.Visitor {
	switch n := node.(type) {
	case *ast.BlockStmt:
		return nil
	case *ast.FuncDecl:
		if n.Recv != nil {
			for _, field := range n.Recv.List {
				expr := field.Type
				if se, ok := expr.(*ast.StarExpr); ok {
					expr = se.X
				}
				obj, _ := types.ExprType(expr, LocalImporter)
				if obj == this.Receiver {
					fobj, _ := types.ExprType(n.Name, LocalImporter)
					this.NodeObjs[n] = fobj
				}
			}
		}
		return nil
	}
	return this
}
예제 #11
0
파일: move.go 프로젝트: rwl/gorf
func (this *ObjChecker) Visit(node ast.Node) ast.Visitor {
	if this.Found {
		return nil
	}
	if expr, ok := node.(ast.Expr); ok {
		obj, _ := types.ExprType(expr, LocalImporter)
		if this.Objs[obj] {
			this.Found = true
			return nil
		}
	}
	return this
}
예제 #12
0
파일: move.go 프로젝트: rwl/gorf
func (this ListImportWalker) Visit(node ast.Node) ast.Visitor {
	switch n := node.(type) {
	case *ast.SelectorExpr:
		ast.Walk(this, n.X)
		//skip n.Sel, we don't need to import for it
		return nil
	case *ast.Ident:
		obj, typ := types.ExprType(n, LocalImporter)
		if is, ok := typ.Node.(*ast.ImportSpec); ok {
			this[obj] = is
		}
	}

	return this
}
예제 #13
0
파일: move.go 프로젝트: rwl/gorf
func (this ImportUseCollector) Visit(node ast.Node) ast.Visitor {
	if _, ok := node.(*ast.ImportSpec); ok {
		return nil
	}

	if expr, ok := node.(ast.Expr); ok {
		_, typ := types.ExprType(expr, LocalImporter)
		if typ.Node != node {
			if is, ok2 := typ.Node.(*ast.ImportSpec); ok2 {
				this[is] = true
			}
		}
	}

	return this
}
예제 #14
0
파일: pkg.go 프로젝트: rwl/gorf
func (this *PkgChanger) Visit(node ast.Node) ast.Visitor {
	if this.Renamed {
		return nil
	}

	if node == nil {
		return this
	}

	switch n := node.(type) {
	case *ast.ImportSpec:
		if string(n.Path.Value) == QuotePath(this.path) {
			if n.Name != nil {

				this.Renamed = true
				return nil
			}

			if n.Name == nil && this.newname != this.pkgname {
				n.Name = &ast.Ident{
					Name:    this.newname,
					NamePos: n.Pos(),
				}
				this.Updated = true
			}
		}

	case *ast.Ident:
		if n.Name == this.oldname {
			obj, typ := types.ExprType(n, LocalImporter)
			if obj == nil {
				n.Name = this.newname
				this.Updated = true
			}
			if obj != nil {
				if typ.Kind == ast.Pkg && obj.Name == this.oldname {
					n.Name = this.newname
					this.Updated = true
				}
			}
		}

	}

	return this
}
예제 #15
0
파일: lookup.go 프로젝트: hdpe/ident
func lookup(filepath string, offset int) (Definition, error) {
	def := Definition{}

	f, err := parser.ParseFile(fileset, filepath, nil, 0, getScope(filepath))
	if err != nil {
		return def, err
	}

	containsOffset := func(node ast.Node) bool {
		from := fileset.Position(node.Pos()).Offset
		to := fileset.Position(node.End()).Offset
		return offset >= from && offset < to
	}

	// traverse the ast tree until we find a node at the given offset position
	var ident ast.Expr
	ast.Inspect(f, func(node ast.Node) bool {
		switch expr := node.(type) {
		case *ast.SelectorExpr:
			if containsOffset(expr) && containsOffset(expr.Sel) {
				ident = expr
			}
		case *ast.Ident:
			if containsOffset(expr) {
				ident = expr
			}
		}
		return ident == nil
	})

	if ident == nil {
		return def, errors.New("no identifier found")
	}

	pos := getDefPosition(ident)
	if pos == nil {
		return def, errors.New("could not find definition of identifier")
	}

	obj, _ := types.ExprType(ident, types.DefaultImporter)
	def.Name = obj.Name
	def.Position = *pos
	return def, nil
}
예제 #16
0
파일: sym.go 프로젝트: juanman2/dot-emacs
func (ctxt *Context) visitExpr(f *ast.File, e ast.Expr, local bool, visitf func(*Info) bool) bool {
	var info Info
	info.Expr = e
	switch e := e.(type) {
	case *ast.Ident:
		if e.Name == "_" {
			return true
		}
		info.Pos = e.Pos()
		info.Ident = e
	case *ast.SelectorExpr:
		info.Pos = e.Sel.Pos()
		info.Ident = e.Sel
	}
	obj, t := types.ExprType(e, ctxt.importer)
	if obj == nil {
		ctxt.logf(e.Pos(), "no object for %s", pretty(e))
		return true
	}
	info.ExprType = t
	info.ReferObj = obj
	if parser.Universe.Lookup(obj.Name) != obj {
		info.ReferPos = types.DeclPos(obj)
		if info.ReferPos == token.NoPos {
			name := pretty(e)
			if name != "init" {
				ctxt.logf(e.Pos(), "no declaration for %s", pretty(e))
			}
			return true
		}
	} else {
		info.Universe = true
	}
	info.Local = local
	oldName := info.Ident.Name
	more := visitf(&info)
	if info.Ident.Name != oldName {
		ctxt.ChangedFiles[ctxt.filename(f)] = f
	}
	return more
}
예제 #17
0
파일: move.go 프로젝트: rwl/gorf
func (this *ReferenceWalker) Visit(node ast.Node) ast.Visitor {
	if _, ok := this.SkipNodes[node]; ok {
		this.SkipNodeParents[node] = this.Parent
		return nil
	}

	if expr, ok := node.(ast.Expr); ok {
		obj, _ := types.ExprType(expr, LocalImporter)
		if this.UnexportedObjs[obj] {
			*this.BadReferences = append(*this.BadReferences, node)
		} else if _, ok2 := this.MoveObjs[obj]; ok2 {
			this.GoodReferenceParents[node] = this.Parent
		}
	}

	next := new(ReferenceWalker)
	*next = *this

	next.Parent = node

	return next
}
예제 #18
0
func main() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "usage: godef [flags] [expr]\n")
		flag.PrintDefaults()
	}
	flag.Parse()
	if flag.NArg() > 1 {
		flag.Usage()
		os.Exit(2)
	}
	types.Debug = *debug
	*tflag = *tflag || *aflag || *Aflag
	searchpos := *offset
	filename := *fflag

	var afile *acmeFile
	var src []byte
	if *acmeFlag {
		var err error
		if afile, err = acmeCurrentFile(); err != nil {
			fail("%v", err)
		}
		filename, src, searchpos = afile.name, afile.body, afile.offset
	} else if *readStdin {
		src, _ = ioutil.ReadAll(os.Stdin)
	} else {
		// TODO if there's no filename, look in the current
		// directory and do something plausible.
		b, err := ioutil.ReadFile(filename)
		if err != nil {
			fail("cannot read %s: %v", filename, err)
		}
		src = b
	}
	pkgScope := ast.NewScope(parser.Universe)
	f, err := parser.ParseFile(types.FileSet, filename, src, 0, pkgScope)
	if f == nil {
		fail("cannot parse %s: %v", filename, err)
	}

	var o ast.Node
	switch {
	case flag.NArg() > 0:
		o = parseExpr(f.Scope, flag.Arg(0))

	case searchpos >= 0:
		o = findIdentifier(f, searchpos)

	default:
		fmt.Fprintf(os.Stderr, "no expression or offset specified\n")
		flag.Usage()
		os.Exit(2)
	}
	// print old source location to facilitate backtracking
	if *acmeFlag {
		fmt.Printf("\t%s:#%d\n", afile.name, afile.runeOffset)
	}
	switch e := o.(type) {
	case *ast.ImportSpec:
		path := importPath(e)
		pkg, err := build.Default.Import(path, "", build.FindOnly)
		if err != nil {
			fail("error finding import path for %s: %s", path, err)
		}
		fmt.Println(pkg.Dir)
	case ast.Expr:
		if !*tflag {
			// try local declarations only
			if obj, typ := types.ExprType(e, types.DefaultImporter); obj != nil {
				done(obj, typ)
			}
		}
		// add declarations from other files in the local package and try again
		pkg, err := parseLocalPackage(filename, f, pkgScope)
		if pkg == nil && !*tflag {
			fmt.Printf("parseLocalPackage error: %v\n", err)
		}
		if obj, typ := types.ExprType(e, types.DefaultImporter); obj != nil {
			done(obj, typ)
		}
		fail("no declaration found for %v", pretty{e})
	}
}
예제 #19
0
파일: singlemover.go 프로젝트: rwl/gorf
func (this *SingleMover) UpdateOther() (err error) {
	for _, path := range ImportedBy[QuotePath(this.oldpath)] {
		opkg := LocalImporter(path)

		for fpath, file := range opkg.Files {
			rw := ReferenceWalker{
				UnexportedObjs:       make(map[*ast.Object]bool),
				MoveObjs:             this.moveObjs,
				SkipNodes:            make(map[ast.Node]*ast.Object),
				SkipNodeParents:      make(map[ast.Node]ast.Node),
				GoodReferenceParents: make(map[ast.Node]ast.Node),
				BadReferences:        &[]ast.Node{},
			}
			ast.Walk(&rw, file)

			if len(rw.GoodReferenceParents) == 0 {
				continue
			}

			newpkgname := GetUniqueIdent([]*ast.File{file}, this.pkg.Name)

			//construct the import
			nis := &ast.ImportSpec{
				Name: &ast.Ident{Name: newpkgname},
				Path: &ast.BasicLit{
					Kind:  token.STRING,
					Value: QuotePath(this.newpath),
				},
			}

			ngd := &ast.GenDecl{
				Tok:   token.IMPORT,
				Specs: []ast.Spec{nis},
			}
			file.Decls = append([]ast.Decl{ngd}, file.Decls...)

			for node, parent := range rw.GoodReferenceParents {
				getSel := func(sel *ast.SelectorExpr) *ast.SelectorExpr {
					obj, _ := types.ExprType(sel.X, LocalImporter)
					if obj.Kind == ast.Pkg {
						return &ast.SelectorExpr{
							X: &ast.Ident{
								Name:    newpkgname,
								NamePos: sel.X.Pos(),
							},
							Sel: sel.Sel,
						}
					}
					return sel
				}

				switch p := parent.(type) {
				case *ast.CallExpr:
					if sel, ok := node.(*ast.SelectorExpr); ok {

						p.Fun = getSel(sel)
					} else {

						return MakeErr("CallExpr w/ unexpected type %T\n", node)
					}
				case *ast.AssignStmt:
					for i, x := range p.Lhs {
						if x == node {
							if sel, ok := x.(*ast.SelectorExpr); ok {
								p.Lhs[i] = getSel(sel)
							}
						}
					}
					for i, x := range p.Rhs {
						if x == node {
							if sel, ok := x.(*ast.SelectorExpr); ok {
								p.Rhs[i] = getSel(sel)
							}
						}
					}
				case *ast.ValueSpec:
					if node == p.Type {
						if sel, ok := p.Type.(*ast.SelectorExpr); ok {
							p.Type = getSel(sel)
						}
					}
					for i, x := range p.Values {
						if x == node {
							if sel, ok := x.(*ast.SelectorExpr); ok {
								p.Values[i] = getSel(sel)
							}
						}
					}
				case *ast.StarExpr:
					if p.X == node {
						if sel, ok := p.X.(*ast.SelectorExpr); ok {
							p.X = getSel(sel)
						}
					}
				default:
					printer.Fprint(os.Stdout, AllSources, parent)
					return MakeErr("Unexpected remote parent %T\n", parent)
				}
			}

			//now that we've renamed some references, do we still need to import oldpath?
			oc := ObjChecker{
				Objs: this.remainingObjs,
			}
			ast.Walk(&oc, file)
			if !oc.Found {
				ast.Walk(&ImportRemover{nil, this.oldpath}, file)
			}

			err = RewriteSource(fpath, file)
			if err != nil {
				return
			}
		}
	}

	return
}
예제 #20
0
파일: singlemover.go 프로젝트: rwl/gorf
func (this *SingleMover) CreateNewSource() (err error) {

	liw := make(ListImportWalker)
	for n := range this.moveNodes {
		ast.Walk(liw, n)
	}
	finalImports := make(map[*ast.ImportSpec]bool)
	for obj, is := range liw {
		if _, ok := this.moveObjs[obj]; !ok {
			finalImports[is] = true
		}
	}

	newfile := &ast.File{
		Name: &ast.Ident{Name: this.pkg.Name},
	}

	if len(finalImports) != 0 {
		for is := range finalImports {
			gdl := &ast.GenDecl{
				Tok:   token.IMPORT,
				Specs: []ast.Spec{is},
			}
			newfile.Decls = append(newfile.Decls, gdl)
		}
	}

	var sortedNodes NodeSorter

	for mn := range this.moveNodes {
		sortedNodes = append(sortedNodes, mn)
	}
	sort.Sort(sortedNodes)

	for _, mn := range sortedNodes {
		switch m := mn.(type) {
		case ast.Decl:
			newfile.Decls = append(newfile.Decls, m)
		case *ast.TypeSpec:
			gdl := &ast.GenDecl{
				Tok:   token.TYPE,
				Specs: []ast.Spec{m},
			}
			newfile.Decls = append(newfile.Decls, gdl)
		}
	}

	npf := ExprParentFinder{
		ExprParents: make(map[ast.Expr]ast.Node),
	}
	for n := range this.moveNodes {
		ast.Walk(&npf, n)
	}

	var pkgfiles []*ast.File
	for _, pkgfile := range this.pkg.Files {
		pkgfiles = append(pkgfiles, pkgfile)
	}
	oldPkgNewName := GetUniqueIdent(pkgfiles, this.pkg.Name)

	needOldImport := false

	this.referenceBack = false

	for expr, parent := range npf.ExprParents {
		obj, _ := types.ExprType(expr, LocalImporter)
		if _, ok := this.moveObjs[obj]; ok {
			continue
		}

		if _, ok := this.allObjs[obj]; !ok {
			continue
		}

		if !unicode.IsUpper([]rune(obj.Name)[0] /*utf8.NewString(obj.Name).At(0)*/) {
			position := AllSources.Position(expr.Pos())
			fmt.Printf("At %v ", position)
			printer.Fprint(os.Stdout, token.NewFileSet(), expr)
			fmt.Println()
			err = MakeErr("Can't move code that references unexported objects")
			return
		}

		needOldImport = true
		this.referenceBack = true

		getSel := func(idn *ast.Ident) *ast.SelectorExpr {
			return &ast.SelectorExpr{
				X: &ast.Ident{
					Name:    oldPkgNewName,
					NamePos: idn.NamePos,
				},
				Sel: idn,
			}
		}

		switch p := parent.(type) {
		case *ast.CallExpr:
			if idn, ok := expr.(*ast.Ident); ok {
				p.Fun = getSel(idn)
			} else {
				err = MakeErr("CallExpr w/ unexpected type %T\n", expr)
				return
			}
		case *ast.AssignStmt:
			for i, x := range p.Lhs {
				if x == expr {
					if idn, ok := x.(*ast.Ident); ok {
						p.Lhs[i] = getSel(idn)
					}
				}
			}
			for i, x := range p.Rhs {
				if x == expr {
					if idn, ok := x.(*ast.Ident); ok {
						p.Rhs[i] = getSel(idn)
					}
				}
			}
		default:
			err = MakeErr("Unexpected parent %T\n", parent)
			return
		}
	}

	if needOldImport {
		is := &ast.ImportSpec{
			Name: &ast.Ident{Name: oldPkgNewName},
			Path: &ast.BasicLit{Value: QuotePath(this.oldpath)},
		}
		gdl := &ast.GenDecl{
			Tok:   token.IMPORT,
			Specs: []ast.Spec{is},
		}
		newfile.Decls = append([]ast.Decl{gdl}, newfile.Decls...)
	}

	err = os.MkdirAll(this.newpath, 0755)
	if err != nil {
		return
	}
	newSourcePath := filepath.Join(this.newpath, this.pkg.Name+".go")

	containedComments := make(CommentCollector)
	for node := range this.moveNodes {
		ast.Walk(containedComments, node)
	}

	for _, file := range this.pkg.Files {
		for i := len(file.Comments) - 1; i >= 0; i-- {
			cg := file.Comments[i]
			add := func() {
				newfile.Comments = append([]*ast.CommentGroup{cg}, newfile.Comments...)
				file.Comments[i] = file.Comments[len(file.Comments)-1]
				file.Comments = file.Comments[:len(file.Comments)-1]
			}
			if containedComments[cg] {
				add()
			} else {
				for node := range this.moveNodes {
					if node.Pos() <= cg.Pos() && node.End() >= cg.End() {
						add()
						break
					}
				}
			}
		}

	}
	err = NewSource(newSourcePath, newfile)
	if err != nil {
		return
	}

	return
}