Skip to content

Commit

Permalink
export c struct
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Jul 26, 2022
1 parent bef4f08 commit 057c2f6
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 8 deletions.
19 changes: 19 additions & 0 deletions builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,25 @@ func getConf() *Config {
return &Config{Fset: fset, Importer: imp}
}

func TestExportFields(t *testing.T) {
pkg := NewPackage("", "foo", nil)
fields := []*types.Var{
types.NewField(token.NoPos, pkg.Types, "Y", types.Typ[types.Int], false),
types.NewField(token.NoPos, pkg.Types, "X__u", types.Typ[types.String], false),
}
tyT := pkg.NewType("T").InitType(pkg, types.NewStruct(fields, nil))
pkg.ExportFields(tyT)
if name := pkg.cb.getFieldName(tyT, "y"); name != "Y" {
t.Fatal("getFieldName y:", name)
}
if name := pkg.cb.getFieldName(tyT, "__u"); name != "X__u" {
t.Fatal("getFieldName __u:", name)
}
if CPubName("123") != "123" {
t.Fatal("CPubName(123) failed")
}
}

func TestGetBuiltinTI(t *testing.T) {
pkg := NewPackage("", "foo", nil)
cb := &pkg.cb
Expand Down
27 changes: 27 additions & 0 deletions c.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,28 @@ type VFields interface { // virtual fields
FieldRef(cb *CodeBuilder, t *types.Named, name string, src ast.Node) MemberKind
}

type none = struct{}

type vFieldsMgr struct {
vfts map[*types.Named]VFields
pubs map[*types.Named]none
}

func CPubName(name string) string {
if r := name[0]; 'a' <= r && r <= 'z' {
r -= 'a' - 'A'
return string(r) + name[1:]
} else if r == '_' {
return "X" + name
}
return name
}

func (p *CodeBuilder) getFieldName(t *types.Named, name string) string {
if _, ok := p.pubs[t]; ok {
return CPubName(name)
}
return name
}

func (p *CodeBuilder) refVField(t *types.Named, name string, src ast.Node) MemberKind {
Expand All @@ -47,6 +67,13 @@ func (p *CodeBuilder) findVField(t *types.Named, name string, arg *Element, src
return MemberInvalid
}

func (p *Package) ExportFields(t *types.Named) {
if p.cb.pubs == nil {
p.cb.pubs = make(map[*types.Named]none)
}
p.cb.pubs[t] = none{}
}

func (p *Package) SetVFields(t *types.Named, vft VFields) {
if p.cb.vfts == nil {
p.cb.vfts = make(map[*types.Named]VFields)
Expand Down
4 changes: 4 additions & 0 deletions codebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,7 @@ retry:
u := p.getUnderlying(t) // may cause to loadNamed (delay-loaded)
struc, fstruc := u.(*types.Struct)
if fstruc {
name = p.getFieldName(t, name)
if kind := p.normalField(struc, name, arg, srcExpr); kind != MemberInvalid {
return kind
}
Expand All @@ -1564,6 +1565,9 @@ retry:
if kind := p.method(o, name, aliasName, flag, arg, srcExpr); kind != MemberInvalid {
return kind
}
if _, ok := typ.(*types.Struct); ok {
name = p.getFieldName(o, name)
}
goto retry
case *types.Struct:
if kind := p.field(o, name, aliasName, flag, arg, srcExpr); kind != MemberInvalid {
Expand Down
10 changes: 2 additions & 8 deletions cpackages/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,15 @@ func (p *PkgRef) Pkg() *gox.PkgRef {
func (p *PkgRef) Lookup(name string) types.Object {
if goName, ok := p.public[name]; ok {
if goName == "" {
goName = PubName(name)
goName = gox.CPubName(name)
}
return p.pkg.TryRef(goName)
}
return nil
}

func PubName(name string) string {
if r := name[0]; 'a' <= r && r <= 'z' {
r -= 'a' - 'A'
return string(r) + name[1:]
} else if r == '_' {
return "X" + name
}
return name
return gox.CPubName(name)
}

// ----------------------------------------------------------------------------
Expand Down

0 comments on commit 057c2f6

Please sign in to comment.