mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-29 23:33:37 +00:00
compiler: make ForEachFile
accept a package
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
ac040a6f22
commit
b8d7e93459
3 changed files with 37 additions and 48 deletions
|
@ -8,7 +8,6 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"golang.org/x/tools/go/loader"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -30,7 +29,7 @@ func (c *codegen) newGlobal(name string) {
|
||||||
// and returns number of variables initialized.
|
// and returns number of variables initialized.
|
||||||
func (c *codegen) traverseGlobals() int {
|
func (c *codegen) traverseGlobals() int {
|
||||||
var n int
|
var n int
|
||||||
c.ForEachFile(func(f *ast.File) {
|
c.ForEachFile(func(f *ast.File, _ *types.Package) {
|
||||||
n += countGlobals(f)
|
n += countGlobals(f)
|
||||||
})
|
})
|
||||||
if n != 0 {
|
if n != 0 {
|
||||||
|
@ -95,12 +94,11 @@ func lastStmtIsReturn(decl *ast.FuncDecl) (b bool) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func analyzeFuncUsage(mainPkg *loader.PackageInfo, pkgs map[*types.Package]*loader.PackageInfo) funcUsage {
|
func (c *codegen) analyzeFuncUsage() funcUsage {
|
||||||
usage := funcUsage{}
|
usage := funcUsage{}
|
||||||
|
|
||||||
for _, pkg := range pkgs {
|
c.ForEachFile(func(f *ast.File, pkg *types.Package) {
|
||||||
isMain := pkg == mainPkg
|
isMain := pkg == c.mainPkg.Pkg
|
||||||
for _, f := range pkg.Files {
|
|
||||||
ast.Inspect(f, func(node ast.Node) bool {
|
ast.Inspect(f, func(node ast.Node) bool {
|
||||||
switch n := node.(type) {
|
switch n := node.(type) {
|
||||||
case *ast.CallExpr:
|
case *ast.CallExpr:
|
||||||
|
@ -118,8 +116,7 @@ func analyzeFuncUsage(mainPkg *loader.PackageInfo, pkgs map[*types.Package]*load
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
}
|
|
||||||
return usage
|
return usage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,7 @@ func (c *codegen) emitDefault(t types.Type) {
|
||||||
// convertGlobals traverses the AST and only converts global declarations.
|
// convertGlobals traverses the AST and only converts global declarations.
|
||||||
// If we call this in convertFuncDecl then it will load all global variables
|
// If we call this in convertFuncDecl then it will load all global variables
|
||||||
// into the scope of the function.
|
// into the scope of the function.
|
||||||
func (c *codegen) convertGlobals(f *ast.File) {
|
func (c *codegen) convertGlobals(f *ast.File, _ *types.Package) {
|
||||||
ast.Inspect(f, func(node ast.Node) bool {
|
ast.Inspect(f, func(node ast.Node) bool {
|
||||||
switch n := node.(type) {
|
switch n := node.(type) {
|
||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
|
@ -1415,16 +1415,12 @@ func (c *codegen) newLambda(u uint16, lit *ast.FuncLit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *codegen) compile(info *buildInfo, pkg *loader.PackageInfo) error {
|
func (c *codegen) compile(info *buildInfo, pkg *loader.PackageInfo) error {
|
||||||
funUsage := analyzeFuncUsage(pkg, info.program.AllPackages)
|
c.mainPkg = pkg
|
||||||
|
funUsage := c.analyzeFuncUsage()
|
||||||
|
|
||||||
// Bring all imported functions into scope.
|
// Bring all imported functions into scope.
|
||||||
for _, pkg := range info.program.AllPackages {
|
c.ForEachFile(c.resolveFuncDecls)
|
||||||
for _, f := range pkg.Files {
|
|
||||||
c.resolveFuncDecls(f, pkg.Pkg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.mainPkg = pkg
|
|
||||||
n := c.traverseGlobals()
|
n := c.traverseGlobals()
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
emit.Opcode(c.prog.BinWriter, opcode.RET)
|
emit.Opcode(c.prog.BinWriter, opcode.RET)
|
||||||
|
@ -1439,23 +1435,18 @@ func (c *codegen) compile(info *buildInfo, pkg *loader.PackageInfo) error {
|
||||||
sort.Slice(keys, func(i, j int) bool { return keys[i].Path() < keys[j].Path() })
|
sort.Slice(keys, func(i, j int) bool { return keys[i].Path() < keys[j].Path() })
|
||||||
|
|
||||||
// Generate the code for the program.
|
// Generate the code for the program.
|
||||||
for _, k := range keys {
|
c.ForEachFile(func(f *ast.File, pkg *types.Package) {
|
||||||
pkg := info.program.AllPackages[k]
|
|
||||||
c.typeInfo = &pkg.Info
|
|
||||||
|
|
||||||
for _, f := range pkg.Files {
|
|
||||||
for _, decl := range f.Decls {
|
for _, decl := range f.Decls {
|
||||||
switch n := decl.(type) {
|
switch n := decl.(type) {
|
||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
// Don't convert the function if it's not used. This will save a lot
|
// Don't convert the function if it's not used. This will save a lot
|
||||||
// of bytecode space.
|
// of bytecode space.
|
||||||
if funUsage.funcUsed(n.Name.Name) {
|
if funUsage.funcUsed(n.Name.Name) {
|
||||||
c.convertFuncDecl(f, n, k)
|
c.convertFuncDecl(f, n, pkg)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return c.prog.Err
|
return c.prog.Err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
|
"go/types"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -44,11 +45,11 @@ type buildInfo struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachFile executes fn on each file used in current program.
|
// ForEachFile executes fn on each file used in current program.
|
||||||
func (c *codegen) ForEachFile(fn func(*ast.File)) {
|
func (c *codegen) ForEachFile(fn func(*ast.File, *types.Package)) {
|
||||||
for _, pkg := range c.buildInfo.program.AllPackages {
|
for _, pkg := range c.buildInfo.program.AllPackages {
|
||||||
c.typeInfo = &pkg.Info
|
c.typeInfo = &pkg.Info
|
||||||
for _, f := range pkg.Files {
|
for _, f := range pkg.Files {
|
||||||
fn(f)
|
fn(f, pkg.Pkg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue