Repository: syncthing/syncthing
File: lib/fs/walkfs.go (Go)

Code before:
	return &ancestorDirList{list: make([]FileInfo, 0, 20)}
}

type ancestorDirList struct {
	list []FileInfo
}

func (ancestors *ancestorDirList) AppendUnlessPresent(info FileInfo) bool {
	l.Debugf("ancestorDirList: AppendUnlessPresent '%s'", info.Name())
	for _, ancestor := range ancestors.list {
		if SameFile(info, ancestor) {
			return false
		}
	}
	aLen := len(ancestors.list)
	if aLen == cap(ancestors.list) {
		t := make([]FileInfo, aLen, aLen*2)
		copy(t, ancestors.list)
		ancestors.list = t
		l.Debugf("ancestorDirList: capacity increased to %d", cap(ancestors.list))
	}
	ancestors.list = append(ancestors.list, info)
	return true
}

func (ancestors *ancestorDirList) Remove(info FileInfo) bool {
	l.Debugf("ancestorDirList: Remove '%s'", info.Name())
	aLen := len(ancestors.list)
	if aLen == 0 {
		panic(fmt.Sprintf("Removal of item '%s' attempted on empty ancestorDirList", info.Name()))
		//return false
	} else if info.Name() != ancestors.list[aLen-1].Name() { //!SameFile(info, ancestors.list[aLen-1]) may fail
		panic(fmt.Sprintf("ancestorDirList.Remove attempted for item '%s', but the topmost ancestor is '%s'", info.Name(), ancestors.list[aLen-1]))
		//return false
	}
	ancestors.list = ancestors.list[:aLen-1]
	return true
}

func (ancestors *ancestorDirList) Count() int {
	return len(ancestors.list)
}

// WalkFunc is the type of the function called for each file or directory
// visited by Walk. The path argument contains the argument to Walk as a
// prefix; that is, if Walk is called with "dir", which is a directory
// containing the file "a", the walk function will be called with argument
// "dir/a". The info argument is the FileInfo for the named path.
//
// If there was a problem walking to the file or directory named by path, the
// incoming error will describe the problem and the function can decide how

Review comment (bug):
I think I'd call this `Pop() FileInfo` and do the check/panic on the other side maybe (or not at all, as it would require recursion not to be recursion or something like that to actually trigger)?

With the `Identity()` stuff above that could be used here as well as it can't fail, if we want to be paranoid about it.

Code after:
}

func (ancestors *ancestorDirList) Push(info FileInfo) {
	l.Debugf("ancestorDirList: Push '%s'", info.Name())
	ancestors.list = append(ancestors.list, info)
}

func (ancestors *ancestorDirList) Pop() FileInfo {
	aLen := len(ancestors.list)
	info := ancestors.list[aLen-1]
	l.Debugf("ancestorDirList: Pop '%s'", info.Name())
	ancestors.list = ancestors.list[:aLen-1]
	return info
}

func (ancestors *ancestorDirList) Contains(info FileInfo) bool {
	l.Debugf("ancestorDirList: Contains '%s'", info.Name())
	for _, ancestor := range ancestors.list {
		if ancestors.fs.SameFile(info, ancestor) {
			return true
		}
	}
	return false
}

// WalkFunc is the type of the function called for each file or directory
// visited by Walk. The path argument contains the argument to Walk as a
// prefix; that is, if Walk is called with "dir", which is a directory
// containing the file "a", the walk function will be called with argument
// "dir/a". The info argument is the FileInfo for the named path.
//
// If there was a problem walking to the file or directory named by path, the
// incoming error will describe the problem and the function can decide how
// to handle that error (and Walk will not descend into that directory). If
// an error is returned, processing stops. The sole exception is when the function
// returns the special value SkipDir. If the function returns SkipDir when invoked
// on a directory, Walk skips the directory's contents entirely.
// If the function returns SkipDir when invoked on a non-directory file,
// Walk skips the remaining files in the containing directory.
type WalkFunc func(path string, info FileInfo, err error) error

type walkFilesystem struct {
	Filesystem
}

func NewWalkFilesystem(next Filesystem) Filesystem {
	return &walkFilesystem{next}
}

// walk recursively descends path, calling walkFn.
func (f *walkFilesystem) walk(path string, info FileInfo, walkFn WalkFunc, ancestors *ancestorDirList) error {