github.com/lheiskan/zebrapack@v4.1.1-0.20181107023619-e955d028f9bf+incompatible/parse/noload.go (about) 1 package parse 2 3 import ( 4 "fmt" 5 "go/ast" 6 "go/parser" 7 "go/token" 8 9 "github.com/glycerine/zebrapack/cfg" 10 "github.com/glycerine/zebrapack/gen" 11 ) 12 13 // FileNoLoad parses a file at the relative path 14 // provided and produces a new *FileSet. 15 // If you pass in a path to a directory, the entire 16 // directory will be parsed. 17 // If unexport is false, only exported identifiers are included in the FileSet. 18 // If the resulting FileSet would be empty, an error is returned. 19 // 20 // FileNoLoad(), in noload.go, is 21 // the original msgp version of File() 22 // that doesn't require full 23 // compilability/avialability 24 // of all dependencies. Although this 25 // doesn't support resolution of 26 // named constants like the loader 27 // version does, this can be 28 // useful when reading a partial 29 // completed source file or otherwise 30 // in a situation where it is 31 // inconvient to have to meet 32 // the compiler's demands just yet. 33 // 34 func FileNoLoad(c *cfg.ZebraConfig) (*FileSet, error) { 35 ok, isDir := fileOrDir(c.GoFile) 36 if !ok { 37 return nil, fmt.Errorf("error: path '%s' does not exist", c.GoFile) 38 } 39 40 name := c.GoFile 41 pushstate(name) 42 defer popstate() 43 fs := &FileSet{ 44 Specs: make(map[string]ast.Expr), 45 Identities: make(map[string]gen.Elem), 46 Cfg: c, 47 } 48 49 fset := token.NewFileSet() 50 if isDir { 51 pkgs, err := parser.ParseDir(fset, name, nil, parser.ParseComments) 52 if err != nil { 53 return nil, err 54 } 55 if len(pkgs) != 1 { 56 return nil, fmt.Errorf("multiple packages in directory: %s", name) 57 } 58 var one *ast.Package 59 for _, nm := range pkgs { 60 one = nm 61 break 62 } 63 fs.Package = one.Name 64 for _, fl := range one.Files { 65 pushstate(fl.Name.Name) 66 fs.Directives = append(fs.Directives, yieldComments(fl.Comments)...) 67 fs.getZebraSchemaId(fl) 68 if !c.Unexported { 69 ast.FileExports(fl) 70 } 71 fs.getTypeSpecs(fl) 72 popstate() 73 } 74 } else { 75 f, err := parser.ParseFile(fset, name, nil, parser.ParseComments) 76 if err != nil { 77 return nil, err 78 } 79 fs.Package = f.Name.Name 80 fs.Directives = yieldComments(f.Comments) 81 fs.getZebraSchemaId(f) 82 if !c.Unexported { 83 ast.FileExports(f) 84 } 85 fs.getTypeSpecs(f) 86 } 87 88 if len(fs.Specs) == 0 { 89 return nil, fmt.Errorf("no definitions in %s", name) 90 } 91 92 err := fs.process() 93 if err != nil { 94 return nil, err 95 } 96 fs.applyDirectives() 97 fs.propInline() 98 99 return fs, nil 100 }