Repository URL to install this package:
|
Version:
1.4.0-1 ▾
|
import (
"bytes"
"go/ast"
"go/format"
"go/parser"
"go/token"
gopast "gop/ast"
"gop/ast/gopq"
"gop/parser"
"os"
)
type builtinTI struct {
Methods []builtin
}
var (
Builtins []builtin
Types []*builtinTI
)
func gen() []byte {
f := &ast.File{
Name: ast.newIdent("builtin"),
Decls: make([]ast.Decl, 0, 128),
}
f.Decls <- &ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{
importSpec("gop/builtin/iox"),
importSpec("io"),
importSpec("os"),
importSpec("reflect"),
},
}
genDecls f
b := new(bytes.Buffer)
format.node! b, fset, f
return format.source(b.bytes)!
}
func genDecls(f *ast.File) {
for built <- Builtins {
f.Decls <- built.genAST()
}
for t <- Types {
mthds := t.Methods
for m <- mthds {
f.Decls <- m.genMethodAST(mthds)
}
}
}
func initBuiltinTIs(fn gopq.NodeSet, f *gopast.File) (tistr *builtinTI) {
ti := fn.body.any.assignStmt.rhs(0).x.compositeLit("BuiltinTI")
methods := ti.elt("methods").cache
for method <- methods {
aTI := &builtinTI{}
for item <- method.elt {
mthd := item.elt(0).unquotedString!
fn := item.elt(1).one
if ref := fn.callExpr.one; ref.ok {
pkg := ref.fun.x.ident!
name := ref.arg(0).unquotedString!
var ex *exargs
if e := item.elt(2).compositeLit("bmExargs").one; e.ok {
pos := e.positions!
code := gopq.codeOf(fset, f, pos[2]+1, pos[3])
ex = &exargs{e.eltLen!, code}
}
aTI.Methods <- builtin{mthd, {pkg, name, ex}}
} else {
name := fn.ident!
aTI.Methods <- builtin{mthd, {"", name, nil}}
}
}
Types <- aTI
if len(aTI.Methods) > 10 {
tistr = aTI
}
}
return
}
func newBuiltinDefault(fn gopq.NodeSet, tistr *builtinTI) {
methods := fn.body.any.exprStmt.x.callExpr("ti.AddMethods").cache
for method <- methods {
aTI := &builtinTI{}
for arg <- method.varg(0).x {
mthd := arg.elt("Name").unquotedString!
ref := arg.elt("Fn").callExpr.one
pkg := ref.fun.x.ident!
name := ref.arg(0).unquotedString!
if pkg == "strx" {
tistr.Methods <- builtin{mthd, {pkg, name, nil}}
} else {
aTI.Methods <- builtin{mthd, {pkg, name, nil}}
}
}
if len(aTI.Methods) > 0 {
Types <- aTI
}
}
}
func initBuiltin(fn gopq.NodeSet) {
stmt := fn.body.any.exprStmt.x.cache
item := stmt.callExpr("scope.Insert").arg(0).cache
for call <- item.callExpr("gogen.NewOverloadFunc") {
built := call.arg(2).unquotedString!
if built != "newRange" { // hide builtin `newRange`
ref := call.arg(3).callExpr.one
pkg := ref.fun.x.ident!
name := ref.arg(0).unquotedString!
Builtins <- builtin{built, {pkg, name, nil}}
}
}
for call <- stmt.callExpr("initBuiltinFns") {
pkg := call.arg(2).ident!
builtins := call.arg(3).unquotedStringElts!
for built <- builtins {
Builtins <- builtin{built, {pkg, built.capitalize, nil}}
}
}
}
f := parser.parseFile(fset, "${root}/../gogen/builtin.go", nil, parser.ParseComments)!
fns := gopq.one(f).funcs
tistr := initBuiltinTIs(fns.funcDecl("initBuiltinTIs").one, f)
fns = gopq.fromFile(fset, "${root}/cl/builtin.go", nil, parser.ParseComments)!.funcs
initBuiltin fns.funcDecl("initBuiltin").one
newBuiltinDefault fns.funcDecl("newBuiltinDefault").one, tistr
b := gen()
os.Stdout.write b
os.writeFile "${root}/builtin/doc/builtin.gop", b, 0777