diff options
Diffstat (limited to 'binapigen/generator.go')
-rw-r--r-- | binapigen/generator.go | 65 |
1 files changed, 47 insertions, 18 deletions
diff --git a/binapigen/generator.go b/binapigen/generator.go index ce0954a..009c0ec 100644 --- a/binapigen/generator.go +++ b/binapigen/generator.go @@ -32,12 +32,13 @@ import ( "github.com/sirupsen/logrus" - "git.fd.io/govpp.git/binapigen/vppapi" + "go.fd.io/govpp/binapigen/vppapi" ) type Generator struct { Files []*File FilesByName map[string]*File + FilesByPath map[string]*File opts Options apifiles []*vppapi.File @@ -53,11 +54,12 @@ type Generator struct { messagesByName map[string]*Message } -func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator, error) { +func New(opts Options, apiFiles []*vppapi.File, filesToGen []string) (*Generator, error) { gen := &Generator{ FilesByName: make(map[string]*File), + FilesByPath: make(map[string]*File), opts: opts, - apifiles: apifiles, + apifiles: apiFiles, filesToGen: filesToGen, enumsByName: map[string]*Enum{}, aliasesByName: map[string]*Alias{}, @@ -68,9 +70,9 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator // Normalize API files SortFilesByImports(gen.apifiles) - for _, apifile := range apifiles { - RemoveImportedTypes(gen.apifiles, apifile) - SortFileObjectsByName(apifile) + for _, apiFile := range apiFiles { + RemoveImportedTypes(gen.apifiles, apiFile) + SortFileObjectsByName(apiFile) } // prepare package names and import paths @@ -96,6 +98,7 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator } gen.Files = append(gen.Files, file) gen.FilesByName[apifile.Name] = file + gen.FilesByPath[apifile.Path] = file logrus.Debugf("added file %q (path: %v)", apifile.Name, apifile.Path) } @@ -103,16 +106,24 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator // mark files for generation if len(gen.filesToGen) > 0 { logrus.Debugf("Checking %d files to generate: %v", len(gen.filesToGen), gen.filesToGen) - for _, genfile := range gen.filesToGen { - file, ok := gen.FilesByName[genfile] - if !ok { - return nil, fmt.Errorf("nol API file found for: %v", genfile) + for _, genFile := range gen.filesToGen { + markGen := func(file *File) { + file.Generate = true + // generate all imported files + for _, impFile := range file.importedFiles(gen) { + impFile.Generate = true + } } - file.Generate = true - // generate all imported files - for _, impFile := range file.importedFiles(gen) { - impFile.Generate = true + if file, ok := gen.FilesByName[genFile]; ok { + markGen(file) + continue + } + logrus.Debugf("File %s was not found by name", genFile) + if file, ok := gen.FilesByPath[genFile]; ok { + markGen(file) + continue } + return nil, fmt.Errorf("no API file found for: %v", genFile) } } else { logrus.Debugf("Files to generate not specified, marking all %d files for generate", len(gen.Files)) @@ -212,6 +223,13 @@ func (g *GenFile) Content() ([]byte, error) { return g.injectImports(g.buf.Bytes()) } +func getImportClass(importPath string) int { + if !strings.Contains(importPath, ".") { + return 0 /* std */ + } + return 1 /* External */ +} + // injectImports parses source, injects import block declaration with all imports and return formatted func (g *GenFile) injectImports(original []byte) ([]byte, error) { // Parse source code @@ -233,7 +251,7 @@ func (g *GenFile) injectImports(original []byte) ([]byte, error) { var importPaths []Import for importPath := range g.packageNames { importPaths = append(importPaths, Import{ - Name: string(g.packageNames[GoImportPath(importPath)]), + Name: string(g.packageNames[importPath]), Path: string(importPath), }) } @@ -248,7 +266,12 @@ func (g *GenFile) injectImports(original []byte) ([]byte, error) { } // Sort imports by import path sort.Slice(importPaths, func(i, j int) bool { - return importPaths[i].Path < importPaths[j].Path + ci := getImportClass(importPaths[i].Path) + cj := getImportClass(importPaths[j].Path) + if ci == cj { + return importPaths[i].Path < importPaths[j].Path + } + return ci < cj }) // Inject new import block into parsed AST if len(importPaths) > 0 { @@ -264,14 +287,20 @@ func (g *GenFile) injectImports(original []byte) ([]byte, error) { } // Prepare the import block impDecl := &ast.GenDecl{Tok: token.IMPORT, TokPos: pos, Lparen: pos, Rparen: pos} - for _, importPath := range importPaths { + for i, importPath := range importPaths { var name *ast.Ident if importPath.Name == "_" || strings.Contains(importPath.Path, ".") { name = &ast.Ident{Name: importPath.Name, NamePos: pos} } + value := strconv.Quote(importPath.Path) + if i < len(importPaths)-1 { + if getImportClass(importPath.Path) != getImportClass(importPaths[i+1].Path) { + value += "\n" + } + } impDecl.Specs = append(impDecl.Specs, &ast.ImportSpec{ Name: name, - Path: &ast.BasicLit{Kind: token.STRING, Value: strconv.Quote(importPath.Path), ValuePos: pos}, + Path: &ast.BasicLit{Kind: token.STRING, Value: value, ValuePos: pos}, EndPos: pos, }) } |