1
0
Fork 0
golang-github-pocketbase-ty.../package_generator.go
Daniel Baumann b6e042e2af
Adding upstream version 0.0~git20250307.c2e6a77.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-22 11:21:48 +02:00

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
}