Skip to content

Commit

Permalink
Merge pull request #1556 from goplus/main
Browse files Browse the repository at this point in the history
v1.1.12
  • Loading branch information
xushiwei authored Nov 25, 2023
2 parents db289a9 + 8cf27b4 commit 169bdb6
Show file tree
Hide file tree
Showing 21 changed files with 1,121 additions and 74 deletions.
14 changes: 13 additions & 1 deletion cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import (
"go/types"
"log"
"os"
"path/filepath"
"reflect"
"sort"
"strings"

"github.com/goplus/gop/ast"
"github.com/goplus/gop/ast/fromgo"
"github.com/goplus/gop/cl/internal/typesutil"
"github.com/goplus/gop/token"
"github.com/goplus/gox"
"github.com/goplus/gox/cpackages"
Expand Down Expand Up @@ -204,6 +206,9 @@ type Config struct {
// RelativePath = true means to generate file line comments with relative file path.
RelativePath bool

// FileLineRoot set means generate file line comments start with root path.
FileLineRoot string

// NoAutoGenMain = true means not to auto generate main func is no entry.
NoAutoGenMain bool

Expand All @@ -220,7 +225,7 @@ type goxRecorder struct {

// Member maps identifiers to the objects they denote.
func (p *goxRecorder) Member(id ast.Node, obj types.Object) {
tv := types.TypeAndValue{Type: obj.Type()}
tv := typesutil.NewTypeAndValueForObject(obj)
switch v := id.(type) {
case *ast.SelectorExpr:
sel := v.Sel
Expand Down Expand Up @@ -369,6 +374,9 @@ type pkgCtx struct {
generics map[string]bool // generic type record
idents []*ast.Ident // toType ident recored
inInst int // toType in generic instance

fileLineRoot string // comment file line start root
fileLineWorkingDir string // comment file line working dir
}

type pkgImp struct {
Expand Down Expand Up @@ -509,6 +517,10 @@ func NewPackage(pkgPath string, pkg *ast.Package, conf *Config) (p *gox.Package,
fset: fset,
syms: make(map[string]loader), nodeInterp: interp, generics: make(map[string]bool),
}
if conf.FileLineRoot != "" {
ctx.fileLineRoot, _ = filepath.Abs(conf.FileLineRoot)
ctx.fileLineWorkingDir, _ = filepath.Abs(workingDir)
}
confGox := &gox.Config{
Types: conf.Types,
Fset: fset,
Expand Down
61 changes: 61 additions & 0 deletions cl/compile_spx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -731,3 +731,64 @@ func (this *Kai) onMsg(msg string) {
}
`, "Game.tgmx", "Kai.tspx")
}

func TestSpxSelection(t *testing.T) {
gopSpxTestEx(t, `
println "hi"
`, `
import "fmt"
func onMsg(msg string) {
fmt.println msg
this.position.add 100,200
position.add 100,200
position.X += 100
println position.X
this.vector.add 100,200
vector.add 100,200
vector.X += 100
vector.self.X += 100
vector.self.Y += 200
vector.self.add position.X,position.Y
println vector.X
println vector.self.self
}
`, `package main
import (
"fmt"
"github.com/goplus/gop/cl/internal/spx"
)
type Game struct {
*spx.MyGame
}
func (this *Game) MainEntry() {
fmt.Println("hi")
}
func main() {
spx.Gopt_MyGame_Main(new(Game))
}
type Kai struct {
spx.Sprite
*Game
}
func (this *Kai) onMsg(msg string) {
fmt.Println(msg)
this.Position().Add__0(100, 200)
this.Position().Add__0(100, 200)
this.Position().X += 100
fmt.Println(this.Position().X)
this.Vector().Add__0(100, 200)
this.Vector().Add__0(100, 200)
this.Vector().X += 100
this.Vector().Self().X += 100
this.Vector().Self().Y += 200
this.Vector().Self().Add__0(this.Position().X, this.Position().Y)
fmt.Println(this.Vector().X)
fmt.Println(this.Vector().Self().Self())
}
`, "Game.tgmx", "Kai.tspx")
}
62 changes: 62 additions & 0 deletions cl/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package cl_test
import (
"bytes"
"os"
"runtime"
"strings"
"sync"
"testing"
Expand Down Expand Up @@ -4652,3 +4653,64 @@ func main() {
}
`)
}

func TestCommentLineRoot(t *testing.T) {
conf := *gblConf
conf.NoFileLine = false
conf.FileLineRoot = "/foo/root"
conf.WorkingDir = "/foo"
conf.TargetDir = "/foo"
var src = `
type Point struct {
x int
y int
}
func (pt *Point) Test() {
println(pt.x, pt.y)
}
// testPoint is test point
func testPoint() {
var pt Point
pt.Test()
}
println "hello"
testPoint()
`
var expected = `package main
import "fmt"
type Point struct {
x int
y int
}
//line ../bar.gop:7:1
func (pt *Point) Test() {
//line ../bar.gop:8:1
fmt.Println(pt.x, pt.y)
}
// testPoint is test point
//
//line ../bar.gop:12:1
func testPoint() {
//line ../bar.gop:13:1
var pt Point
//line ../bar.gop:14:1
pt.Test()
}
//line ../bar.gop:17
func main() {
//line ../bar.gop:17:1
fmt.Println("hello")
//line ../bar.gop:18:1
testPoint()
}
`
if runtime.GOOS == "windows" {
expected = strings.Replace(expected, "../", `..\foo\`, -1)
}
gopClTestEx(t, &conf, "main", src, expected)
}
49 changes: 40 additions & 9 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ func compileIdent(ctx *blockCtx, ident *ast.Ident, flags int) (pkg *gox.PkgRef,
sig := fn.Ancestor().Type().(*types.Signature)
if recv := sig.Recv(); recv != nil {
ctx.cb.Val(recv)
if compileMember(ctx, ident, name, flags&^clCommandWithoutArgs) == nil { // class member object
chkFlag := flags &^ clCommandWithoutArgs
if chkFlag&clIdentSelectorExpr != 0 {
chkFlag = clIdentCanAutoCall
}
if compileMember(ctx, ident, name, chkFlag) == nil { // class member object
return
}
ctx.cb.InternalStack().PopN(1)
Expand Down Expand Up @@ -158,12 +162,11 @@ find:
e := ctx.cb.Get(-1)
if oldo != nil && gox.IsTypeEx(e.Type) {
rec.Use(ident, oldo)
rec.Type(ident, typesutil.NewTypeAndValueForObject(oldo))
return
}
rec.Use(ident, o)
typ, _ := gox.DerefType(e.Type)
tv := typesutil.NewTypeAndValue(typ, e.CVal)
rec.Type(ident, tv)
rec.Type(ident, typesutil.NewTypeAndValueForObject(o))
}
return
}
Expand Down Expand Up @@ -199,6 +202,7 @@ func compileExprLHS(ctx *blockCtx, expr ast.Expr) {
compileIndexExprLHS(ctx, v)
case *ast.SelectorExpr:
compileSelectorExprLHS(ctx, v)
recordTypesVariable(ctx, v, -1)
case *ast.StarExpr:
compileStarExprLHS(ctx, v)
default:
Expand All @@ -210,6 +214,21 @@ func twoValue(inFlags []int) bool {
return inFlags != nil && (inFlags[0]&clCallWithTwoValue) != 0
}

func recordTypesValue(ctx *blockCtx, expr ast.Expr, n int) {
if rec := ctx.recorder(); rec != nil {
e := ctx.cb.Get(n)
rec.Type(expr, typesutil.NewTypeAndValueForValue(e.Type, e.CVal))
}
}

func recordTypesVariable(ctx *blockCtx, expr ast.Expr, n int) {
if rec := ctx.recorder(); rec != nil {
e := ctx.cb.Get(n)
t, _ := gox.DerefType(e.Type)
rec.Type(expr, typesutil.NewTypeAndValueForVariable(t))
}
}

func compileExpr(ctx *blockCtx, expr ast.Expr, inFlags ...int) {
switch v := expr.(type) {
case *ast.Ident:
Expand All @@ -220,6 +239,7 @@ func compileExpr(ctx *blockCtx, expr ast.Expr, inFlags ...int) {
compileIdent(ctx, v, flags)
case *ast.BasicLit:
compileBasicLit(ctx, v)
recordTypesValue(ctx, v, -1)
case *ast.CallExpr:
flags := 0
if inFlags != nil {
Expand All @@ -234,8 +254,10 @@ func compileExpr(ctx *blockCtx, expr ast.Expr, inFlags ...int) {
compileSelectorExpr(ctx, v, flags)
case *ast.BinaryExpr:
compileBinaryExpr(ctx, v)
recordTypesValue(ctx, v, -1)
case *ast.UnaryExpr:
compileUnaryExpr(ctx, v, twoValue(inFlags))
recordTypesValue(ctx, v, -1)
case *ast.FuncLit:
compileFuncLit(ctx, v)
case *ast.CompositeLit:
Expand Down Expand Up @@ -359,10 +381,6 @@ func compileSelectorExprLHS(ctx *blockCtx, v *ast.SelectorExpr) {
}
default:
compileExpr(ctx, v.X)
if rec := ctx.recorder(); rec != nil {
e := ctx.cb.Get(-1)
rec.Type(v.X, typesutil.NewTypeAndValue(e.Type, e.CVal))
}
}
ctx.cb.MemberRef(v.Sel.Name, v)
}
Expand All @@ -383,7 +401,7 @@ func compileSelectorExpr(ctx *blockCtx, v *ast.SelectorExpr, flags int) {
compileExpr(ctx, v.X)
if rec := ctx.recorder(); rec != nil {
e := ctx.cb.Get(-1)
rec.Type(v.X, typesutil.NewTypeAndValue(e.Type, e.CVal))
rec.Type(v.X, typesutil.NewTypeAndValueForType(e.Type))
}
}
if err := compileMember(ctx, v, v.Sel.Name, flags); err != nil {
Expand Down Expand Up @@ -544,6 +562,9 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) {
for fn != nil {
err := compileCallArgs(fn, fnt, ctx, v, ellipsis, flags)
if err == nil {
if rec := ctx.recorder(); rec != nil {
rec.Type(v, typesutil.NewTypeAndValueForCallResult(ctx.cb.Get(-1).Type))
}
break
}
if fn.next == nil {
Expand Down Expand Up @@ -794,6 +815,9 @@ func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, t
err := ctx.newCodeErrorf(name.Pos(), "%s undefined (type %v has no field or method %s)", src, typ, name.Name)
panic(err)
}
if rec := ctx.recorder(); rec != nil {
rec.Use(name, t.Field(idx))
}
switch expr := kv.Value.(type) {
case *ast.LambdaExpr, *ast.LambdaExpr2:
sig := checkLambdaFuncType(ctx, expr, t.Field(idx).Type(), clLambaField, kv.Key)
Expand Down Expand Up @@ -878,6 +902,9 @@ func compileCompositeLit(ctx *blockCtx, v *ast.CompositeLit, expected types.Type
}
if t, ok := underlying.(*types.Struct); ok && kind == compositeLitKeyVal {
compileStructLitInKeyVal(ctx, v.Elts, t, typ, v)
if rec := ctx.recorder(); rec != nil {
rec.Type(v, typesutil.NewTypeAndValueForValue(typ, nil))
}
if hasPtr {
ctx.cb.UnaryOp(gotoken.AND)
}
Expand All @@ -892,6 +919,10 @@ func compileCompositeLit(ctx *blockCtx, v *ast.CompositeLit, expected types.Type
ctx.cb.MapLit(nil, n<<1)
return
}
if rec := ctx.recorder(); rec != nil {
rec.Type(v.Type, typesutil.NewTypeAndValueForType(typ))
rec.Type(v, typesutil.NewTypeAndValueForValue(typ, nil))
}
switch underlying.(type) {
case *types.Slice:
ctx.cb.SliceLitEx(typ, n<<kind, kind == compositeLitKeyVal, v)
Expand Down
15 changes: 13 additions & 2 deletions cl/func_type_and_var.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strconv"

"github.com/goplus/gop/ast"
"github.com/goplus/gop/cl/internal/typesutil"
"github.com/goplus/gop/token"
"github.com/goplus/gox"
)
Expand Down Expand Up @@ -112,7 +113,12 @@ func toParam(ctx *blockCtx, fld *ast.Field, args []*gox.Param) []*gox.Param {

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

func toType(ctx *blockCtx, typ ast.Expr) types.Type {
func toType(ctx *blockCtx, typ ast.Expr) (t types.Type) {
if rec := ctx.recorder(); rec != nil {
defer func() {
rec.Type(typ, typesutil.NewTypeAndValueForType(t))
}()
}
switch v := typ.(type) {
case *ast.Ident:
ctx.idents = append(ctx.idents, v)
Expand Down Expand Up @@ -228,6 +234,7 @@ func toIdentType(ctx *blockCtx, ident *ast.Ident) (ret types.Type) {
defer func() {
if obj != nil {
rec.Use(ident, obj)
rec.Type(ident, typesutil.NewTypeAndValueForObject(obj))
}
}()
}
Expand Down Expand Up @@ -341,7 +348,11 @@ func toStructType(ctx *blockCtx, v *ast.StructType) *types.Struct {
}
}
}
return types.NewStruct(fields, tags)
st := types.NewStruct(fields, tags)
if rec != nil {
rec.Type(v, typesutil.NewTypeAndValueForType(st))
}
return st
}

func toFieldTag(v *ast.BasicLit) string {
Expand Down
Loading

0 comments on commit 169bdb6

Please sign in to comment.