Browse Source

Add generator support for properties.

pull/1/head
Zoltan Varga 15 years ago committed by Andreia Gaita
parent
commit
05ed8461a3
  1. 21
      src/generator/Class.cs
  2. 77
      src/generator/Generator.cs
  3. 4
      src/generator/Makefile.am
  4. 28
      src/generator/Method.cs
  5. 22
      src/generator/Parameter.cs
  6. 45
      src/generator/Property.cs

21
src/generator/Class.cs

@ -15,6 +15,7 @@ class Class @@ -15,6 +15,7 @@ class Class
BaseClasses = new List<Class> ();
Methods = new List<Method> ();
Fields = new List<Field> ();
Properties = new List<Property> ();
}
public Node Node {
@ -39,6 +40,10 @@ class Class @@ -39,6 +40,10 @@ class Class
get; set;
}
public List<Property> Properties {
get; set;
}
public bool Disable {
get; set;
}
@ -130,12 +135,18 @@ class Class @@ -130,12 +135,18 @@ class Class
foreach (Method m in Methods) {
iface.Members.Add (m.GenerateIFaceMethod (g));
var cm = m.GenerateWrapperMethod (g);
if (m.IsConstructor && hasBase) {
var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo");
(cm as CodeConstructor).BaseConstructorArgs.Add (implTypeInfo);
if (m.GenWrapperMethod) {
var cm = m.GenerateWrapperMethod (g);
if (m.IsConstructor && hasBase) {
var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo");
(cm as CodeConstructor).BaseConstructorArgs.Add (implTypeInfo);
}
decl.Members.Add (cm);
}
decl.Members.Add (cm);
}
foreach (Property p in Properties) {
decl.Members.Add (p.GenerateProperty (g));
}
return decl;

77
src/generator/Generator.cs

@ -185,12 +185,15 @@ public class Generator @@ -185,12 +185,15 @@ public class Generator
if (!klass.Node.HasValue ("members"))
continue;
int fieldCount = 0;
List<Node> members = new List<Node> ();
foreach (string id in klass.Node ["members"].Split (' ')) {
if (id == "")
continue;
Node n = Node.IdToNode [id];
members.Add (Node.IdToNode [id]);
}
int fieldCount = 0;
foreach (Node n in members) {
bool ctor = false;
bool dtor = false;
@ -248,7 +251,7 @@ public class Generator @@ -248,7 +251,7 @@ public class Generator
if (retType.ElementType == CppTypes.Unknown)
skip = true;
if (CppTypeToCodeDomType (retType) == null) {
Console.WriteLine ("\t\tS: " + retType);
//Console.WriteLine ("\t\tS: " + retType);
skip = true;
}
@ -270,11 +273,11 @@ public class Generator @@ -270,11 +273,11 @@ public class Generator
}
if (CppTypeToCodeDomType (argtype) == null) {
Console.WriteLine ("\t\tS: " + argtype);
//Console.WriteLine ("\t\tS: " + argtype);
skip = true;
}
method.Parameters.Add (new Tuple<string, CppType> (argname, argtype));
method.Parameters.Add (new Parameter (argname, argtype));
argTypes.Add (argtype);
c++;
@ -291,6 +294,11 @@ public class Generator @@ -291,6 +294,11 @@ public class Generator
klass.Methods.Add (method);
}
foreach (Method method in klass.Methods) {
if (AddAsQtProperty (klass, method))
method.GenWrapperMethod = false;
}
Field f2 = klass.Fields.FirstOrDefault (f => f.Type.ElementType == CppTypes.Unknown);
if (f2 != null) {
Console.WriteLine ("Skipping " + klass.Name + " because field " + f2.Name + " has unknown type.");
@ -299,6 +307,65 @@ public class Generator @@ -299,6 +307,65 @@ public class Generator
}
}
//
// Property support
// This is QT specific
//
bool AddAsQtProperty (Class klass, Method method) {
// if it's const, returns a value, has no parameters, and there is no other method with the same name
// in this class assume it's a property getter (for now?)
if (method.IsConst && !method.ReturnType.Equals (CppTypes.Void) && !method.Parameters.Any () &&
klass.Methods.Where (o => o.Name == method.Name).FirstOrDefault () == method) {
Property property;
property = klass.Properties.Where (o => o.Name == method.FormattedName).FirstOrDefault ();
if (property != null) {
property.GetMethod = method;
} else {
property = new Property (method.FormattedName, method.ReturnType) { GetMethod = method };
klass.Properties.Add (property);
}
return true;
}
// if it's name starts with "set", does not return a value, and has one arg (besides this ptr)
// and there is no other method with the same name...
if (method.Name.ToLower ().StartsWith ("set") && method.ReturnType.Equals (CppTypes.Void) &&
method.Parameters.Count == 1 && klass.Methods.Where (o => o.Name == method.Name).Count () == 1) {
string getterName = method.Name.Substring (3).TrimStart ('_').ToLower ();
string pname = method.FormattedName.Substring (3);
Property property = null;
// ...AND there is a corresponding getter method that returns the right type, then assume it's a property setter
bool doIt = false;
property = klass.Properties.Where (o => o.Name == pname).FirstOrDefault ();
if (property != null) {
doIt = property.GetMethod != null && property.GetMethod.ReturnType.Equals (method.Parameters[0].Type);
} else {
Method getter = klass.Methods.Where (o => o.Name == getterName).FirstOrDefault ();
doIt = getter != null && getter.ReturnType.Equals (method.Parameters[0].Type);
}
if (doIt) {
if (property != null) {
property.SetMethod = method;
} else {
property = new Property (pname, method.Parameters [0].Type) { SetMethod = method };
klass.Properties.Add (property);
}
// set the method's arg name to "value" so that the prop setter works right
var valueParam = method.Parameters[0];
valueParam.Name = "value";
return true;
}
}
return false;
}
// Return a CppType for the type node N, return CppTypes.Unknown for unknown types
CppType GetType (Node n) {
return GetType (n, new CppType ());

4
src/generator/Makefile.am

@ -60,7 +60,9 @@ FILES = \ @@ -60,7 +60,9 @@ FILES = \
Node.cs \
Class.cs \
Method.cs \
Field.cs
Field.cs \
Parameter.cs \
Property.cs
DATA_FILES =

28
src/generator/Method.cs

@ -13,7 +13,8 @@ class Method @@ -13,7 +13,8 @@ class Method
{
public Method (Node node) {
Node = node;
Parameters = new List<Tuple<string, CppType>> ();
Parameters = new List<Parameter> ();
GenWrapperMethod = true;
}
public Node Node {
@ -56,14 +57,25 @@ class Method @@ -56,14 +57,25 @@ class Method
get; set;
}
public bool GenWrapperMethod {
get; set;
}
public CppType ReturnType {
get; set;
}
public List<Tuple<string, CppType>> Parameters {
public List<Parameter> Parameters {
get; set;
}
// The C# method name
public string FormattedName {
get {
return "" + Char.ToUpper (Name [0]) + Name.Substring (1);
}
}
string GetCSharpMethodName (string name) {
return "" + Char.ToUpper (name [0]) + name.Substring (1);
}
@ -80,10 +92,10 @@ class Method @@ -80,10 +92,10 @@ class Method
method.ReturnType = rtype;
foreach (var p in Parameters) {
CppType ptype = p.Item2;
CppType ptype = p.Type;
bool byref;
var ctype = g.CppTypeToCodeDomType (ptype, out byref);
var param = new CodeParameterDeclarationExpression (ctype, p.Item1);
var param = new CodeParameterDeclarationExpression (ctype, p.Name);
if (byref)
param.Direction = FieldDirection.Ref;
if (!IsVirtual && !ptype.ToString ().Equals (string.Empty))
@ -136,8 +148,8 @@ class Method @@ -136,8 +148,8 @@ class Method
foreach (var p in Parameters) {
bool byref;
var ptype = g.CppTypeToCodeDomType (p.Item2, out byref);
var param = new CodeParameterDeclarationExpression (ptype, p.Item1);
var ptype = g.CppTypeToCodeDomType (p.Type, out byref);
var param = new CodeParameterDeclarationExpression (ptype, p.Name);
if (byref)
param.Direction = FieldDirection.Ref;
method.Parameters.Add (param);
@ -154,8 +166,8 @@ class Method @@ -154,8 +166,8 @@ class Method
args [0] = new CodeFieldReferenceExpression (null, "Native");
for (int i = 0; i < Parameters.Count; ++i) {
bool byref;
g.CppTypeToCodeDomType (Parameters [i].Item2, out byref);
CodeExpression arg = new CodeArgumentReferenceExpression (Parameters [i].Item1);
g.CppTypeToCodeDomType (Parameters [i].Type, out byref);
CodeExpression arg = new CodeArgumentReferenceExpression (Parameters [i].Name);
if (byref)
arg = new CodeDirectionExpression (FieldDirection.Ref, arg);
args [i + (IsStatic ? 0 : 1)] = arg;

22
src/generator/Parameter.cs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.CodeDom;
using System.CodeDom.Compiler;
using Mono.VisualC.Interop;
public class Parameter
{
public Parameter (String name, CppType type) {
Name = name;
Type = type;
}
public string Name {
get; set;
}
public CppType Type {
get; set;
}
}

45
src/generator/Property.cs

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
//
// Property.cs: Represents a C++ property
//
using System;
using System.Collections.Generic;
using System.CodeDom;
using System.CodeDom.Compiler;
using Mono.VisualC.Interop;
class Property
{
public Property (string name, CppType type) {
Name = name;
Type = type;
}
public string Name {
get; set;
}
public CppType Type {
get; set;
}
public Method GetMethod {
get; set;
}
public Method SetMethod {
get; set;
}
public CodeMemberProperty GenerateProperty (Generator g) {
var p = new CodeMemberProperty () { Name = Name, Attributes = MemberAttributes.Public|MemberAttributes.Final };
p.Type = g.CppTypeToCodeDomType (Type);
if (GetMethod != null) {
p.GetStatements.Add (new CodeMethodReturnStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), GetMethod.Name), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native") })));
}
if (SetMethod != null) {
p.SetStatements.Add (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), SetMethod.Name), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native"), new CodeArgumentReferenceExpression ("value") }));
}
return p;
}
}
Loading…
Cancel
Save