const debugNS … type NameSpace … type mountedFS … // hasPathPrefix reports whether x == y or x == y + "/" + more. func hasPathPrefix(x, y string) bool { … } // translate translates path for use in m, replacing old with new. // // mountedFS{"/src/pkg", fs, "/src"}.translate("/src/pkg/code") == "/src/code". func (m mountedFS) translate(path string) string { … } func (NameSpace) String() string { … } // Fprint writes a text representation of the name space to w. func (ns NameSpace) Fprint(w io.Writer) { … } // clean returns a cleaned, rooted path for evaluation. // It canonicalizes the path so that we can use string operations // to analyze it. func (NameSpace) clean(path string) string { … } type BindMode … const BindReplace … const BindBefore … const BindAfter … // Bind causes references to old to redirect to the path new in newfs. // If mode is BindReplace, old redirections are discarded. // If mode is BindBefore, this redirection takes priority over existing ones, // but earlier ones are still consulted for paths that do not exist in newfs. // If mode is BindAfter, this redirection happens only after existing ones // have been tried and failed. func (ns NameSpace) Bind(old string, newfs FileSystem, new string, mode BindMode) { … } // resolve resolves a path to the list of mountedFS to use for path. func (ns NameSpace) resolve(path string) []mountedFS { … } // Open implements the FileSystem Open method. func (ns NameSpace) Open(path string) (ReadSeekCloser, error) { … } // stat implements the FileSystem Stat and Lstat methods. func (ns NameSpace) stat(path string, f func(FileSystem, string) (os.FileInfo, error)) (os.FileInfo, error) { … } func (ns NameSpace) Stat(path string) (os.FileInfo, error) { … } func (ns NameSpace) Lstat(path string) (os.FileInfo, error) { … } type dirInfo … func (d dirInfo) Name() string { … } func (d dirInfo) Size() int64 { … } func (d dirInfo) Mode() os.FileMode { … } func (d dirInfo) ModTime() time.Time { … } func (d dirInfo) IsDir() bool { … } func (d dirInfo) Sys() interface{ … } var startTime … // ReadDir implements the FileSystem ReadDir method. It's where most of the magic is. // (The rest is in resolve.) // // Logically, ReadDir must return the union of all the directories that are named // by path. In order to avoid misinterpreting Go packages, of all the directories // that contain Go source code, we only include the files from the first, // but we include subdirectories from all. // // ReadDir must also return directory entries needed to reach mount points. // If the name space looks like the example in the type NameSpace comment, // but c:\Go does not have a src/pkg subdirectory, we still want to be able // to find that subdirectory, because we've mounted d:\Work1 and d:\Work2 // there. So if we don't see "src" in the directory listing for c:\Go, we add an // entry for it before returning. func (ns NameSpace) ReadDir(path string) ([]os.FileInfo, error) { … } // RootType returns the RootType for the given path in the namespace. func (ns NameSpace) RootType(path string) RootType { … } type byName … func (f byName) Len() int { … } func (f byName) Less(i, j int) bool { … } func (f byName) Swap(i, j int) { … }