Do not memoize type parser as it causes bugs with typedefs,

'instancetype' etc. Clean up typedefs and type parameters as
soon as Types are created.
This commit is contained in:
Greg 2019-04-30 06:59:05 -04:00
parent d78e055008
commit 0e89d2c29a
6 changed files with 50 additions and 26 deletions

View File

@ -10,7 +10,7 @@ struct stru {int a,b;};
int (*f)(); int (*f)();
} }
- (ClassOne*) init; - (instancetype) init;
- (int) geti1; - (int) geti1;
- (int *) getp1; - (int *) getp1;
- (int (*)()) getf1; - (int (*)()) getf1;
@ -24,5 +24,5 @@ struct stru {int a,b;};
@interface ClassTwo : ClassOne @interface ClassTwo : ClassOne
{ } { }
- (ClassTwo*) init; - (instancetype) init;
@end @end

View File

@ -2,7 +2,7 @@
@implementation ClassOne @implementation ClassOne
- (ClassOne*) init - (instancetype) init
{ {
ClassOne *ret; ClassOne *ret;
ret = [ClassOne alloc]; ret = [ClassOne alloc];
@ -65,7 +65,7 @@
@end @end
@implementation ClassTwo @implementation ClassTwo
- (ClassTwo*) init - (instancetype) init
{ {
return [super init]; return [super init];
} }

View File

@ -32,7 +32,8 @@ var TypeParameters map[string]map[string]string
var typedefs map[string]*Type var typedefs map[string]*Type
func (t *Type) Typedef() *Type { func (t *Type) Typedef() *Type {
return typedefs[t.BaseType().CType()] //return typedefs[t.BaseType().CType()]
return typedefs[t.CType()]
} }
func init() { func init() {
@ -59,46 +60,62 @@ func SetTypeParam(c, n, t string) {
} }
func AddTypedef(n,t string) { func AddTypedef(n,t string) {
//fmt.Printf("AddTypedef(): %s -> %s\n",n,t)
typedefs[n] = NewTypeFromString(t,"") typedefs[n] = NewTypeFromString(t,"")
} }
type Type struct { type Type struct {
Node *Node Node *Node
Class string Class string
ctype string //ctype string
Variadic bool Variadic bool
} }
func clean(n *Node,c string) (*Node,bool) {
ret := NewNode(n.Kind,n.Content)
ret.Children = n.Children
//fmt.Printf("clean(%s,%s)\n",n.Ctype(),c)
recur := false
if TypeParameters[c] != nil {
for k,v := range TypeParameters[c] {
recur = ret.renameTypedefs(k,v)
}
}
recur = recur || ret.renameTypedefs("instancename",c)
recur = recur || ret.renameTypedefs("instancetype",c + "*")
if recur {
clean(n, c)
return ret,true
}
return n,false
}
func NewType(n *Node, c string) *Type { func NewType(n *Node, c string) *Type {
n2,_ := clean(n, c)
return &Type{ return &Type{
Node: n, Node: n2,
Class: c, Class: c,
ctype: "", //ctype: "",
} }
} }
func NewTypeFromString(t,c string) *Type { func NewTypeFromString(t,c string) *Type {
//fmt.Printf("t/c: %s/%s\n",t,c)
n,err := Parse(t) n,err := Parse(t)
//fmt.Printf("%p %s",n,n.String())
if n.IsId() { if n.IsId() {
//if n.CtypeSimplified() == "id" {
n,err = Parse("NSObject*") n,err = Parse("NSObject*")
} }
if err != nil { if err != nil {
return &Type{} return &Type{}
} }
if TypeParameters[c] != nil { if n2,ok := clean(n, c); ok {
recur := false return NewTypeFromString(n2.Ctype(),c)
for k,v := range TypeParameters[c] {
recur = n.renameTypedefs(k,v)
}
if recur {
return NewTypeFromString(n.Ctype(),c)
}
} }
return &Type{ return &Type{
Node: n, Node: n,
Class: c, Class: c,
ctype: "", //ctype: "",
} }
} }
@ -166,9 +183,9 @@ func (t *Type) CTypeAttrib() string {
func (t *Type) _CType(attrib bool) string { func (t *Type) _CType(attrib bool) string {
//if !attrib && c.ctype != "" ... FIXME? //if !attrib && c.ctype != "" ... FIXME?
if t.ctype != "" { // cache //if t.ctype != "" { // cache
return t.ctype // return t.ctype
} //}
var ct string var ct string
if attrib { if attrib {
ignore := map[string]bool { "GenericList": true } ignore := map[string]bool { "GenericList": true }
@ -176,19 +193,22 @@ func (t *Type) _CType(attrib bool) string {
} else { } else {
ct = t.Node.CtypeSimplified() ct = t.Node.CtypeSimplified()
} }
/*
ct = strings.ReplaceAll(ct,"instancename",t.Class) ct = strings.ReplaceAll(ct,"instancename",t.Class)
ct = strings.ReplaceAll(ct,"instancetype",t.Class + " *") ct = strings.ReplaceAll(ct,"instancetype",t.Class + " *")
*/
if len(ct) > 1 && ct[:2] == "id" { if len(ct) > 1 && ct[:2] == "id" {
ct = "NSObject*" + ct[2:] ct = "NSObject*" + ct[2:]
} }
/*
if len(ct) > 11 { if len(ct) > 11 {
if ct[:12] == "instancename" { ct = t.Class + ct[12:] } if ct[:12] == "instancename" { ct = t.Class + ct[12:] }
if ct[:12] == "instancetype" { ct = t.Class + ct[12:] + " *" } if ct[:12] == "instancetype" { ct = t.Class + ct[12:] + " *" }
} }*/
if attrib { if attrib {
t._CType(false) t._CType(false)
} else { //} else {
t.ctype = ct //t.ctype = ct
} }
return ct return ct
} }

View File

@ -95,6 +95,7 @@ func init() {
} }
return s2,n2 return s2,n2
} }
TypeName = _TypeName
} }
func _TypeName(s string, n *Node) (string, *Node) { func _TypeName(s string, n *Node) (string, *Node) {

View File

@ -28,6 +28,7 @@ func (n *Node) HasFunc() bool {
func Parse(s string) (*Node, error) { func Parse(s string) (*Node, error) {
s2, n := TypeName(s,NewNode("AST")) s2, n := TypeName(s,NewNode("AST"))
//fmt.Printf("%p Parsed %s\n",n,s)
if s2 != "" { if s2 != "" {
return n,fmt.Errorf("Parse failed or incomplete. Remainder: %s",s2) return n,fmt.Errorf("Parse failed or incomplete. Remainder: %s",s2)
} }

View File

@ -229,13 +229,14 @@ func (w *Wrapper) add(name string, ns []ast.Node) {
i.Properties[p.Name] = p i.Properties[p.Name] = p
//} //}
case *ast.ObjCMethodDecl: case *ast.ObjCMethodDecl:
//fmt.Printf("ObjCMethodDecl: %s\n",x.Name) //fmt.Printf("ObjCMethodDecl: %s (%s) %s\n",x.Type,name,x.Name)
m := Method{ m := Method{
Name: x.Name, Name: x.Name,
Type: types.NewTypeFromString(x.Type,name), Type: types.NewTypeFromString(x.Type,name),
Class: name, Class: name,
ClassMethod: x.ClassMethod, ClassMethod: x.ClassMethod,
} }
//fmt.Println(m.Type.Node.String())
m.Parameters, avail = w.GetParms(x,name) m.Parameters, avail = w.GetParms(x,name)
if avail { if avail {
i.Methods[m.Name] = m i.Methods[m.Name] = m
@ -448,8 +449,9 @@ New%s() {
grtype = "" grtype = ""
} }
w.goCode.WriteString(fmt.Sprintf(` w.goCode.WriteString(fmt.Sprintf(`
//%s
func %s(%s) %s { func %s(%s) %s {
`,gname,gplist,grtype)) `,m.Type.CType(),gname,gplist,grtype))
lparm := len(tps)-1 lparm := len(tps)-1
if len(tps) > 0 && tps[lparm].Variadic { if len(tps) > 0 && tps[lparm].Variadic {
vn := ns[lparm] vn := ns[lparm]