compiler: check for pkg nilness, fix #3202
Unfortunately, when import cycle happens somewhere deep in the import chain we dont't get an error from packages.Load(). But it leaves some imports uninitialized, so at least we can check for them. Signed-off-by: Roman Khimov <roman@nspcc.ru>
This commit is contained in:
parent
fced6a27ba
commit
eade327b9b
6 changed files with 70 additions and 1 deletions
|
@ -282,7 +282,14 @@ func (c *codegen) visitPkg(pkg *packages.Package, seen map[string]bool) {
|
|||
return
|
||||
}
|
||||
for _, imp := range pkg.Types.Imports() {
|
||||
c.visitPkg(pkg.Imports[imp.Path()], seen)
|
||||
var subpkg = pkg.Imports[imp.Path()]
|
||||
if subpkg == nil {
|
||||
if c.prog.Err == nil {
|
||||
c.prog.Err = fmt.Errorf("failed to load %q package from %q, import cycle?", imp.Path(), pkg.PkgPath)
|
||||
}
|
||||
return
|
||||
}
|
||||
c.visitPkg(subpkg, seen)
|
||||
}
|
||||
seen[pkg.PkgPath] = true
|
||||
c.packages = append(c.packages, pkg.PkgPath)
|
||||
|
|
|
@ -2209,6 +2209,9 @@ func (c *codegen) newLambda(u uint16, lit *ast.FuncLit) {
|
|||
func (c *codegen) compile(info *buildInfo, pkg *packages.Package) error {
|
||||
c.mainPkg = pkg
|
||||
c.analyzePkgOrder()
|
||||
if c.prog.Err != nil {
|
||||
return c.prog.Err
|
||||
}
|
||||
c.fillDocumentInfo()
|
||||
funUsage := c.analyzeFuncAndGlobalVarUsage()
|
||||
if c.prog.Err != nil {
|
||||
|
|
|
@ -2,7 +2,11 @@ package compiler_test
|
|||
|
||||
import (
|
||||
"math/big"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestImportFunction(t *testing.T) {
|
||||
|
@ -61,3 +65,27 @@ func TestImportNameSameAsOwn(t *testing.T) {
|
|||
}`
|
||||
eval(t, src, big.NewInt(3))
|
||||
}
|
||||
|
||||
func TestImportCycleDirect(t *testing.T) {
|
||||
src := `
|
||||
package some
|
||||
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg2"
|
||||
func Main() int {
|
||||
return pkg2.A
|
||||
}
|
||||
`
|
||||
_, _, err := compiler.CompileWithOptions("some.go", strings.NewReader(src), nil)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestImportCycleIndirect(t *testing.T) {
|
||||
src := `
|
||||
package some
|
||||
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg1"
|
||||
func Main() int {
|
||||
return pkg1.A
|
||||
}
|
||||
`
|
||||
_, _, err := compiler.CompileWithOptions("some.go", strings.NewReader(src), nil)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
|
9
pkg/compiler/testdata/importcycle/pkg1/pkg1.go
vendored
Normal file
9
pkg/compiler/testdata/importcycle/pkg1/pkg1.go
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
package pkg1
|
||||
|
||||
import "github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg2"
|
||||
|
||||
var A int
|
||||
|
||||
func init() {
|
||||
pkg2.A = 1
|
||||
}
|
11
pkg/compiler/testdata/importcycle/pkg2/pkg2.go
vendored
Normal file
11
pkg/compiler/testdata/importcycle/pkg2/pkg2.go
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package pkg2
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg3"
|
||||
)
|
||||
|
||||
var A int
|
||||
|
||||
func init() {
|
||||
pkg3.A = 2
|
||||
}
|
11
pkg/compiler/testdata/importcycle/pkg3/pkg3.go
vendored
Normal file
11
pkg/compiler/testdata/importcycle/pkg3/pkg3.go
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package pkg3
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neo-go/pkg/compiler/testdata/importcycle/pkg2"
|
||||
)
|
||||
|
||||
var A int
|
||||
|
||||
func init() {
|
||||
pkg2.A = 1
|
||||
}
|
Loading…
Reference in a new issue