aboutsummaryrefslogtreecommitdiffstats
path: root/binapigen/generator.go
diff options
context:
space:
mode:
Diffstat (limited to 'binapigen/generator.go')
-rw-r--r--binapigen/generator.go65
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,
})
}