Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
gop / usr / lib / gop / cmd / chore / gopbuiltingen / builtingen.gox
Size: Mime:
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