compiler: set type information during traversal, fix #2231

Set all necessary context before file traversal, not only import
maps. Also, we can skip restoring import maps because all our code is
processed via `For*` iterators which set necessary context.
We can also refactor this a bit to have all context in one place,
this will be done in #2086.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgeniy Stratonikov 2021-10-25 10:52:15 +03:00
parent eea728b986
commit 8a0429036b
3 changed files with 32 additions and 2 deletions

View file

@ -301,7 +301,12 @@ func (c *codegen) analyzeFuncUsage() funcUsage {
}
usage[name] = true
old := c.importMap
pkg := c.mainPkg
if fd.path != "" {
pkg = c.buildInfo.program.Package(fd.path)
}
c.typeInfo = &pkg.Info
c.currPkg = pkg.Pkg
c.importMap = fd.importMap
ast.Inspect(fd.decl, func(node ast.Node) bool {
switch n := node.(type) {
@ -316,7 +321,6 @@ func (c *codegen) analyzeFuncUsage() funcUsage {
}
return true
})
c.importMap = old
}
diff = nextDiff
}

View file

@ -350,4 +350,17 @@ func TestUnusedFunctions(t *testing.T) {
require.NoError(t, err)
eval(t, src, big.NewInt(65))
})
t.Run("method inside of an imported package", func(t *testing.T) {
// Check that import map is set correctly during package traversal.
src := `package foo
import inner "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/nestedcall"
func Main() int {
var t inner.Token
return t.Method()
}`
_, err := compiler.Compile("foo", strings.NewReader(src))
require.NoError(t, err)
eval(t, src, big.NewInt(2231))
})
}

View file

@ -28,3 +28,16 @@ func y() int {
tmp := 10
return tmp
}
// Token is stateless token.
type Token struct{}
// Method is a method.
func (t Token) Method() int {
return t.Inner()
}
// Inner is a function to be called in Method.
func (t Token) Inner() int {
return 2231
}