Skip to content

Commit

Permalink
fix #787
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Sep 23, 2021
1 parent acbb4bf commit 66dd100
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 41 deletions.
14 changes: 0 additions & 14 deletions cl/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,6 @@ func TestToString(t *testing.T) {
toString(&ast.BasicLit{Kind: token.INT, Value: "1"})
}

func TestLoadImport(t *testing.T) {
pkg := gox.NewPackage("", "foo", nil)
ctx := &blockCtx{pkg: pkg, cb: pkg.CB()}
defer func() {
if e := recover(); e == nil {
t.Fatal("loadImport: no error?")
}
}()
loadImport(ctx, &ast.ImportSpec{
Name: &ast.Ident{Name: "."},
Path: &ast.BasicLit{Kind: token.STRING, Value: `"fmt"`},
})
}

func TestGetTypeName(t *testing.T) {
if getTypeName(types.Typ[types.Int]) != "int" {
t.Fatal("getTypeName int failed")
Expand Down
29 changes: 16 additions & 13 deletions cl/class_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,35 +33,37 @@ import (
// -----------------------------------------------------------------------------

type gmxInfo struct {
pkgPath string
extSpx string
extSpx string
pkgPaths []string
}

var (
gmxTypes = map[string]gmxInfo{
".gmx": {"github.com/goplus/spx", ".spx"},
".gmx": {".spx", []string{"github.com/goplus/spx", "math"}},
}
)

// RegisterClassFileType registers Go+ class file types.
func RegisterClassFileType(extGmx, extSpx string, pkgPath string) {
func RegisterClassFileType(extGmx, extSpx string, pkgPaths ...string) {
if pkgPaths == nil {
panic("RegisterClassFileType: no pkgPath specified")
}
parser.RegisterFileType(extGmx, ast.FileTypeGmx)
parser.RegisterFileType(extSpx, ast.FileTypeSpx)
if _, ok := gmxTypes[extGmx]; !ok {
gmxTypes[extGmx] = gmxInfo{pkgPath, extSpx}
gmxTypes[extGmx] = gmxInfo{extSpx, pkgPaths}
}
}

// -----------------------------------------------------------------------------

type gmxSettings struct {
pkgPath string
gameClass string
extSpx string
spx *gox.PkgRef
game gox.Ref
sprite gox.Ref
scheds []goast.Stmt // nil or len(scheds) == 2
pkgPaths []string
}

func newGmx(pkg *gox.Package, file string) *gmxSettings {
Expand All @@ -71,15 +73,16 @@ func newGmx(pkg *gox.Package, file string) *gmxSettings {
name = name[:idx]
}
gt := gmxTypes[ext]
p := &gmxSettings{pkgPath: gt.pkgPath, extSpx: gt.extSpx, gameClass: name}
p.spx = pkg.Import(p.pkgPath)
p.game = spxRef(p.spx, "Gop_game", "Game")
p.sprite = spxRef(p.spx, "Gop_sprite", "Sprite")
if x := getStringConst(p.spx, "Gop_sched"); x != "" {
pkgPaths := gt.pkgPaths
spx := pkg.Import(pkgPaths[0])
p := &gmxSettings{extSpx: gt.extSpx, gameClass: name, pkgPaths: pkgPaths}
p.game = spxRef(spx, "Gop_game", "Game")
p.sprite = spxRef(spx, "Gop_sprite", "Sprite")
if x := getStringConst(spx, "Gop_sched"); x != "" {
scheds := strings.SplitN(x, ",", 2)
p.scheds = make([]goast.Stmt, 2)
for i, v := range scheds {
fn := pkg.CB().Val(p.spx.Ref(v)).Call(0).InternalStack().Pop().Val
fn := pkg.CB().Val(spx.Ref(v)).Call(0).InternalStack().Pop().Val
p.scheds[i] = &goast.ExprStmt{X: fn}
}
if len(scheds) < 2 {
Expand Down
8 changes: 7 additions & 1 deletion cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ type blockCtx struct {
cb *gox.CodeBuilder
fset *token.FileSet
imports map[string]*gox.PkgRef
lookups []*gox.PkgRef
targetDir string
classRecv *ast.FieldList // avaliable when gmxSettings != nil
fileLine bool
Expand Down Expand Up @@ -512,6 +513,10 @@ func preloadFile(p *gox.Package, parent *pkgCtx, file string, f *ast.File, targe
if debugLoad {
log.Println("==> Preload type", classType)
}
ctx.lookups = make([]*gox.PkgRef, len(parent.pkgPaths))
for i, pkgPath := range parent.pkgPaths {
ctx.lookups[i] = p.Import(pkgPath)
}
pos := f.Pos()
specs := getFields(ctx, f)
ld := getTypeLoader(syms, pos, classType)
Expand Down Expand Up @@ -788,7 +793,8 @@ func loadImport(ctx *blockCtx, spec *ast.ImportSpec) {
if spec.Name != nil {
name = spec.Name.Name
if name == "." {
panic("TODO: not impl")
ctx.lookups = append(ctx.lookups, pkg)
return
}
if name == "_" {
pkg.MarkForceUsed()
Expand Down
9 changes: 7 additions & 2 deletions cl/compile_spx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func newTwoFileFS(dir string, fname, data string, fname2 string, data2 string) *
}

func init() {
cl.RegisterClassFileType(".tgmx", ".tspx", "github.com/goplus/gop/cl/internal/spx")
cl.RegisterClassFileType(".tgmx", ".tspx", "github.com/goplus/gop/cl/internal/spx", "math")
}

func gopSpxTest(t *testing.T, gmx, spxcode, expected string) {
Expand Down Expand Up @@ -151,6 +151,7 @@ func onInit() {
sched
broadcast "msg1"
testIntValue = 1
x := round(1.2)
}
`, `
func onInit() {
Expand All @@ -161,7 +162,10 @@ func onInit() {
}
`, `package main
import spx "github.com/goplus/gop/cl/internal/spx"
import (
spx "github.com/goplus/gop/cl/internal/spx"
math "math"
)
type Game struct {
spx.MyGame
Expand All @@ -171,6 +175,7 @@ func (this *Game) onInit() {
spx.Sched()
this.Broadcast__0("msg1")
spx.TestIntValue = 1
x := math.Round(1.2)
}
type bar struct {
Expand Down
12 changes: 12 additions & 0 deletions cl/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2341,6 +2341,18 @@ func main() {
`)
}

func TestDotImport(t *testing.T) {
gopClTest(t, `import . "math"
var a = round(1.2)
`, `package main
import math "math"
var a = math.Round(1.2)
`)
}

func TestImportUnused(t *testing.T) {
gopClTest(t, `import "fmt"
Expand Down
10 changes: 10 additions & 0 deletions cl/error_msg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ func foo(v map[int]bar) {
}

func TestErrImport(t *testing.T) {
codeErrorTest(t,
`./bar.gop:8:2: confliction: NewEncoding declared both in "encoding/base64" and "encoding/base32"`, `
import (
. "encoding/base32"
. "encoding/base64"
)
func foo() {
NewEncoding("Hi")
}`)
codeErrorTest(t,
"./bar.gop:5:2: cannot refer to unexported name os.undefined", `
import "os"
Expand Down
27 changes: 21 additions & 6 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,9 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) *gox.PkgRef {
}
}

// spx object
if ctx.fileType > 0 {
if compilePkgRef(ctx, ctx.spx, ident, flags) {
return nil
}
// object from import . "xxx"
if compilePkgRef(ctx, nil, ident, flags) {
return nil
}

// universe object
Expand Down Expand Up @@ -334,8 +332,25 @@ func pkgRef(at *gox.PkgRef, name string) (o types.Object, canAutoCall bool) {
return at.Ref(name), false
}

func lookupPkgRef(ctx *blockCtx, pkg *gox.PkgRef, x *ast.Ident) (o types.Object, canAutoCall bool) {
if pkg != nil {
return pkgRef(pkg, x.Name)
}
for _, at := range ctx.lookups {
if o2, canAutoCall2 := pkgRef(at, x.Name); o2 != nil {
if o != nil {
panic(ctx.newCodeErrorf(
x.Pos(), "confliction: %s declared both in \"%s\" and \"%s\"",
x.Name, at.Types.Path(), pkg.Types.Path()))
}
pkg, o, canAutoCall = at, o2, canAutoCall2
}
}
return
}

func compilePkgRef(ctx *blockCtx, at *gox.PkgRef, x *ast.Ident, flags int) bool {
if v, canAutoCall := pkgRef(at, x.Name); v != nil {
if v, canAutoCall := lookupPkgRef(ctx, at, x); v != nil {
cb := ctx.cb
if (flags & clIdentLHS) != 0 {
cb.VarRef(v, x)
Expand Down
8 changes: 3 additions & 5 deletions cl/func_type_and_var.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,9 @@ func toIdentType(ctx *blockCtx, ident *ast.Ident) types.Type {
if t, ok := v.(*types.TypeName); ok {
return t.Type()
}
if ctx.fileType > 0 {
if v := ctx.spx.Ref(ident.Name); v != nil {
if t, ok := v.(*types.TypeName); ok {
return t.Type()
}
if v, _ := lookupPkgRef(ctx, nil, ident); v != nil {
if t, ok := v.(*types.TypeName); ok {
return t.Type()
}
}
panic(ctx.newCodeErrorf(ident.Pos(), "%s is not a type", ident.Name))
Expand Down

0 comments on commit 66dd100

Please sign in to comment.