Skip to content

Commit e6a27d6

Browse files
committed
hax: add partial struct support
1 parent 58f17aa commit e6a27d6

File tree

15 files changed

+2310
-3080
lines changed

15 files changed

+2310
-3080
lines changed

generate/codegen/gen_function.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ type Function struct {
3030

3131
// GoArgs return go function args
3232
func (f *Function) GoArgs(currentModule *modules.Module) string {
33-
log.Println("rendering function", f.Name)
33+
// log.Println("rendering function", f.Name)
3434
var args []string
3535
for _, p := range f.Parameters {
3636
log.Println("rendering function", f.Name, p.Name, p.Type)
37-
log.Printf("type: %T", p.Type)
37+
log.Printf("rendering function ptype: %T", p.Type)
3838
if pt, ok := p.Type.(*typing.PointerType); ok {
3939
log.Printf("ptr type: %T", pt.Type)
4040
}

generate/codegen/gen_struct.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package codegen
2+
3+
import (
4+
"github.com/progrium/macdriver/generate/typing"
5+
)
6+
7+
// Struct is code generator for objective-c struct
8+
type Struct struct {
9+
Type *typing.StructType
10+
Name string // the first part of objc function name
11+
GoName string
12+
Deprecated bool // if has been deprecated
13+
Suffix bool // GoName conflicts so add suffix to this function
14+
Description string
15+
DocURL string
16+
17+
goFuncName string
18+
identifier string
19+
}

generate/codegen/modulewriter.go

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ type ModuleWriter struct {
2424
EnumAliases []*AliasInfo
2525
FuncAliases []*AliasInfo
2626
Functions []*Function
27+
Structs []*Struct
2728
}
2829

2930
func (m *ModuleWriter) WriteCode() {
3031
m.WriteDocFile()
3132
m.WriteEnumAliases()
3233
m.WriteTypeAliases()
34+
m.WriteStructs()
3335
m.WriteFunctions()
3436
if m.Module.Package == "coreimage" {
3537
// filter protocols maybe arent "real" protocols?
@@ -81,6 +83,53 @@ func (m *ModuleWriter) WriteTypeAliases() {
8183
}
8284
}
8385

86+
func (m *ModuleWriter) WriteStructs() {
87+
if len(m.Structs) == 0 {
88+
return
89+
}
90+
91+
filePath := filepath.Join(m.PlatformDir, m.Module.Package, "structs.gen.go")
92+
os.MkdirAll(filepath.Dir(filePath), 0755)
93+
f, err := os.Create(filePath)
94+
if err != nil {
95+
panic(err)
96+
}
97+
defer f.Close()
98+
99+
cw := &CodeWriter{Writer: f, IndentStr: "\t"}
100+
cw.WriteLine(AutoGeneratedMark)
101+
cw.WriteLine("package " + m.Module.Package)
102+
103+
cw.WriteLine("import (")
104+
105+
// imports
106+
var imports = set.New("unsafe")
107+
for _, fa := range m.FuncAliases {
108+
imports.AddSet(fa.GoImports())
109+
}
110+
cw.Indent()
111+
imports.ForEach(func(value string) {
112+
if value != "github.com/progrium/macdriver/macos/objc" {
113+
cw.WriteLine("\"" + value + "\"")
114+
}
115+
})
116+
cw.UnIndent()
117+
cw.WriteLine(")")
118+
119+
for _, s := range m.Structs {
120+
if s.DocURL != "" {
121+
cw.WriteLine(fmt.Sprintf("// %s [Full Topic]", s.Description))
122+
cw.WriteLine(fmt.Sprintf("//\n// [Full Topic]: %s", s.DocURL))
123+
}
124+
125+
// if Ref type, allias to unsafe.Pointer
126+
if strings.HasSuffix(s.Name, "Ref") {
127+
cw.WriteLineF("type %s = unsafe.Pointer", s.GoName)
128+
continue
129+
}
130+
}
131+
}
132+
84133
func (m *ModuleWriter) WriteFunctions() {
85134
if len(m.Functions) == 0 {
86135
return
@@ -119,7 +168,7 @@ func (m *ModuleWriter) WriteFunctions() {
119168
cw.WriteLine(fmt.Sprintf("// %s [Full Topic]", fa.Description))
120169
cw.WriteLine(fmt.Sprintf("//\n// [Full Topic]: %s", fa.DocURL))
121170
}
122-
cw.WriteLineF("// func %s(%s) %s {}", fa.GoName, fa.GoArgs(&m.Module), fa.GoReturn(&m.Module))
171+
cw.WriteLineF("func %s(%s) %s {}", fa.Type.GoName(&m.Module, true), fa.GoArgs(&m.Module), fa.GoReturn(&m.Module))
123172
}
124173
}
125174

generate/declparse/declparse_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,4 +1107,36 @@ var tests = []struct {
11071107
},
11081108
},
11091109
},
1110+
{
1111+
ParseOnly: true,
1112+
s: "CFURLRef CFURLCreateFromFSRef(CFAllocatorRef allocator, const struct FSRef *fsRef);",
1113+
Hint: HintFunction,
1114+
n: &Statement{
1115+
Function: &FunctionDecl{
1116+
ReturnType: TypeInfo{
1117+
Name: "CFURLRef",
1118+
},
1119+
Name: "CFURLCreateFromFSRef",
1120+
Args: FuncArgs{
1121+
ArgInfo{
1122+
Name: "allocator",
1123+
Type: TypeInfo{
1124+
Name: "CFAllocatorRef",
1125+
},
1126+
},
1127+
ArgInfo{
1128+
Name: "fsRef",
1129+
Type: TypeInfo{
1130+
Name: "FSRef",
1131+
IsPtr: true,
1132+
Annots: map[TypeAnnotation]bool{
1133+
TypeAnnotConst: true,
1134+
TypeAnnotStruct: true,
1135+
},
1136+
},
1137+
},
1138+
},
1139+
},
1140+
},
1141+
},
11101142
}

generate/function.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ func (db *Generator) ToFunction(fw string, sym Symbol) *codegen.Function {
264264
for _, p := range fntyp.Parameters {
265265
if p.Type == nil {
266266
fmt.Printf("skipping %s: %s because of nil type\n", sym.Name, p.Name)
267-
continue
267+
return nil
268268
}
269269
fn.Parameters = append(fn.Parameters, &codegen.Param{
270270
Name: p.Name,

generate/generator.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,17 @@ func (db *Generator) Generate(platform string, version int, rootDir string, fram
112112
continue
113113
}
114114
mw.Functions = append(mw.Functions, fn)
115+
case "Struct":
116+
if s.Name != "CGImageRef" {
117+
continue
118+
}
119+
fn := db.ToStruct(framework, s)
120+
if fn == nil {
121+
continue
122+
}
123+
mw.Structs = append(mw.Structs, fn)
124+
default:
125+
log.Printf("skipping '%s', unhandled kind: %s", s.Name, s.Kind)
115126
}
116127
}
117128
mw.WriteCode()

generate/struct.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package generate
2+
3+
import (
4+
"log"
5+
6+
"github.com/progrium/macdriver/generate/codegen"
7+
"github.com/progrium/macdriver/generate/typing"
8+
)
9+
10+
func (db *Generator) ToStruct(fw string, sym Symbol) *codegen.Struct {
11+
// these structs have known declparse failures
12+
knownIssues := map[string]bool{}
13+
if knownIssues[sym.Name] {
14+
_, err := sym.Parse()
15+
log.Printf("skipping struct %s %s because of known issue: decl='%s' err='%v'\n", fw, sym.Name, sym.Declaration, err)
16+
return nil
17+
}
18+
typ := db.TypeFromSymbol(sym)
19+
styp, ok := typ.(*typing.StructType)
20+
if !ok {
21+
return nil
22+
}
23+
s := &codegen.Struct{
24+
Name: sym.Name,
25+
GoName: sym.Name,
26+
Description: sym.Description,
27+
DocURL: sym.DocURL(),
28+
Type: styp,
29+
}
30+
31+
return s
32+
33+
}
34+
35+
/*
36+
*/

generate/types.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package generate
22

33
import (
44
"fmt"
5+
"log"
56
"strings"
67

78
"github.com/progrium/macdriver/generate/declparse"
@@ -94,6 +95,9 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
9495
Module: modules.Get(module),
9596
}
9697
case "Function":
98+
if sym.Name != "CGDisplayCreateImage" {
99+
return nil
100+
}
97101
typ, err := sym.Parse()
98102
if err != nil {
99103
fmt.Printf("TypeFromSymbol: failed to parse %s: %s\n", sym.Declaration, err)
@@ -116,7 +120,6 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
116120
})
117121
}
118122
ft.ReturnType = db.ParseType(fn.ReturnType)
119-
// TODO: parse function params and return type from declaration
120123
return ft
121124
default:
122125
fmt.Printf("TypeFromSymbol: kind=%s name=%s path=%s\n", sym.Kind, sym.Name, sym.Path)
@@ -136,6 +139,18 @@ func (db *Generator) ParseType(ti declparse.TypeInfo) (typ typing.Type) {
136139
}
137140
}
138141
}()
142+
if ti.Name == "CFURLRef" {
143+
log.Printf("ParseType: %s\n", ti.Name)
144+
log.Printf("info: %v\n", ti)
145+
log.Printf("info fn: %v\n", ti.Func)
146+
defer func() {
147+
log.Printf("info typ: %T %+v\n", typ, typ)
148+
if pt, ok := typ.(*typing.PointerType); ok {
149+
log.Printf("info typ: %T %+v\n", pt.Type, pt.Type)
150+
}
151+
152+
}()
153+
}
139154
if ti.Func != nil {
140155
var blockParams []typing.BlockParam
141156
for _, arg := range ti.Func.Args {
@@ -215,17 +230,23 @@ func (db *Generator) ParseType(ti declparse.TypeInfo) (typ typing.Type) {
215230
default:
216231
var ok bool
217232
typ, ok = typing.GetPrimitiveType(ti.Name)
233+
log.Println("primitive", ti.Name, ok)
218234
if !ok {
219235
typ, ok = typing.GetDispatchType(ti.Name)
220236
}
237+
log.Println("dispatch", ti.Name, ok)
221238
if !ok {
222239
typ, ok = typing.GetKernelType(ti.Name)
223240
}
241+
log.Println("kernel", ti.Name, ok)
224242
if !ok {
225243
typ = db.TypeFromSymbolName(ti.Name)
244+
log.Println("symbol", ti.Name, typ, ok)
226245
switch typ.(type) {
227246
case *typing.ClassType:
228247
ref = true
248+
case *typing.StructType:
249+
ref = true
229250
case *typing.ProtocolType:
230251
panic("standalone proto type")
231252
}
@@ -236,6 +257,9 @@ func (db *Generator) ParseType(ti declparse.TypeInfo) (typ typing.Type) {
236257
if _, ok := typ.(*typing.VoidType); ok {
237258
typ = &typing.VoidPointerType{}
238259
} else {
260+
if typ == nil {
261+
panic("nil type")
262+
}
239263
typ = &typing.PointerType{
240264
Type: typ,
241265
}

0 commit comments

Comments
 (0)