fix: handle name import of src packages (#74)

Rename the package scope from internal package name to alias name.
Detect different packages in the same directory (forbidden by spec).
Update example to test named import.
This commit is contained in:
Marc Vertes
2019-02-02 14:18:09 +01:00
committed by Ludovic Fernandez
parent e347d35c24
commit 6fc6560af3
8 changed files with 122 additions and 3 deletions

View File

@@ -0,0 +1,7 @@
package fromage
import "fmt"
func Hello() string {
return fmt.Sprint("Fromage!")
}

View File

@@ -0,0 +1,17 @@
package pkg
import (
"fmt"
fr "github.com/foo/pkg/fromage"
)
func Here() string {
return "root"
}
func NewSample() func() string {
return func() string {
return fmt.Sprintf("%s %s", Here(), fr.Hello())
}
}

View File

@@ -0,0 +1,7 @@
package fromage
import "fmt"
func Hello() string {
return fmt.Sprint("Fromage!")
}

View File

@@ -0,0 +1,17 @@
package pkg
import (
"fmt"
"github.com/foo/pkg/fromage"
)
func Here() string {
return "root"
}
func NewSample() func() string {
return func() string {
return fmt.Sprintf("%s %s", Here(), fromage.Hello())
}
}

View File

@@ -0,0 +1,17 @@
package pkgfalse
import (
"fmt"
"github.com/foo/pkg/fromage"
)
func HereNot() string {
return "root"
}
func NewSampleNot() func() string {
return func() string {
return fmt.Sprintf("%s %s", HereNot(), fromage.Here())
}
}

View File

@@ -59,6 +59,11 @@ func TestPackages(t *testing.T) {
goPath: "./_pkg7/",
expected: "root vin cheese fromage",
},
{
desc: "named subpackage",
goPath: "./_pkg8/",
expected: "root Fromage!",
},
}
for _, test := range testCases {
@@ -96,3 +101,39 @@ func TestPackages(t *testing.T) {
})
}
}
func TestPackagesError(t *testing.T) {
testCases := []struct {
desc string
goPath string
expected string
}{
{
desc: "different packages in the same directory",
goPath: "./_pkg9/",
expected: "found packages pkg and pkgfalse in _pkg9/src/github.com/foo/pkg",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
// Init go interpreter
i := interp.New(interp.Opt{
GoPath: test.goPath,
})
i.Use(stdlib.Value, stdlib.Type) // Use binary standard library
// Load pkg from sources
_, err := i.Eval(`import "github.com/foo/pkg"`)
if err == nil {
t.Fatalf("got no error, want %q", test.expected)
}
if err.Error() != test.expected {
t.Errorf("got %q, want %q", err.Error(), test.expected)
}
})
}
}

View File

@@ -100,7 +100,7 @@ func (interp *Interpreter) Gta(root *Node, rpath string) error {
}
} else {
// TODO: make sure we do not import a src package more than once
err = interp.importSrcFile(rpath, ipath)
err = interp.importSrcFile(rpath, ipath, name)
scope.sym[name] = &Symbol{typ: &Type{cat: SrcPkgT}, path: ipath}
}

View File

@@ -8,7 +8,7 @@ import (
"strings"
)
func (i *Interpreter) importSrcFile(rPath, path string) error {
func (i *Interpreter) importSrcFile(rPath, path, alias string) error {
dir, rPath, err := pkgDir(i.GoPath, rPath, path)
if err != nil {
return err
@@ -23,6 +23,7 @@ func (i *Interpreter) importSrcFile(rPath, path string) error {
var rootNodes []*Node
var root *Node
var pkgName string
// Parse source files
for _, file := range files {
@@ -40,9 +41,15 @@ func (i *Interpreter) importSrcFile(rPath, path string) error {
return err
}
if _, root, err = i.ast(string(buf), name); err != nil {
var pname string
if pname, root, err = i.ast(string(buf), name); err != nil {
return err
}
if pkgName == "" {
pkgName = pname
} else if pkgName != pname {
return fmt.Errorf("found packages %s and %s in %s", pkgName, pname, dir)
}
rootNodes = append(rootNodes, root)
if i.AstDot {
@@ -64,6 +71,12 @@ func (i *Interpreter) importSrcFile(rPath, path string) error {
initNodes = append(initNodes, nodes...)
}
// Rename imported pkgName to alias if they are different
if pkgName != alias {
i.scope[alias] = i.scope[pkgName]
delete(i.scope, pkgName)
}
if i.NoRun {
return nil
}