forked from TrueCloudLab/neoneo-go
compiler: allow to use exported constants
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
6df019913d
commit
528c184f00
3 changed files with 31 additions and 7 deletions
|
@ -65,6 +65,9 @@ type codegen struct {
|
||||||
// importMap contains mapping from package aliases to full package names for the current file.
|
// importMap contains mapping from package aliases to full package names for the current file.
|
||||||
importMap map[string]string
|
importMap map[string]string
|
||||||
|
|
||||||
|
// constMap contains constants from foreign packages.
|
||||||
|
constMap map[string]types.TypeAndValue
|
||||||
|
|
||||||
// mainPkg is a main package metadata.
|
// mainPkg is a main package metadata.
|
||||||
mainPkg *loader.PackageInfo
|
mainPkg *loader.PackageInfo
|
||||||
|
|
||||||
|
@ -263,11 +266,7 @@ func (c *codegen) convertGlobals(f *ast.File, _ *types.Package) {
|
||||||
case *ast.FuncDecl:
|
case *ast.FuncDecl:
|
||||||
return false
|
return false
|
||||||
case *ast.GenDecl:
|
case *ast.GenDecl:
|
||||||
// constants are loaded directly so there is no need
|
ast.Walk(c, n)
|
||||||
// to store them as a local variables
|
|
||||||
if n.Tok != token.CONST {
|
|
||||||
ast.Walk(c, n)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@ -367,6 +366,15 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
// x = 2
|
// x = 2
|
||||||
// )
|
// )
|
||||||
case *ast.GenDecl:
|
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 {
|
for _, spec := range n.Specs {
|
||||||
switch t := spec.(type) {
|
switch t := spec.(type) {
|
||||||
case *ast.ValueSpec:
|
case *ast.ValueSpec:
|
||||||
|
@ -816,8 +824,12 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
||||||
if typ == nil {
|
if typ == nil {
|
||||||
// This is a global variable from a package.
|
// This is a global variable from a package.
|
||||||
pkgAlias := n.X.(*ast.Ident).Name
|
pkgAlias := n.X.(*ast.Ident).Name
|
||||||
pkgPath := c.importMap[pkgAlias]
|
name := c.getIdentName(pkgAlias, n.Sel.Name)
|
||||||
c.emitLoadVar(pkgPath, n.Sel.Name)
|
if tv, ok := c.constMap[name]; ok {
|
||||||
|
c.emitLoadConst(tv)
|
||||||
|
} else {
|
||||||
|
c.emitLoadVar(pkgAlias, n.Sel.Name)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
strct, ok := typ.Underlying().(*types.Struct)
|
strct, ok := typ.Underlying().(*types.Struct)
|
||||||
|
@ -1480,6 +1492,7 @@ func newCodegen(info *buildInfo, pkg *loader.PackageInfo) *codegen {
|
||||||
globals: map[string]int{},
|
globals: map[string]int{},
|
||||||
labels: map[labelWithType]uint16{},
|
labels: map[labelWithType]uint16{},
|
||||||
typeInfo: &pkg.Info,
|
typeInfo: &pkg.Info,
|
||||||
|
constMap: map[string]types.TypeAndValue{},
|
||||||
|
|
||||||
sequencePoints: make(map[string][]DebugSeqPoint),
|
sequencePoints: make(map[string][]DebugSeqPoint),
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,3 +187,12 @@ func TestExportedVariable(t *testing.T) {
|
||||||
eval(t, src, big.NewInt(46))
|
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))
|
||||||
|
}
|
||||||
|
|
2
pkg/compiler/testdata/multi/file1.go
vendored
2
pkg/compiler/testdata/multi/file1.go
vendored
|
@ -1,3 +1,5 @@
|
||||||
package multi
|
package multi
|
||||||
|
|
||||||
var SomeVar12 = 12
|
var SomeVar12 = 12
|
||||||
|
|
||||||
|
const SomeConst = 42
|
||||||
|
|
Loading…
Reference in a new issue