Skip to content

Commit 04985cb

Browse files
authored
Merge pull request #563 from xushiwei/q
ClassDefs: support embed
2 parents d52f340 + d7a6163 commit 04985cb

File tree

6 files changed

+209
-96
lines changed

6 files changed

+209
-96
lines changed

ast.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,22 @@ func toVariadic(fld *ast.Field) {
139139

140140
// -----------------------------------------------------------------------------
141141

142+
// embedName returns the name of the embedded type.
143+
func embedName(typ types.Type) string {
144+
if t, ok := typ.(*types.Pointer); ok {
145+
typ = t.Elem()
146+
}
147+
switch t := typ.(type) {
148+
case *types.Basic:
149+
return t.Name()
150+
case *types.Named:
151+
return t.Obj().Name()
152+
case *typesalias.Alias:
153+
return t.Obj().Name()
154+
}
155+
return ""
156+
}
157+
142158
func toType(pkg *Package, typ types.Type) ast.Expr {
143159
retry:
144160
switch t := typ.(type) {

ast_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright 2021 The XGo Authors (xgo.dev)
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package gogen
15+
16+
import (
17+
"go/ast"
18+
"go/token"
19+
"go/types"
20+
"testing"
21+
22+
"github.com/goplus/gogen/internal/typesalias"
23+
)
24+
25+
func TestToVariadic(t *testing.T) {
26+
defer func() {
27+
if e := recover(); e == nil {
28+
t.Fatal("TestToVariadic: no error?")
29+
}
30+
}()
31+
toVariadic(&ast.Field{Type: &ast.Ident{Name: "int"}})
32+
}
33+
34+
func TestToType(t *testing.T) {
35+
pkg := NewPackage("", "foo", gblConf)
36+
toType(pkg, &unboundType{tBound: tyInt})
37+
defer func() {
38+
if e := recover(); e == nil {
39+
t.Fatal("TestToType: no error?")
40+
}
41+
}()
42+
toType(pkg, &unboundType{})
43+
}
44+
45+
func TestToTypeAlias(t *testing.T) {
46+
pkg := NewPackage("", "foo", gblConf)
47+
alias := typesalias.NewAlias(types.NewTypeName(token.NoPos, nil, "Int", nil), types.Typ[types.Int])
48+
expr := toType(pkg, alias)
49+
if ident, ok := expr.(*ast.Ident); !ok || ident.Name != "Int" {
50+
t.Fatalf("bad alias %#v", expr)
51+
}
52+
}
53+
54+
func Test_embedName(t *testing.T) {
55+
tests := []struct {
56+
name string // description of this test case
57+
// Named input parameters for target function.
58+
typ types.Type
59+
want string
60+
}{
61+
{
62+
name: "basic type",
63+
typ: types.Typ[types.Int],
64+
want: "int",
65+
},
66+
{
67+
name: "named type",
68+
typ: types.NewNamed(types.NewTypeName(0, nil, "MyInt", nil), types.Typ[types.Int], nil),
69+
want: "MyInt",
70+
},
71+
{
72+
name: "pointer to named type",
73+
typ: types.NewPointer(types.NewNamed(types.NewTypeName(0, nil, "MyInt", nil), types.Typ[types.Int], nil)),
74+
want: "MyInt",
75+
},
76+
{
77+
name: "alias type",
78+
typ: typesalias.NewAlias(types.NewTypeName(0, nil, "MyInt", nil), types.Typ[types.Int]),
79+
want: "MyInt",
80+
},
81+
}
82+
for _, tt := range tests {
83+
t.Run(tt.name, func(t *testing.T) {
84+
got := embedName(tt.typ)
85+
if got != tt.want {
86+
t.Errorf("embedName() = %v, want %v", got, tt.want)
87+
}
88+
})
89+
}
90+
}

builtin_test.go

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,13 @@ import (
2121
"go/types"
2222
"log"
2323
"math/big"
24-
"runtime"
25-
"strconv"
2624
"strings"
2725
"sync"
2826
"testing"
2927
"unsafe"
3028

3129
"github.com/goplus/gogen/internal"
3230
"github.com/goplus/gogen/internal/go/format"
33-
"github.com/goplus/gogen/internal/typesalias"
3431
"github.com/goplus/gogen/packages"
3532
)
3633

@@ -678,61 +675,6 @@ func TestToFields(t *testing.T) {
678675
}
679676
}
680677

681-
func TestToVariadic(t *testing.T) {
682-
defer func() {
683-
if e := recover(); e == nil {
684-
t.Fatal("TestToVariadic: no error?")
685-
}
686-
}()
687-
toVariadic(&ast.Field{Type: &ast.Ident{Name: "int"}})
688-
}
689-
690-
func TestToType(t *testing.T) {
691-
pkg := NewPackage("", "foo", gblConf)
692-
toType(pkg, &unboundType{tBound: tyInt})
693-
defer func() {
694-
if e := recover(); e == nil {
695-
t.Fatal("TestToType: no error?")
696-
}
697-
}()
698-
toType(pkg, &unboundType{})
699-
}
700-
701-
func isLeastGo122() bool {
702-
ver, err := strconv.ParseInt(runtime.Version()[4:6], 10, 0)
703-
return err == nil && ver >= 22
704-
}
705-
706-
func TestToTypeAlias(t *testing.T) {
707-
pkg := NewPackage("", "foo", gblConf)
708-
alias := typesalias.NewAlias(types.NewTypeName(token.NoPos, nil, "Int", nil), types.Typ[types.Int])
709-
if isLeastGo122() {
710-
expr := toType(pkg, alias)
711-
if ident, ok := expr.(*ast.Ident); !ok || ident.Name != "Int" {
712-
t.Fatalf("bad alias %#v", expr)
713-
}
714-
} else {
715-
defer func() {
716-
if e := recover(); e == nil {
717-
t.Fatal("TestToTypeAlias: no error?")
718-
}
719-
}()
720-
toType(pkg, alias)
721-
}
722-
}
723-
724-
/*
725-
func typString(pkg *Package, t types.Type) string {
726-
v := toType(pkg, t)
727-
var b bytes.Buffer
728-
err := format.Node(&b, pkg.Fset, v)
729-
if err != nil {
730-
panic(err)
731-
}
732-
return b.String()
733-
}
734-
*/
735-
736678
func TestMethodAutoProperty(t *testing.T) {
737679
pkg := types.NewPackage("", "")
738680
typs := []types.Type{

internal/typesalias/alias_go121.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import "go/types"
88
const Support = false
99

1010
type Alias struct {
11+
obj *types.TypeName
1112
}
1213

1314
const unsupported = "typesAlias are unsupported at this go version"
@@ -21,11 +22,11 @@ func (t *Alias) String() string {
2122
}
2223

2324
func (t *Alias) Obj() *types.TypeName {
24-
panic(unsupported)
25+
return t.obj
2526
}
2627

2728
func NewAlias(obj *types.TypeName, rhs types.Type) *Alias {
28-
return &Alias{}
29+
return &Alias{obj}
2930
}
3031

3132
func Unalias(t types.Type) types.Type {

package_test.go

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,18 +1438,29 @@ const (
14381438
`)
14391439
}
14401440

1441+
type fldAdder struct {
1442+
Fields []*types.Var
1443+
pkgTypes *types.Package
1444+
}
1445+
1446+
func (p *fldAdder) addFld(idx int, name string, typ types.Type, embed bool) {
1447+
fld := types.NewField(token.NoPos, p.pkgTypes, name, typ, embed)
1448+
p.Fields = append(p.Fields, fld)
1449+
}
1450+
14411451
func TestClassDefsInitWithoutType(t *testing.T) {
14421452
pkg := newMainPackage()
1453+
fa := fldAdder{pkgTypes: pkg.Types}
14431454
typ := pkg.NewTypeDefs().NewType("Rect")
14441455
recv := types.NewParam(token.NoPos, pkg.Types, "this", types.NewPointer(typ.Type()))
1445-
defs := pkg.ClassDefsStart(recv, nil, nil)
1456+
defs := pkg.ClassDefsStart(recv, fa.addFld)
14461457
defs.NewAndInit(func(cb *gogen.CodeBuilder) int {
14471458
cb.Val(1).Val(2).BinaryOp(token.ADD).
14481459
Val("1").Val("2").BinaryOp(token.ADD)
14491460
return 2
1450-
}, "", token.NoPos, nil, "n", "s")
1461+
}, token.NoPos, nil, "n", "s")
14511462
defs.End()
1452-
typ.InitType(pkg, types.NewStruct(defs.Fields, defs.Tags))
1463+
typ.InitType(pkg, types.NewStruct(fa.Fields, nil))
14531464
domTest(t, pkg, `package main
14541465
14551466
type Rect struct {
@@ -1466,16 +1477,17 @@ func (this *Rect) XGo_Init() *Rect {
14661477

14671478
func TestClassDefsInitWithType(t *testing.T) {
14681479
pkg := newMainPackage()
1480+
fa := fldAdder{pkgTypes: pkg.Types}
14691481
typ := pkg.NewTypeDefs().NewType("Rect")
14701482
recv := types.NewParam(token.NoPos, pkg.Types, "this", types.NewPointer(typ.Type()))
1471-
defs := pkg.ClassDefsStart(recv, nil, nil)
1483+
defs := pkg.ClassDefsStart(recv, fa.addFld)
14721484
defs.NewAndInit(func(cb *gogen.CodeBuilder) int {
14731485
cb.Val(1).Val(2).BinaryOp(token.ADD).
14741486
Val(5)
14751487
return 2
1476-
}, "", token.NoPos, types.Typ[types.Int], "a", "b")
1488+
}, token.NoPos, types.Typ[types.Int], "a", "b")
14771489
defs.End()
1478-
typ.InitType(pkg, types.NewStruct(defs.Fields, defs.Tags))
1490+
typ.InitType(pkg, types.NewStruct(fa.Fields, nil))
14791491
domTest(t, pkg, `package main
14801492
14811493
type Rect struct {
@@ -1497,23 +1509,25 @@ func TestClassDefsInitPanic(t *testing.T) {
14971509
}
14981510
}()
14991511
pkg := newMainPackage()
1512+
fa := fldAdder{pkgTypes: pkg.Types}
15001513
typ := pkg.NewTypeDefs().NewType("Rect")
15011514
recv := types.NewParam(token.NoPos, pkg.Types, "this", types.NewPointer(typ.Type()))
1502-
defs := pkg.ClassDefsStart(recv, nil, nil)
1515+
defs := pkg.ClassDefsStart(recv, fa.addFld)
15031516
defs.NewAndInit(func(cb *gogen.CodeBuilder) int {
15041517
panic("fail")
1505-
}, "", token.NoPos, types.Typ[types.Int], "a", "b")
1518+
}, token.NoPos, types.Typ[types.Int], "a", "b")
15061519
defs.End()
1507-
typ.InitType(pkg, types.NewStruct(defs.Fields, defs.Tags))
1520+
typ.InitType(pkg, types.NewStruct(fa.Fields, nil))
15081521
}
15091522

15101523
func TestClassDefsNoInit(t *testing.T) {
15111524
pkg := newMainPackage()
1525+
fa := fldAdder{pkgTypes: pkg.Types}
15121526
typ := pkg.NewTypeDefs().NewType("Rect")
1513-
defs := pkg.ClassDefsStart(nil, nil, nil)
1514-
defs.NewAndInit(nil, "", token.NoPos, types.Typ[types.Int], "a", "b")
1527+
defs := pkg.ClassDefsStart(nil, fa.addFld)
1528+
defs.NewAndInit(nil, token.NoPos, types.Typ[types.Int], "a", "b")
15151529
defs.End()
1516-
typ.InitType(pkg, types.NewStruct(defs.Fields, defs.Tags))
1530+
typ.InitType(pkg, types.NewStruct(fa.Fields, nil))
15171531
domTest(t, pkg, `package main
15181532
15191533
type Rect struct {
@@ -1523,6 +1537,47 @@ type Rect struct {
15231537
`)
15241538
}
15251539

1540+
func TestClassDefsEmbedNoInit(t *testing.T) {
1541+
pkg := newMainPackage()
1542+
fa := fldAdder{pkgTypes: pkg.Types}
1543+
typ := pkg.NewTypeDefs().NewType("Rect")
1544+
defs := pkg.ClassDefsStart(nil, fa.addFld)
1545+
defs.NewAndInit(nil, token.NoPos, types.Typ[types.Int])
1546+
defs.End()
1547+
typ.InitType(pkg, types.NewStruct(fa.Fields, nil))
1548+
domTest(t, pkg, `package main
1549+
1550+
type Rect struct {
1551+
int
1552+
}
1553+
`)
1554+
}
1555+
1556+
func TestClassDefsEmbedInit(t *testing.T) {
1557+
pkg := newMainPackage()
1558+
fa := fldAdder{pkgTypes: pkg.Types}
1559+
typ := pkg.NewTypeDefs().NewType("Rect")
1560+
recv := types.NewParam(token.NoPos, pkg.Types, "this", types.NewPointer(typ.Type()))
1561+
defs := pkg.ClassDefsStart(recv, fa.addFld)
1562+
defs.NewAndInit(func(cb *gogen.CodeBuilder) int {
1563+
cb.Val(5)
1564+
return 1
1565+
}, token.NoPos, types.Typ[types.Int])
1566+
defs.End()
1567+
typ.InitType(pkg, types.NewStruct(fa.Fields, nil))
1568+
domTest(t, pkg, `package main
1569+
1570+
type Rect struct {
1571+
int
1572+
}
1573+
1574+
func (this *Rect) XGo_Init() *Rect {
1575+
this.int = 5
1576+
return this
1577+
}
1578+
`)
1579+
}
1580+
15261581
func TestDeleteVarDecl(t *testing.T) {
15271582
pkg := newMainPackage()
15281583
pkg.SetRedeclarable(true)

0 commit comments

Comments
 (0)