mirror of https://github.com/gogits/gogs.git
Unknown
12 years ago
4 changed files with 206 additions and 30 deletions
@ -0,0 +1,147 @@
|
||||
// Copyright 2011 Gary Burd
|
||||
// Copyright 2013 Unknown
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package doc |
||||
|
||||
import ( |
||||
"bytes" |
||||
"errors" |
||||
"go/ast" |
||||
"go/build" |
||||
"go/parser" |
||||
"go/token" |
||||
"io" |
||||
"io/ioutil" |
||||
"os" |
||||
"path" |
||||
"runtime" |
||||
"strings" |
||||
/* |
||||
"fmt" |
||||
"regexp" |
||||
"time"*/ |
||||
|
||||
//"github.com/GPMGo/gpm/models"
|
||||
//"github.com/GPMGo/gpm/utils"
|
||||
) |
||||
|
||||
type sliceWriter struct{ p *[]byte } |
||||
|
||||
func (w sliceWriter) Write(p []byte) (int, error) { |
||||
*w.p = append(*w.p, p...) |
||||
return len(p), nil |
||||
} |
||||
|
||||
func (w *walker) readDir(dir string) ([]os.FileInfo, error) { |
||||
if dir != w.ImportPath { |
||||
panic("unexpected") |
||||
} |
||||
fis := make([]os.FileInfo, 0, len(w.srcs)) |
||||
for _, src := range w.srcs { |
||||
fis = append(fis, src) |
||||
} |
||||
return fis, nil |
||||
} |
||||
|
||||
func (w *walker) openFile(path string) (io.ReadCloser, error) { |
||||
if strings.HasPrefix(path, w.ImportPath+"/") { |
||||
if src, ok := w.srcs[path[len(w.ImportPath)+1:]]; ok { |
||||
return ioutil.NopCloser(bytes.NewReader(src.data)), nil |
||||
} |
||||
} |
||||
panic("unexpected") |
||||
} |
||||
|
||||
func simpleImporter(imports map[string]*ast.Object, path string) (*ast.Object, error) { |
||||
pkg := imports[path] |
||||
if pkg == nil { |
||||
// Guess the package name without importing it. Start with the last
|
||||
// element of the path.
|
||||
name := path[strings.LastIndex(path, "/")+1:] |
||||
|
||||
// Trim commonly used prefixes and suffixes containing illegal name
|
||||
// runes.
|
||||
name = strings.TrimSuffix(name, ".go") |
||||
name = strings.TrimSuffix(name, "-go") |
||||
name = strings.TrimPrefix(name, "go.") |
||||
name = strings.TrimPrefix(name, "go-") |
||||
name = strings.TrimPrefix(name, "biogo.") |
||||
|
||||
// It's also common for the last element of the path to contain an
|
||||
// extra "go" prefix, but not always. TODO: examine unresolved ids to
|
||||
// detect when trimming the "go" prefix is appropriate.
|
||||
|
||||
pkg = ast.NewObj(ast.Pkg, name) |
||||
pkg.Data = ast.NewScope(nil) |
||||
imports[path] = pkg |
||||
} |
||||
return pkg, nil |
||||
} |
||||
|
||||
// build gets imports from source files.
|
||||
func (w *walker) build(srcs []*source) ([]string, error) { |
||||
// Add source files to walker, I skipped references here.
|
||||
w.srcs = make(map[string]*source) |
||||
for _, src := range srcs { |
||||
w.srcs[src.name] = src |
||||
} |
||||
|
||||
w.fset = token.NewFileSet() |
||||
|
||||
// Find the package and associated files.
|
||||
ctxt := build.Context{ |
||||
GOOS: runtime.GOOS, |
||||
GOARCH: runtime.GOARCH, |
||||
CgoEnabled: true, |
||||
JoinPath: path.Join, |
||||
IsAbsPath: path.IsAbs, |
||||
SplitPathList: func(list string) []string { return strings.Split(list, ":") }, |
||||
IsDir: func(path string) bool { panic("unexpected") }, |
||||
HasSubdir: func(root, dir string) (rel string, ok bool) { panic("unexpected") }, |
||||
ReadDir: func(dir string) (fi []os.FileInfo, err error) { return w.readDir(dir) }, |
||||
OpenFile: func(path string) (r io.ReadCloser, err error) { return w.openFile(path) }, |
||||
Compiler: "gc", |
||||
} |
||||
|
||||
bpkg, err := ctxt.ImportDir(w.ImportPath, 0) |
||||
// Continue if there are no Go source files; we still want the directory info.
|
||||
_, nogo := err.(*build.NoGoError) |
||||
if err != nil { |
||||
if nogo { |
||||
err = nil |
||||
} else { |
||||
return nil, errors.New("doc.walker.build(): " + err.Error()) |
||||
} |
||||
} |
||||
|
||||
// Parse the Go files
|
||||
|
||||
files := make(map[string]*ast.File) |
||||
for _, name := range append(bpkg.GoFiles, bpkg.CgoFiles...) { |
||||
file, err := parser.ParseFile(w.fset, name, w.srcs[name].data, parser.ParseComments) |
||||
if err != nil { |
||||
//beego.Error("doc.walker.build():", err)
|
||||
continue |
||||
} |
||||
files[name] = file |
||||
} |
||||
|
||||
var imports []string |
||||
/* for _, v := range bpkg.Imports { |
||||
// Skip strandard library.
|
||||
|
||||
}*/ |
||||
return imports, err |
||||
} |
Loading…
Reference in new issue