104 lines
2.4 KiB
Go
104 lines
2.4 KiB
Go
package tygoja
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/token"
|
|
"strings"
|
|
|
|
"golang.org/x/tools/go/packages"
|
|
)
|
|
|
|
// PackageGenerator is responsible for generating the code for a single input package.
|
|
type PackageGenerator struct {
|
|
conf *Config
|
|
pkg *packages.Package
|
|
types []string
|
|
withPkgDoc bool
|
|
|
|
generatedTypes map[string]struct{}
|
|
unknownTypes map[string]struct{}
|
|
imports map[string][]string // path -> []names/aliases
|
|
}
|
|
|
|
// Generate generates the typings for a single package.
|
|
func (g *PackageGenerator) Generate() (string, error) {
|
|
s := new(strings.Builder)
|
|
|
|
namespace := packageNameFromPath(g.pkg.ID)
|
|
|
|
s.WriteString("\n")
|
|
|
|
if g.withPkgDoc {
|
|
for _, f := range g.pkg.Syntax {
|
|
if f.Doc == nil || len(f.Doc.List) == 0 {
|
|
continue
|
|
}
|
|
g.writeCommentGroup(s, f.Doc, 0)
|
|
}
|
|
}
|
|
|
|
g.writeStartModifier(s, 0)
|
|
s.WriteString("namespace ")
|
|
s.WriteString(namespace)
|
|
s.WriteString(" {\n")
|
|
|
|
// register the aliased imports within the package namespace
|
|
// (see https://www.typescriptlang.org/docs/handbook/namespaces.html#aliases)
|
|
loadedAliases := map[string]struct{}{}
|
|
for _, file := range g.pkg.Syntax {
|
|
for _, imp := range file.Imports {
|
|
path := strings.Trim(imp.Path.Value, `"' `)
|
|
|
|
pgkName := packageNameFromPath(path)
|
|
alias := pgkName
|
|
|
|
if imp.Name != nil && imp.Name.Name != "" && imp.Name.Name != "_" {
|
|
alias = imp.Name.Name
|
|
|
|
if _, ok := loadedAliases[alias]; ok {
|
|
continue // already registered
|
|
}
|
|
|
|
loadedAliases[alias] = struct{}{}
|
|
|
|
g.writeIndent(s, 1)
|
|
s.WriteString("// @ts-ignore\n")
|
|
g.writeIndent(s, 1)
|
|
s.WriteString("import ")
|
|
s.WriteString(alias)
|
|
s.WriteString(" = ")
|
|
s.WriteString(pgkName)
|
|
s.WriteString("\n")
|
|
}
|
|
|
|
// register the import to export its package later
|
|
if !exists(g.imports[path], alias) {
|
|
if g.imports[path] == nil {
|
|
g.imports[path] = []string{}
|
|
}
|
|
g.imports[path] = append(g.imports[path], alias)
|
|
}
|
|
}
|
|
|
|
ast.Inspect(file, func(n ast.Node) bool {
|
|
switch x := n.(type) {
|
|
case *ast.FuncDecl: // FuncDecl can be package level function or struct method
|
|
g.writeFuncDecl(s, x, 1)
|
|
return false
|
|
case *ast.GenDecl: // GenDecl can be an import, type, var, or const expression
|
|
if x.Tok == token.VAR || x.Tok == token.IMPORT {
|
|
return false // ignore variables and import statements for now
|
|
}
|
|
|
|
g.writeGroupDecl(s, x, 1)
|
|
return false
|
|
}
|
|
|
|
return true
|
|
})
|
|
}
|
|
|
|
s.WriteString("}\n")
|
|
|
|
return s.String(), nil
|
|
}
|