From 528c184f006046dbd6748258eebfc0d9aa28c10d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 28 Jul 2020 19:50:44 +0300 Subject: [PATCH] compiler: allow to use exported constants Signed-off-by: Evgenii Stratonikov --- pkg/compiler/codegen.go | 27 ++++++++++++++++++++------- pkg/compiler/global_test.go | 9 +++++++++ pkg/compiler/testdata/multi/file1.go | 2 ++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 15163c05f..49d9250e1 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -65,6 +65,9 @@ type codegen struct { // importMap contains mapping from package aliases to full package names for the current file. importMap map[string]string + // constMap contains constants from foreign packages. + constMap map[string]types.TypeAndValue + // mainPkg is a main package metadata. mainPkg *loader.PackageInfo @@ -263,11 +266,7 @@ func (c *codegen) convertGlobals(f *ast.File, _ *types.Package) { case *ast.FuncDecl: return false case *ast.GenDecl: - // constants are loaded directly so there is no need - // to store them as a local variables - if n.Tok != token.CONST { - ast.Walk(c, n) - } + ast.Walk(c, n) } return true }) @@ -367,6 +366,15 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { // x = 2 // ) case *ast.GenDecl: + if n.Tok == token.CONST { + for _, spec := range n.Specs { + vs := spec.(*ast.ValueSpec) + for i := range vs.Names { + c.constMap[c.getIdentName("", vs.Names[i].Name)] = c.typeAndValueOf(vs.Values[i]) + } + } + return nil + } for _, spec := range n.Specs { switch t := spec.(type) { case *ast.ValueSpec: @@ -816,8 +824,12 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { if typ == nil { // This is a global variable from a package. pkgAlias := n.X.(*ast.Ident).Name - pkgPath := c.importMap[pkgAlias] - c.emitLoadVar(pkgPath, n.Sel.Name) + name := c.getIdentName(pkgAlias, n.Sel.Name) + if tv, ok := c.constMap[name]; ok { + c.emitLoadConst(tv) + } else { + c.emitLoadVar(pkgAlias, n.Sel.Name) + } return nil } strct, ok := typ.Underlying().(*types.Struct) @@ -1480,6 +1492,7 @@ func newCodegen(info *buildInfo, pkg *loader.PackageInfo) *codegen { globals: map[string]int{}, labels: map[labelWithType]uint16{}, typeInfo: &pkg.Info, + constMap: map[string]types.TypeAndValue{}, sequencePoints: make(map[string][]DebugSeqPoint), } diff --git a/pkg/compiler/global_test.go b/pkg/compiler/global_test.go index 076555188..1b46ff986 100644 --- a/pkg/compiler/global_test.go +++ b/pkg/compiler/global_test.go @@ -187,3 +187,12 @@ func TestExportedVariable(t *testing.T) { eval(t, src, big.NewInt(46)) }) } + +func TestExportedConst(t *testing.T) { + src := `package foo + import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/multi" + func Main() int { + return multi.SomeConst + }` + eval(t, src, big.NewInt(42)) +} diff --git a/pkg/compiler/testdata/multi/file1.go b/pkg/compiler/testdata/multi/file1.go index 7aa330c8e..c51714e74 100644 --- a/pkg/compiler/testdata/multi/file1.go +++ b/pkg/compiler/testdata/multi/file1.go @@ -1,3 +1,5 @@ package multi var SomeVar12 = 12 + +const SomeConst = 42