Skip to content

Commit 05ed846

Browse files
vargazshana
authored andcommitted
Add generator support for properties.
1 parent f295c46 commit 05ed846

File tree

6 files changed

+178
-19
lines changed

6 files changed

+178
-19
lines changed

src/generator/Class.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public Class (Node n) {
1515
BaseClasses = new List<Class> ();
1616
Methods = new List<Method> ();
1717
Fields = new List<Field> ();
18+
Properties = new List<Property> ();
1819
}
1920

2021
public Node Node {
@@ -39,6 +40,10 @@ public List<Field> Fields {
3940
get; set;
4041
}
4142

43+
public List<Property> Properties {
44+
get; set;
45+
}
46+
4247
public bool Disable {
4348
get; set;
4449
}
@@ -130,12 +135,18 @@ public CodeTypeDeclaration GenerateClass (Generator g, CodeTypeDeclaration libDe
130135
foreach (Method m in Methods) {
131136
iface.Members.Add (m.GenerateIFaceMethod (g));
132137

133-
var cm = m.GenerateWrapperMethod (g);
134-
if (m.IsConstructor && hasBase) {
135-
var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo");
136-
(cm as CodeConstructor).BaseConstructorArgs.Add (implTypeInfo);
138+
if (m.GenWrapperMethod) {
139+
var cm = m.GenerateWrapperMethod (g);
140+
if (m.IsConstructor && hasBase) {
141+
var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo");
142+
(cm as CodeConstructor).BaseConstructorArgs.Add (implTypeInfo);
143+
}
144+
decl.Members.Add (cm);
137145
}
138-
decl.Members.Add (cm);
146+
}
147+
148+
foreach (Property p in Properties) {
149+
decl.Members.Add (p.GenerateProperty (g));
139150
}
140151

141152
return decl;

src/generator/Generator.cs

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,15 @@ void CreateMethods () {
185185
if (!klass.Node.HasValue ("members"))
186186
continue;
187187

188-
int fieldCount = 0;
188+
List<Node> members = new List<Node> ();
189189
foreach (string id in klass.Node ["members"].Split (' ')) {
190190
if (id == "")
191191
continue;
192-
Node n = Node.IdToNode [id];
192+
members.Add (Node.IdToNode [id]);
193+
}
193194

195+
int fieldCount = 0;
196+
foreach (Node n in members) {
194197
bool ctor = false;
195198
bool dtor = false;
196199

@@ -248,7 +251,7 @@ void CreateMethods () {
248251
if (retType.ElementType == CppTypes.Unknown)
249252
skip = true;
250253
if (CppTypeToCodeDomType (retType) == null) {
251-
Console.WriteLine ("\t\tS: " + retType);
254+
//Console.WriteLine ("\t\tS: " + retType);
252255
skip = true;
253256
}
254257

@@ -270,11 +273,11 @@ void CreateMethods () {
270273
}
271274

272275
if (CppTypeToCodeDomType (argtype) == null) {
273-
Console.WriteLine ("\t\tS: " + argtype);
276+
//Console.WriteLine ("\t\tS: " + argtype);
274277
skip = true;
275278
}
276279

277-
method.Parameters.Add (new Tuple<string, CppType> (argname, argtype));
280+
method.Parameters.Add (new Parameter (argname, argtype));
278281
argTypes.Add (argtype);
279282

280283
c++;
@@ -291,6 +294,11 @@ void CreateMethods () {
291294
klass.Methods.Add (method);
292295
}
293296

297+
foreach (Method method in klass.Methods) {
298+
if (AddAsQtProperty (klass, method))
299+
method.GenWrapperMethod = false;
300+
}
301+
294302
Field f2 = klass.Fields.FirstOrDefault (f => f.Type.ElementType == CppTypes.Unknown);
295303
if (f2 != null) {
296304
Console.WriteLine ("Skipping " + klass.Name + " because field " + f2.Name + " has unknown type.");
@@ -299,6 +307,65 @@ void CreateMethods () {
299307
}
300308
}
301309

310+
//
311+
// Property support
312+
// This is QT specific
313+
//
314+
bool AddAsQtProperty (Class klass, Method method) {
315+
// if it's const, returns a value, has no parameters, and there is no other method with the same name
316+
// in this class assume it's a property getter (for now?)
317+
if (method.IsConst && !method.ReturnType.Equals (CppTypes.Void) && !method.Parameters.Any () &&
318+
klass.Methods.Where (o => o.Name == method.Name).FirstOrDefault () == method) {
319+
Property property;
320+
321+
property = klass.Properties.Where (o => o.Name == method.FormattedName).FirstOrDefault ();
322+
if (property != null) {
323+
property.GetMethod = method;
324+
} else {
325+
property = new Property (method.FormattedName, method.ReturnType) { GetMethod = method };
326+
klass.Properties.Add (property);
327+
}
328+
329+
return true;
330+
}
331+
332+
// if it's name starts with "set", does not return a value, and has one arg (besides this ptr)
333+
// and there is no other method with the same name...
334+
if (method.Name.ToLower ().StartsWith ("set") && method.ReturnType.Equals (CppTypes.Void) &&
335+
method.Parameters.Count == 1 && klass.Methods.Where (o => o.Name == method.Name).Count () == 1) {
336+
string getterName = method.Name.Substring (3).TrimStart ('_').ToLower ();
337+
338+
string pname = method.FormattedName.Substring (3);
339+
Property property = null;
340+
341+
// ...AND there is a corresponding getter method that returns the right type, then assume it's a property setter
342+
bool doIt = false;
343+
property = klass.Properties.Where (o => o.Name == pname).FirstOrDefault ();
344+
if (property != null) {
345+
doIt = property.GetMethod != null && property.GetMethod.ReturnType.Equals (method.Parameters[0].Type);
346+
} else {
347+
Method getter = klass.Methods.Where (o => o.Name == getterName).FirstOrDefault ();
348+
doIt = getter != null && getter.ReturnType.Equals (method.Parameters[0].Type);
349+
}
350+
if (doIt) {
351+
if (property != null) {
352+
property.SetMethod = method;
353+
} else {
354+
property = new Property (pname, method.Parameters [0].Type) { SetMethod = method };
355+
klass.Properties.Add (property);
356+
}
357+
358+
// set the method's arg name to "value" so that the prop setter works right
359+
var valueParam = method.Parameters[0];
360+
valueParam.Name = "value";
361+
362+
return true;
363+
}
364+
}
365+
366+
return false;
367+
}
368+
302369
// Return a CppType for the type node N, return CppTypes.Unknown for unknown types
303370
CppType GetType (Node n) {
304371
return GetType (n, new CppType ());

src/generator/Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ FILES = \
6060
Node.cs \
6161
Class.cs \
6262
Method.cs \
63-
Field.cs
63+
Field.cs \
64+
Parameter.cs \
65+
Property.cs
6466

6567
DATA_FILES =
6668

src/generator/Method.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ class Method
1313
{
1414
public Method (Node node) {
1515
Node = node;
16-
Parameters = new List<Tuple<string, CppType>> ();
16+
Parameters = new List<Parameter> ();
17+
GenWrapperMethod = true;
1718
}
1819

1920
public Node Node {
@@ -56,14 +57,25 @@ public bool IsCopyCtor {
5657
get; set;
5758
}
5859

60+
public bool GenWrapperMethod {
61+
get; set;
62+
}
63+
5964
public CppType ReturnType {
6065
get; set;
6166
}
6267

63-
public List<Tuple<string, CppType>> Parameters {
68+
public List<Parameter> Parameters {
6469
get; set;
6570
}
6671

72+
// The C# method name
73+
public string FormattedName {
74+
get {
75+
return "" + Char.ToUpper (Name [0]) + Name.Substring (1);
76+
}
77+
}
78+
6779
string GetCSharpMethodName (string name) {
6880
return "" + Char.ToUpper (name [0]) + name.Substring (1);
6981
}
@@ -80,10 +92,10 @@ public CodeMemberMethod GenerateIFaceMethod (Generator g) {
8092
method.ReturnType = rtype;
8193

8294
foreach (var p in Parameters) {
83-
CppType ptype = p.Item2;
95+
CppType ptype = p.Type;
8496
bool byref;
8597
var ctype = g.CppTypeToCodeDomType (ptype, out byref);
86-
var param = new CodeParameterDeclarationExpression (ctype, p.Item1);
98+
var param = new CodeParameterDeclarationExpression (ctype, p.Name);
8799
if (byref)
88100
param.Direction = FieldDirection.Ref;
89101
if (!IsVirtual && !ptype.ToString ().Equals (string.Empty))
@@ -136,8 +148,8 @@ public CodeMemberMethod GenerateWrapperMethod (Generator g) {
136148

137149
foreach (var p in Parameters) {
138150
bool byref;
139-
var ptype = g.CppTypeToCodeDomType (p.Item2, out byref);
140-
var param = new CodeParameterDeclarationExpression (ptype, p.Item1);
151+
var ptype = g.CppTypeToCodeDomType (p.Type, out byref);
152+
var param = new CodeParameterDeclarationExpression (ptype, p.Name);
141153
if (byref)
142154
param.Direction = FieldDirection.Ref;
143155
method.Parameters.Add (param);
@@ -154,8 +166,8 @@ public CodeMemberMethod GenerateWrapperMethod (Generator g) {
154166
args [0] = new CodeFieldReferenceExpression (null, "Native");
155167
for (int i = 0; i < Parameters.Count; ++i) {
156168
bool byref;
157-
g.CppTypeToCodeDomType (Parameters [i].Item2, out byref);
158-
CodeExpression arg = new CodeArgumentReferenceExpression (Parameters [i].Item1);
169+
g.CppTypeToCodeDomType (Parameters [i].Type, out byref);
170+
CodeExpression arg = new CodeArgumentReferenceExpression (Parameters [i].Name);
159171
if (byref)
160172
arg = new CodeDirectionExpression (FieldDirection.Ref, arg);
161173
args [i + (IsStatic ? 0 : 1)] = arg;

src/generator/Parameter.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.CodeDom;
4+
using System.CodeDom.Compiler;
5+
6+
using Mono.VisualC.Interop;
7+
8+
public class Parameter
9+
{
10+
public Parameter (String name, CppType type) {
11+
Name = name;
12+
Type = type;
13+
}
14+
15+
public string Name {
16+
get; set;
17+
}
18+
19+
public CppType Type {
20+
get; set;
21+
}
22+
}

src/generator/Property.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//
2+
// Property.cs: Represents a C++ property
3+
//
4+
using System;
5+
using System.Collections.Generic;
6+
using System.CodeDom;
7+
using System.CodeDom.Compiler;
8+
9+
using Mono.VisualC.Interop;
10+
11+
class Property
12+
{
13+
public Property (string name, CppType type) {
14+
Name = name;
15+
Type = type;
16+
}
17+
18+
public string Name {
19+
get; set;
20+
}
21+
22+
public CppType Type {
23+
get; set;
24+
}
25+
26+
public Method GetMethod {
27+
get; set;
28+
}
29+
30+
public Method SetMethod {
31+
get; set;
32+
}
33+
34+
public CodeMemberProperty GenerateProperty (Generator g) {
35+
var p = new CodeMemberProperty () { Name = Name, Attributes = MemberAttributes.Public|MemberAttributes.Final };
36+
p.Type = g.CppTypeToCodeDomType (Type);
37+
if (GetMethod != null) {
38+
p.GetStatements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), GetMethod.Name), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native") })));
39+
}
40+
if (SetMethod != null) {
41+
p.SetStatements.Add (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), SetMethod.Name), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native"), new CodeArgumentReferenceExpression ("value") }));
42+
}
43+
return p;
44+
}
45+
}

0 commit comments

Comments
 (0)