X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=binapigen%2Fgenerator.go;h=e5eed5a0def462f5e467c347692f842e3fdde8c8;hb=c94a962279858fb13eaacc689f47aed358373e44;hp=ce0954a0cfffa1e274766978ad518bf487f25e76;hpb=58da9ac6e691a8c660eb8ca838a154e11da0db68;p=govpp.git diff --git a/binapigen/generator.go b/binapigen/generator.go index ce0954a..e5eed5a 100644 --- a/binapigen/generator.go +++ b/binapigen/generator.go @@ -38,6 +38,7 @@ import ( 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, }) }