Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cl: typesRecorder.instantiate for gox TyOverloadNamed #1672

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cl/func_type_and_var.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
20 changes: 20 additions & 0 deletions cl/recorder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)}
}
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
170 changes: 170 additions & 0 deletions x/typesutil/info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
}