Skip to content

Commit ef1b73e

Browse files
committed
generate: iterate on supporting functions
1 parent 01aba91 commit ef1b73e

File tree

6 files changed

+107
-85
lines changed

6 files changed

+107
-85
lines changed

generate/codegen/gen_function.go

Lines changed: 35 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -27,87 +27,68 @@ type Function struct {
2727
identifier string
2828
}
2929

30-
func (f *Function) Init() {
31-
}
32-
33-
func (f *Function) WriteGoCode(cw *CodeWriter) {
34-
panic("implement me")
35-
}
36-
37-
// Copy for copy fetcher cache value
38-
func (f *Function) Copy() CodeGen {
39-
if f == nil {
40-
return nil
41-
}
42-
return &Function{
43-
Type: f.Type,
44-
Name: f.Name,
45-
GoName: f.GoName,
46-
Params: f.Params,
47-
ReturnType: f.ReturnType,
48-
Deprecated: f.Deprecated,
49-
Suffix: f.Suffix,
50-
Description: f.Description,
51-
DocURL: f.DocURL,
52-
goFuncName: f.goFuncName,
53-
identifier: f.identifier,
30+
// GoArgs return go function args
31+
func (f *Function) GoArgs() string {
32+
var args []string
33+
for _, p := range f.Params {
34+
args = append(args, p.GoName())
5435
}
36+
return strings.Join(args, ", ")
5537
}
5638

57-
func (m *Function) needRelease() bool {
58-
switch m.ReturnType.(type) {
59-
case *typing.PrimitiveType, *typing.StringType:
60-
return false
39+
// GoReturn return go function return
40+
func (f *Function) GoReturn() string {
41+
if f.ReturnType == nil {
42+
return ""
6143
}
62-
return strings.HasPrefix(m.Name, "new") || !strings.HasPrefix(m.Name, "init") && strings.HasPrefix(m.Name, "Initial") ||
63-
strings.HasPrefix(m.Name, "copy") || strings.HasPrefix(m.Name, "mutableCopy")
44+
return f.ReturnType.GoName(nil, true)
6445
}
6546

6647
// Selector return full Objc function name
67-
func (m *Function) Selector() string {
68-
if m.identifier == "" {
48+
func (f *Function) Selector() string {
49+
if f.identifier == "" {
6950
var sb strings.Builder
70-
sb.WriteString(m.Name)
71-
for idx, p := range m.Params {
51+
sb.WriteString(f.Name)
52+
for idx, p := range f.Params {
7253
if idx > 0 {
7354
sb.WriteString(p.FieldName)
7455
}
7556
sb.WriteString(":")
7657
}
77-
m.identifier = sb.String()
58+
f.identifier = sb.String()
7859
}
79-
return m.identifier
60+
return f.identifier
8061
}
8162

82-
func (m *Function) String() string {
83-
return m.Selector()
63+
func (f *Function) String() string {
64+
return f.Selector()
8465
}
8566

8667
// NormalizeInstanceTypeFunction return new init function.
87-
func (m *Function) NormalizeInstanceTypeFunction(returnType *typing.ClassType) *Function {
68+
func (f *Function) NormalizeInstanceTypeFunction(returnType *typing.ClassType) *Function {
8869
nm := &Function{
89-
Name: m.Name,
90-
GoName: m.GoName,
91-
Params: m.Params,
70+
Name: f.Name,
71+
GoName: f.GoName,
72+
Params: f.Params,
9273
ReturnType: returnType,
93-
goFuncName: m.goFuncName,
94-
Suffix: m.Suffix,
74+
goFuncName: f.goFuncName,
75+
Suffix: f.Suffix,
9576
}
9677
return nm
9778
}
9879

9980
// WriteGoCallCode generate go function code to call c wrapper code
100-
func (m *Function) WriteGoCallCode(currentModule *modules.Module, typeName string, cw *CodeWriter) {
101-
funcDeclare := m.GoFuncDeclare(currentModule, typeName)
81+
func (f *Function) WriteGoCallCode(currentModule *modules.Module, typeName string, cw *CodeWriter) {
82+
funcDeclare := f.GoFuncDeclare(currentModule, typeName)
10283

103-
if m.Deprecated {
84+
if f.Deprecated {
10485
return
10586
cw.WriteLine("// deprecated")
10687
}
10788

108-
if m.DocURL != "" {
109-
cw.WriteLine(fmt.Sprintf("// %s [Full Topic]", m.Description))
110-
cw.WriteLine(fmt.Sprintf("//\n// [Full Topic]: %s", m.DocURL))
89+
if f.DocURL != "" {
90+
cw.WriteLine(fmt.Sprintf("// %s [Full Topic]", f.Description))
91+
cw.WriteLine(fmt.Sprintf("//\n// [Full Topic]: %s", f.DocURL))
11192
}
11293

11394
var receiver string
@@ -117,16 +98,16 @@ func (m *Function) WriteGoCallCode(currentModule *modules.Module, typeName strin
11798
cw.Indent()
11899

119100
var returnTypeStr string
120-
rt := typing.UnwrapAlias(m.ReturnType)
101+
rt := typing.UnwrapAlias(f.ReturnType)
121102
switch rt.(type) {
122103
case *typing.VoidType:
123104
returnTypeStr = "objc.Void"
124105
default:
125-
returnTypeStr = m.ReturnType.GoName(currentModule, true)
106+
returnTypeStr = f.ReturnType.GoName(currentModule, true)
126107
}
127-
callCode := fmt.Sprintf("objc.Call[%s](%s, objc.Sel(\"%s\")", returnTypeStr, receiver, m.Selector())
108+
callCode := fmt.Sprintf("objc.Call[%s](%s, objc.Sel(\"%s\")", returnTypeStr, receiver, f.Selector())
128109
var sb strings.Builder
129-
for idx, p := range m.Params {
110+
for idx, p := range f.Params {
130111
sb.WriteString(", ")
131112
switch tt := p.Type.(type) {
132113
case *typing.ClassType:
@@ -154,9 +135,6 @@ func (m *Function) WriteGoCallCode(currentModule *modules.Module, typeName strin
154135
default:
155136
var resultName = "rv"
156137
cw.WriteLine(resultName + " := " + callCode)
157-
if m.needRelease() {
158-
cw.WriteLine(resultName + ".Autorelease()")
159-
}
160138
cw.WriteLine("return " + resultName)
161139
}
162140
cw.UnIndent()

generate/codegen/modulewriter.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ type ModuleWriter struct {
2323
Protocols []*typing.ProtocolType
2424
EnumAliases []*AliasInfo
2525
FuncAliases []*AliasInfo
26+
Functions []*Function
2627
}
2728

2829
func (m *ModuleWriter) WriteCode() {
2930
m.WriteDocFile()
3031
m.WriteEnumAliases()
3132
m.WriteTypeAliases()
33+
m.WriteFunctions()
3234
if m.Module.Package == "coreimage" {
3335
// filter protocols maybe arent "real" protocols?
3436
// get "cannot find protocol declaration" with protocol imports
@@ -79,6 +81,48 @@ func (m *ModuleWriter) WriteTypeAliases() {
7981
}
8082
}
8183

84+
func (m *ModuleWriter) WriteFunctions() {
85+
if len(m.Functions) == 0 {
86+
return
87+
}
88+
89+
filePath := filepath.Join(m.PlatformDir, m.Module.Package, "functions.gen.go")
90+
os.MkdirAll(filepath.Dir(filePath), 0755)
91+
f, err := os.Create(filePath)
92+
if err != nil {
93+
panic(err)
94+
}
95+
defer f.Close()
96+
97+
cw := &CodeWriter{Writer: f, IndentStr: "\t"}
98+
cw.WriteLine(AutoGeneratedMark)
99+
cw.WriteLine("package " + m.Module.Package)
100+
101+
cw.WriteLine("import (")
102+
103+
// imports
104+
var imports = set.New("unsafe")
105+
for _, fa := range m.FuncAliases {
106+
imports.AddSet(fa.GoImports())
107+
}
108+
cw.Indent()
109+
imports.ForEach(func(value string) {
110+
if value != "github.com/progrium/macdriver/macos/objc" {
111+
cw.WriteLine("\"" + value + "\"")
112+
}
113+
})
114+
cw.UnIndent()
115+
cw.WriteLine(")")
116+
117+
for _, fa := range m.Functions {
118+
if fa.DocURL != "" {
119+
cw.WriteLine(fmt.Sprintf("// %s [Full Topic]", fa.Description))
120+
cw.WriteLine(fmt.Sprintf("//\n// [Full Topic]: %s", fa.DocURL))
121+
}
122+
cw.WriteLineF("// func %s(%s) %s", fa.Name, fa.GoArgs(), fa.GoReturn())
123+
}
124+
}
125+
82126
func (m *ModuleWriter) WriteEnumAliases() {
83127
enums := make([]*AliasInfo, len(m.EnumAliases))
84128
copy(enums, m.EnumAliases)

generate/function.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,24 @@ import (
88
"github.com/progrium/macdriver/generate/typing"
99
)
1010

11-
func (db *Generator) ToFunctionGen(fw string, sym Symbol) *codegen.Function {
12-
if db.genCache == nil {
13-
db.genCache = make(map[string]codegen.CodeGen)
14-
}
15-
key := fmt.Sprintf("%s.%s", fw, sym.Name)
16-
fg, ok := db.genCache[key]
17-
fmt.Printf("function: %s\n", key, fg, ok)
18-
11+
func (db *Generator) ToFunction(fw string, sym Symbol) *codegen.Function {
12+
typ := db.TypeFromSymbol(sym)
13+
fmt.Println("typ:", typ)
1914
type_ := &typing.FunctionType{
2015
Name: sym.Name,
2116
GName: modules.TrimPrefix(sym.Name),
2217
Module: modules.Get(fw),
2318
}
24-
functionGen := &codegen.Function{
19+
fn := &codegen.Function{
2520
Description: sym.Description,
2621
DocURL: sym.DocURL(),
2722
Type: type_,
2823
}
29-
30-
db.genCache[key] = functionGen
31-
return functionGen
24+
for _, arg := range sym.Parameters {
25+
fn.Params = append(fn.Params, &codegen.Param{
26+
Name: arg.Name,
27+
})
28+
}
29+
return fn
3230

3331
}

generate/generator.go

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,21 +107,7 @@ func (db *Generator) Generate(platform string, version int, rootDir string, fram
107107
continue
108108
}
109109
case "Function":
110-
functionGen := db.ToFunctionGen(framework, s)
111-
if functionGen == nil {
112-
log.Println("skipping function", s.Name)
113-
continue
114-
}
115-
functionGen.Init()
116-
fw := &codegen.FileWriter{
117-
Name: s.Name,
118-
Module: *functionGen.Type.Module,
119-
PlatformDir: rootDir,
120-
}
121-
fw.Add(functionGen)
122-
fw.WriteCode()
123-
default:
124-
log.Println("skipping", s.Kind, s.Name)
110+
mw.Functions = append(mw.Functions, db.ToFunction(framework, s))
125111
}
126112
}
127113
mw.WriteCode()

generate/types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ func (db *Generator) TypeFromSymbol(sym Symbol) typing.Type {
9393
GName: modules.TrimPrefix(sym.Name),
9494
Module: modules.Get(module),
9595
}
96+
case "Function":
97+
ft := &typing.FunctionType{
98+
Name: sym.Name,
99+
GName: modules.TrimPrefix(sym.Name),
100+
Module: modules.Get(module),
101+
}
102+
// TODO: parse function params and return type from declaration
103+
return ft
96104
default:
97105
fmt.Printf("TypeFromSymbol: kind=%s name=%s path=%s\n", sym.Kind, sym.Name, sym.Path)
98106
panic("bad type")

generate/typing/function_type.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@ import (
77

88
var _ Type = (*FunctionType)(nil)
99

10-
// FunctionType Objective-c interface type
10+
type Parameter struct {
11+
Type Type
12+
Name string // the param name
13+
}
14+
15+
// FunctionType Objective-c function type
1116
type FunctionType struct {
1217
Name string // objc type name
1318
GName string // Go name, usually is objc type name without prefix 'NS'
1419
Module *modules.Module // object-c module
20+
21+
Parameters []Parameter // function parameters
22+
Return Type // function return type
1523
}
1624

1725
var Function = &FunctionType{

0 commit comments

Comments
 (0)