Repository: goplus/gop
Pull request #1672 (2024-01-26 12:10:09)

cl: typesRecorder.instantiate for gox TyOverloadNamed


Patch:
diff --git a/ast/walk.go b/ast/walk.go
index 08874611..fc9f98d1 100644
--- a/ast/walk.go
+++ b/ast/walk.go
@@ -98,18 +98,9 @@ func Walk(v Visitor, node Node) {
 		}
 
 	// Expressions
-	case *BadExpr, *Ident:
+	case *BadExpr, *Ident, *BasicLit:
 		// nothing to do
 
-	case *BasicLit:
-		if n.Extra != nil { // Go+ extended
-			for _, part := range n.Extra.Parts {
-				if e, ok := part.(Expr); ok {
-					Walk(v, e)
-				}
-			}
-		}
-
 	case *Ellipsis:
 		if n.Elt != nil {
 			Walk(v, n.Elt)
@@ -386,7 +377,7 @@ func Walk(v Visitor, node Node) {
 			Walk(v, f)
 		}
 
-	// Go+ extended expr and stmt
+	// Go+ expr and stmt
 	case *SliceLit:
 		walkExprList(v, n.Elts)
 
@@ -442,16 +433,6 @@ func Walk(v Visitor, node Node) {
 			Walk(v, n.Default)
 		}
 
-	case *OverloadFuncDecl:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		if n.Recv != nil {
-			Walk(v, n.Recv)
-		}
-		Walk(v, n.Name)
-		walkExprList(v, n.Funcs)
-
 	default:
 		panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n))
 	}
diff --git a/cl/expr.go b/cl/expr.go
index fb6cc143..ee2cddb3 100644
--- a/cl/expr.go
+++ b/cl/expr.go
@@ -1175,7 +1175,7 @@ func compileErrWrapExpr(ctx *blockCtx, v *ast.ErrWrapExpr, inFlags int) {
 			retName = "_gop_ret" + strconv.Itoa(i+1)
 		}
 	}
-	sig := types.NewSignatureType(nil, nil, nil, nil, types.NewTuple(ret...), false)
+	sig := types.NewSignature(nil, nil, types.NewTuple(ret...), false)
 	if useClosure {
 		cb.NewClosureWith(sig).BodyStart(pkg)
 	} else {
diff --git a/cl/func_type_and_var.go b/cl/func_type_and_var.go
index 8141f011..03fa6fdb 100644
--- a/cl/func_type_and_var.go
+++ b/cl/func_type_and_var.go
@@ -449,7 +449,11 @@ func instantiate(ctx *blockCtx, exprX ast.Expr, indices ...ast.Expr) types.Type
 	for i, index := range indices {
 		idx[i] = toType(ctx, index)
 	}
-	return ctx.pkg.Instantiate(x, idx, exprX)
+	typ := ctx.pkg.Instantiate(x, idx, exprX)
+	if rec := ctx.recorder(); rec != nil {
+		rec.instantiate(exprX, x, typ)
+	}
+	return typ
 }
 
 func toIndexType(ctx *blockCtx, v *ast.IndexExpr) types.Type {
diff --git a/cl/recorder.go b/cl/recorder.go
index 5ce8e9cb..3ffb0e02 100644
--- a/cl/recorder.go
+++ b/cl/recorder.go
@@ -76,6 +76,26 @@ func (rec *typesRecorder) Type(expr ast.Expr, tv types.TypeAndValue) {
 	rec.Recorder.Type(expr, tv)
 }
 
+func (rec *typesRecorder) instantiate(expr ast.Expr, org, typ types.Type) {
+	// check gox TyOverloadNamed
+	if tv, ok := rec.types[expr]; ok {
+		tv.Type = typ
+		rec.Recorder.Type(expr, tv)
+	}
+	var ident *ast.Ident
+	switch id := expr.(type) {
+	case *ast.Ident:
+		ident = id
+	case *ast.SelectorExpr:
+		ident = id.Sel
+	}
+	if ident != nil {
+		if named, ok := typ.(*types.Named); ok {
+			rec.Use(ident, named.Obj())
+		}
+	}
+}
+
 func newTypeRecord(rec Recorder) *typesRecorder {
 	return &typesRecorder{rec, make(map[ast.Expr]types.TypeAndValue)}
 }
diff --git a/go.mod b/go.mod
index 5003d859..dbc8b2dc 100644
--- a/go.mod
+++ b/go.mod
@@ -5,8 +5,8 @@ go 1.18
 require (
 	github.com/fsnotify/fsnotify v1.7.0
 	github.com/goplus/c2go v0.7.20-0.20240115161159-762f74054b17
-	github.com/goplus/gox v1.13.1-0.20240125113411-ce41652103db
-	github.com/goplus/mod v0.12.2-0.20240123033711-abba4c2e8b32
+	github.com/goplus/gox v1.13.1-0.20240126072039-ad4303141498
+	github.com/goplus/mod v0.12.2
 	github.com/qiniu/x v1.13.2
 	golang.org/x/tools v0.17.0
 )
diff --git a/go.sum b/go.sum
index 6b44ae96..f6c12848 100644
--- a/go.sum
+++ b/go.sum
@@ -7,11 +7,11 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
 github.com/goplus/c2go v0.7.20-0.20240115161159-762f74054b17 h1:2+AWW9KjzTwaM8pfvRZqhI3PCXs7cMxzsn98AqDpgH0=
 github.com/goplus/c2go v0.7.20-0.20240115161159-762f74054b17/go.mod h1:WFbERV86IVV4wJ2/mLa8756Fy6iSXtlwGQbEqkYoIR4=
 github.com/goplus/gox v1.13.1-0.20240115155941-e657d899cb2e/go.mod h1:G7Hz+cAOUyJyN9pPHrpqhfQPDUtiJNmoRVTwoaQ9nw0=
-github.com/goplus/gox v1.13.1-0.20240125113411-ce41652103db h1:WCFom2ltMaK6bLmGDsv/i4qc71DYq/7NeH17zUg/DOo=
-github.com/goplus/gox v1.13.1-0.20240125113411-ce41652103db/go.mod h1:G7Hz+cAOUyJyN9pPHrpqhfQPDUtiJNmoRVTwoaQ9nw0=
+github.com/goplus/gox v1.13.1-0.20240126072039-ad4303141498 h1:1iwsA7pIGPtSNLfWOXq7rmUuUmM57l0PU79ndyeyZNY=
+github.com/goplus/gox v1.13.1-0.20240126072039-ad4303141498/go.mod h1:G7Hz+cAOUyJyN9pPHrpqhfQPDUtiJNmoRVTwoaQ9nw0=
 github.com/goplus/mod v0.12.2-0.20240107203906-5044606d0c51/go.mod h1:ZtlS9wHOcAVxZ/zq7WLdKVes1HG/8Yn3KNuWZGcpeTs=
-github.com/goplus/mod v0.12.2-0.20240123033711-abba4c2e8b32 h1:9eOpqJKwb/V3uxfM/CZ0V9Wn/a9NtSmfx2VyXics2+I=
-github.com/goplus/mod v0.12.2-0.20240123033711-abba4c2e8b32/go.mod h1:ZtlS9wHOcAVxZ/zq7WLdKVes1HG/8Yn3KNuWZGcpeTs=
+github.com/goplus/mod v0.12.2 h1:5RHUdmXT5jlzOFUAfrx/5uSk4RTphFPFcCbRUt/AIBo=
+github.com/goplus/mod v0.12.2/go.mod h1:ZtlS9wHOcAVxZ/zq7WLdKVes1HG/8Yn3KNuWZGcpeTs=
 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
diff --git a/parser/interface.go b/parser/interface.go
index 7fd616af..1b61209b 100644
--- a/parser/interface.go
+++ b/parser/interface.go
@@ -46,15 +46,12 @@ const (
 	AllErrors = Mode(goparser.AllErrors)
 	// SkipObjectResolution - don't resolve identifiers to objects - see ParseFile
 	SkipObjectResolution = Mode(goparser.SkipObjectResolution)
-
 	// ParseGoAsGoPlus - parse Go files by gop/parser
 	ParseGoAsGoPlus Mode = 1 << 16
 	// ParserGoPlusClass - parse Go+ classfile by gop/parser
 	ParseGoPlusClass Mode = 1 << 17
 	// SaveAbsFile - parse and save absolute path to pkg.Files
 	SaveAbsFile Mode = 1 << 18
-
-	goReservedFlags Mode = ((1 << 16) - 1)
 )
 
 // -----------------------------------------------------------------------------
diff --git a/parser/parser_gop.go b/parser/parser_gop.go
index 34f549f2..d3fe3e99 100644
--- a/parser/parser_gop.go
+++ b/parser/parser_gop.go
@@ -161,7 +161,7 @@ func ParseFSDir(fset *token.FileSet, fs FileSystem, dir string, conf Config) (pk
 			filename := fs.Join(dir, fname)
 			if useGoParser {
 				if filedata, err := fs.ReadFile(filename); err == nil {
-					if src, err := goparser.ParseFile(fset, filename, filedata, goparser.Mode(conf.Mode&goReservedFlags)); err == nil {
+					if src, err := goparser.ParseFile(fset, filename, filedata, goparser.Mode(conf.Mode)); err == nil {
 						pkg := reqPkg(pkgs, src.Name.Name)
 						if pkg.GoFiles == nil {
 							pkg.GoFiles = make(map[string]*goast.File)


Test patch:
diff --git a/x/typesutil/info_test.go b/x/typesutil/info_test.go
index 4632f22f..addddcaa 100644
--- a/x/typesutil/info_test.go
+++ b/x/typesutil/info_test.go
@@ -1385,3 +1385,173 @@ func (p *N) Test__1(n int) {
 005:  6: 1 | n                   | var n main.N
 006:  6: 3 | test                | func (*main.N).Test__1(n int)`)
 }
+
+func TestOverloadNamed(t *testing.T) {
+	testGopInfo(t, `
+import "github.com/goplus/gop/cl/internal/overload/bar"
+
+var a bar.Var[int]
+var b bar.Var[bar.M]
+c := bar.Var(string)
+d := bar.Var(bar.M)
+`, ``, `== types ==
+000:  4: 7 | bar.Var             *ast.SelectorExpr              | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__0[int] | type
+001:  4: 7 | bar.Var[int]        *ast.IndexExpr                 | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__0[int] | type
+002:  4:15 | int                 *ast.Ident                     | type    : int | type
+003:  5: 7 | bar.Var             *ast.SelectorExpr              | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any] | type
+004:  5: 7 | bar.Var[bar.M]      *ast.IndexExpr                 | type    : github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any] | type
+005:  5:15 | bar.M               *ast.SelectorExpr              | type    : map[string]any | type
+006:  6: 6 | bar.Var             *ast.SelectorExpr              | value   : func[T github.com/goplus/gop/cl/internal/overload/bar.basetype]() *github.com/goplus/gop/cl/internal/overload/bar.Var__0[T] | value
+007:  6: 6 | bar.Var(string)     *ast.CallExpr                  | value   : *github.com/goplus/gop/cl/internal/overload/bar.Var__0[string] | value
+008:  6:14 | string              *ast.Ident                     | type    : string | type
+009:  7: 6 | bar.Var             *ast.SelectorExpr              | value   : func[T map[string]any]() *github.com/goplus/gop/cl/internal/overload/bar.Var__1[T] | value
+010:  7: 6 | bar.Var(bar.M)      *ast.CallExpr                  | value   : *github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any] | value
+011:  7:14 | bar.M               *ast.SelectorExpr              | var     : map[string]any | variable
+== defs ==
+000:  4: 5 | a                   | var main.a github.com/goplus/gop/cl/internal/overload/bar.Var__0[int]
+001:  5: 5 | b                   | var main.b github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any]
+002:  6: 1 | c                   | var c *github.com/goplus/gop/cl/internal/overload/bar.Var__0[string]
+003:  6: 1 | main                | func main.main()
+004:  7: 1 | d                   | var d *github.com/goplus/gop/cl/internal/overload/bar.Var__1[map[string]any]
+== uses ==
+000:  4: 7 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
+001:  4:11 | Var                 | type github.com/goplus/gop/cl/internal/overload/bar.Var__0[T github.com/goplus/gop/cl/internal/overload/bar.basetype] struct{val T}
+002:  4:15 | int                 | type int
+003:  5: 7 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
+004:  5:11 | Var                 | type github.com/goplus/gop/cl/internal/overload/bar.Var__1[T map[string]any] struct{val T}
+005:  5:15 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
+006:  5:19 | M                   | type github.com/goplus/gop/cl/internal/overload/bar.M = map[string]any
+007:  6: 6 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
+008:  6:10 | Var                 | func github.com/goplus/gop/cl/internal/overload/bar.Gopx_Var_Cast__0[T github.com/goplus/gop/cl/internal/overload/bar.basetype]() *github.com/goplus/gop/cl/internal/overload/bar.Var__0[T]
+009:  6:14 | string              | type string
+010:  7: 6 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
+011:  7:10 | Var                 | func github.com/goplus/gop/cl/internal/overload/bar.Gopx_Var_Cast__1[T map[string]any]() *github.com/goplus/gop/cl/internal/overload/bar.Var__1[T]
+012:  7:14 | bar                 | package bar ("github.com/goplus/gop/cl/internal/overload/bar")
+013:  7:18 | M                   | type github.com/goplus/gop/cl/internal/overload/bar.M = map[string]any`)
+}
+
+func TestMixedOverloadNamed(t *testing.T) {
+	//gox.SetDebug(gox.DbgFlagAll)
+	testGopInfo(t, `
+var a Var[int]
+var b Var[M]
+c := Var(string)
+d := Var(M)
+`, `
+package main
+
+const GopPackage = true
+
+type M = map[string]any
+
+type basetype interface {
+	string | int | bool | float64
+}
+
+type Var__0[T basetype] struct {
+	val T
+}
+
+type Var__1[T map[string]any] struct {
+	val T
+}
+
+func Gopx_Var_Cast__0[T basetype]() *Var__0[T] {
+	return new(Var__0[T])
+}
+
+func Gopx_Var_Cast__1[T map[string]any]() *Var__1[T] {
+	return new(Var__1[T])
+}
+`, `== types ==
+000:  2: 7 | Var                 *ast.Ident                     | type    : main.Var__0[int] | type
+001:  2: 7 | Var[int]            *ast.IndexExpr                 | type    : main.Var__0[int] | type
+002:  2:11 | int                 *ast.Ident                     | type    : int | type
+003:  3: 7 | Var                 *ast.Ident                     | type    : main.Var__1[map[string]interface{}] | type
+004:  3: 7 | Var[M]              *ast.IndexExpr                 | type    : main.Var__1[map[string]interface{}] | type
+005:  3:11 | M                   *ast.Ident                     | type    : map[string]interface{} | type
+006:  4: 6 | Var                 *ast.Ident                     | value   : func[T main.basetype]() *main.Var__0[T] | value
+007:  4: 6 | Var(string)         *ast.CallExpr                  | value   : *main.Var__0[string] | value
+008:  4:10 | string              *ast.Ident                     | type    : string | type
+009:  5: 6 | Var                 *ast.Ident                     | value   : func[T map[string]interface{}]() *main.Var__1[T] | value
+010:  5: 6 | Var(M)              *ast.CallExpr                  | value   : *main.Var__1[map[string]interface{}] | value
+011:  5:10 | M                   *ast.Ident                     | type    : map[string]interface{} | type
+== defs ==
+000:  2: 5 | a                   | var main.a main.Var__0[int]
+001:  3: 5 | b                   | var main.b main.Var__1[map[string]interface{}]
+002:  4: 1 | c                   | var c *main.Var__0[string]
+003:  4: 1 | main                | func main.main()
+004:  5: 1 | d                   | var d *main.Var__1[map[string]interface{}]
+== uses ==
+000:  2: 7 | Var                 | type main.Var__0[T main.basetype] struct{val T}
+001:  2:11 | int                 | type int
+002:  3: 7 | Var                 | type main.Var__1[T map[string]any] struct{val T}
+003:  3:11 | M                   | type main.M = map[string]any
+004:  4: 6 | Var                 | func main.Gopx_Var_Cast__0[T main.basetype]() *main.Var__0[T]
+005:  4:10 | string              | type string
+006:  5: 6 | Var                 | func main.Gopx_Var_Cast__1[T map[string]any]() *main.Var__1[T]
+007:  5:10 | M                   | type main.M = map[string]any`)
+}
+
+func TestMixedRawNamed(t *testing.T) {
+	//gox.SetDebug(gox.DbgFlagAll)
+	testGopInfo(t, `
+var a Var__0[int]
+var b Var__1[M]
+c := Gopx_Var_Cast__0[string]
+d := Gopx_Var_Cast__1[M]
+`, `
+package main
+
+const GopPackage = true
+
+type M = map[string]any
+
+type basetype interface {
+	string | int | bool | float64
+}
+
+type Var__0[T basetype] struct {
+	val T
+}
+
+type Var__1[T map[string]any] struct {
+	val T
+}
+
+func Gopx_Var_Cast__0[T basetype]() *Var__0[T] {
+	return new(Var__0[T])
+}
+
+func Gopx_Var_Cast__1[T map[string]any]() *Var__1[T] {
+	return new(Var__1[T])
+}
+`, `== types ==
+000:  2: 7 | Var__0              *ast.Ident                     | type    : main.Var__0[int] | type
+001:  2: 7 | Var__0[int]         *ast.IndexExpr                 | type    : main.Var__0[int] | type
+002:  2:14 | int                 *ast.Ident                     | type    : int | type
+003:  3: 7 | Var__1              *ast.Ident                     | type    : main.Var__1[map[string]interface{}] | type
+004:  3: 7 | Var__1[M]           *ast.IndexExpr                 | type    : main.Var__1[map[string]interface{}] | type
+005:  3:14 | M                   *ast.Ident                     | type    : map[string]interface{} | type
+006:  4: 6 | Gopx_Var_Cast__0    *ast.Ident                     | value   : func[T main.basetype]() *main.Var__0[T] | value
+007:  4: 6 | Gopx_Var_Cast__0[string] *ast.IndexExpr                 | var     : func() *main.Var__0[string] | variable
+008:  4:23 | string              *ast.Ident                     | type    : string | type
+009:  5: 6 | Gopx_Var_Cast__1    *ast.Ident                     | value   : func[T map[string]interface{}]() *main.Var__1[T] | value
+010:  5: 6 | Gopx_Var_Cast__1[M] *ast.IndexExpr                 | var     : func() *main.Var__1[map[string]interface{}] | variable
+011:  5:23 | M                   *ast.Ident                     | type    : map[string]interface{} | type
+== defs ==
+000:  2: 5 | a                   | var main.a main.Var__0[int]
+001:  3: 5 | b                   | var main.b main.Var__1[map[string]interface{}]
+002:  4: 1 | c                   | var c func() *main.Var__0[string]
+003:  4: 1 | main                | func main.main()
+004:  5: 1 | d                   | var d func() *main.Var__1[map[string]interface{}]
+== uses ==
+000:  2: 7 | Var__0              | type main.Var__0[T main.basetype] struct{val T}
+001:  2:14 | int                 | type int
+002:  3: 7 | Var__1              | type main.Var__1[T map[string]any] struct{val T}
+003:  3:14 | M                   | type main.M = map[string]any
+004:  4: 6 | Gopx_Var_Cast__0    | func main.Gopx_Var_Cast__0[T main.basetype]() *main.Var__0[T]
+005:  4:23 | string              | type string
+006:  5: 6 | Gopx_Var_Cast__1    | func main.Gopx_Var_Cast__1[T map[string]any]() *main.Var__1[T]
+007:  5:23 | M                   | type main.M = map[string]any`)
+}