diff options
Diffstat (limited to 'vendor/github.com/mailru/easyjson/parser')
3 files changed, 188 insertions, 0 deletions
diff --git a/vendor/github.com/mailru/easyjson/parser/parser.go b/vendor/github.com/mailru/easyjson/parser/parser.go new file mode 100644 index 000000000..5bd06e946 --- /dev/null +++ b/vendor/github.com/mailru/easyjson/parser/parser.go @@ -0,0 +1,97 @@ +package parser + +import ( + "go/ast" + "go/parser" + "go/token" + "os/exec" + "strings" +) + +const structComment = "easyjson:json" + +type Parser struct { + PkgPath string + PkgName string + StructNames []string + AllStructs bool +} + +type visitor struct { + *Parser + + name string + explicit bool +} + +func (p *Parser) needType(comments string) bool { + for _, v := range strings.Split(comments, "\n") { + if strings.HasPrefix(v, structComment) { + return true + } + } + return false +} + +func (v *visitor) Visit(n ast.Node) (w ast.Visitor) { + switch n := n.(type) { + case *ast.Package: + return v + case *ast.File: + v.PkgName = n.Name.String() + return v + + case *ast.GenDecl: + v.explicit = v.needType(n.Doc.Text()) + + if !v.explicit && !v.AllStructs { + return nil + } + return v + case *ast.TypeSpec: + v.name = n.Name.String() + + // Allow to specify non-structs explicitly independent of '-all' flag. + if v.explicit { + v.StructNames = append(v.StructNames, v.name) + return nil + } + return v + case *ast.StructType: + v.StructNames = append(v.StructNames, v.name) + return nil + } + return nil +} + +func (p *Parser) Parse(fname string, isDir bool) error { + var err error + if p.PkgPath, err = getPkgPath(fname, isDir); err != nil { + return err + } + + fset := token.NewFileSet() + if isDir { + packages, err := parser.ParseDir(fset, fname, nil, parser.ParseComments) + if err != nil { + return err + } + + for _, pckg := range packages { + ast.Walk(&visitor{Parser: p}, pckg) + } + } else { + f, err := parser.ParseFile(fset, fname, nil, parser.ParseComments) + if err != nil { + return err + } + + ast.Walk(&visitor{Parser: p}, f) + } + return nil +} + +func getDefaultGoPath() (string, error) { + output, err := exec.Command("go", "env", "GOPATH").Output() + return string(output), err +} diff --git a/vendor/github.com/mailru/easyjson/parser/parser_unix.go b/vendor/github.com/mailru/easyjson/parser/parser_unix.go new file mode 100644 index 000000000..09b20a2e1 --- /dev/null +++ b/vendor/github.com/mailru/easyjson/parser/parser_unix.go @@ -0,0 +1,42 @@ +// +build !windows + +package parser + +import ( + "fmt" + "os" + "path" + "strings" +) + +func getPkgPath(fname string, isDir bool) (string, error) { + if !path.IsAbs(fname) { + pwd, err := os.Getwd() + if err != nil { + return "", err + } + fname = path.Join(pwd, fname) + } + + gopath := os.Getenv("GOPATH") + if gopath == "" { + var err error + gopath, err = getDefaultGoPath() + if err != nil { + return "", fmt.Errorf("cannot determine GOPATH: %s", err) + } + } + + for _, p := range strings.Split(os.Getenv("GOPATH"), ":") { + prefix := path.Join(p, "src") + "/" + if rel := strings.TrimPrefix(fname, prefix); rel != fname { + if !isDir { + return path.Dir(rel), nil + } else { + return path.Clean(rel), nil + } + } + } + + return "", fmt.Errorf("file '%v' is not in GOPATH", fname) +} diff --git a/vendor/github.com/mailru/easyjson/parser/parser_windows.go b/vendor/github.com/mailru/easyjson/parser/parser_windows.go new file mode 100644 index 000000000..90d3a78b5 --- /dev/null +++ b/vendor/github.com/mailru/easyjson/parser/parser_windows.go @@ -0,0 +1,49 @@ +package parser
+
+import (
+ "fmt"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+)
+
+func normalizePath(path string) string {
+ // use lower case, as Windows file systems will almost always be case insensitive
+ return strings.ToLower(strings.Replace(path, "\\", "/", -1))
+}
+
+func getPkgPath(fname string, isDir bool) (string, error) {
+ // path.IsAbs doesn't work properly on Windows; use filepath.IsAbs instead
+ if !filepath.IsAbs(fname) {
+ pwd, err := os.Getwd()
+ if err != nil {
+ return "", err
+ }
+ fname = path.Join(pwd, fname)
+ }
+
+ fname = normalizePath(fname)
+
+ gopath := os.Getenv("GOPATH")
+ if gopath == "" {
+ var err error
+ gopath, err = getDefaultGoPath()
+ if err != nil {
+ return "", fmt.Errorf("cannot determine GOPATH: %s", err)
+ }
+ }
+
+ for _, p := range strings.Split(os.Getenv("GOPATH"), ";") {
+ prefix := path.Join(normalizePath(p), "src") + "/"
+ if rel := strings.TrimPrefix(fname, prefix); rel != fname {
+ if !isDir {
+ return path.Dir(rel), nil
+ } else {
+ return path.Clean(rel), nil
+ }
+ }
+ }
+
+ return "", fmt.Errorf("file '%v' is not in GOPATH", fname)
+}
|