Browse Source

Hacked on generator. Improvements to CppType to support generator, including round-trippable (I think) ToString.

git-svn-id: https://mono-soc-2010.googlecode.com/svn/trunk/cppinterop@116 a470b8cb-0e6f-1642-1b45-71e107334c4b
pull/1/head
alexander.corrado 15 years ago
parent
commit
fa95953dfd
  1. 18
      Mono.VisualC.Code/Atoms/Class.cs
  2. 36
      Mono.VisualC.Code/Atoms/Method.cs
  3. 184
      Mono.VisualC.Interop/CppType.cs
  4. 8
      Mono.VisualC.Interop/Util/IEnumerableTransform.cs
  5. 90
      generator/Main.cs
  6. 6
      generator/generator.csproj

18
Mono.VisualC.Code/Atoms/Class.cs

@ -18,26 +18,32 @@ namespace Mono.VisualC.Code.Atoms { @@ -18,26 +18,32 @@ namespace Mono.VisualC.Code.Atoms {
Struct
}
public struct BaseClass {
public Class Class;
public string Name;
public Access Access;
public bool IsVirtual;
}
public string Name { get; set; }
public string StaticCppLibrary { get; set; }
public Definition DefinedAs { get; set; }
public IEnumerable<BaseClass> Bases { get; set; }
public Definition DefinedAs { get; set; }
public IList<string> TemplateArguments { get; set; }
public Class (string name)
{
Name = name;
Bases = Enumerable.Empty<BaseClass> ();
TemplateArguments = new List<string> ();
}
internal protected override CodeObject InsideCodeNamespace (CodeNamespace ns)
{
var wrapper = new CodeTypeDeclaration (Name) { TypeAttributes = TypeAttributes.Public };
foreach (var arg in TemplateArguments)
wrapper.TypeParameters.Add (arg);
var iface = CreateInterface ();
var native = CreateNativeLayout ();
@ -45,7 +51,7 @@ namespace Mono.VisualC.Code.Atoms { @@ -45,7 +51,7 @@ namespace Mono.VisualC.Code.Atoms {
wrapper.Members.Add (native);
// FIXME: For now, we'll have the managed wrapper extend from the first public base class
string managedBase = Bases.Where (b => b.Access == Access.Public).Select (b => b.Class.Name).FirstOrDefault ();
string managedBase = Bases.Where (b => b.Access == Access.Public).Select (b => b.Name).FirstOrDefault ();
if (managedBase == null) {
managedBase = typeof (ICppObject).Name;
@ -56,7 +62,7 @@ namespace Mono.VisualC.Code.Atoms { @@ -56,7 +62,7 @@ namespace Mono.VisualC.Code.Atoms {
Name = "Native",
Type = new CodeTypeReference (typeof (CppInstancePtr)),
HasSet = false,
Attributes = MemberAttributes.Public
Attributes = MemberAttributes.Public | MemberAttributes.Final
};
nativeProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), nativeField.Name)));
@ -135,7 +141,7 @@ namespace Mono.VisualC.Code.Atoms { @@ -135,7 +141,7 @@ namespace Mono.VisualC.Code.Atoms {
case Access.Private: writer.Write ("private "); break;
}
writer.Write (baseClass.Class.Name);
writer.Write (baseClass.Name);
if (!bce.MoveNext ())
break;

36
Mono.VisualC.Code/Atoms/Method.cs

@ -10,15 +10,15 @@ namespace Mono.VisualC.Code.Atoms { @@ -10,15 +10,15 @@ namespace Mono.VisualC.Code.Atoms {
public class Method : CodeContainer {
public struct Parameter {
public string Name;
public string Type;
public CppType Type;
}
public string Name { get; set; }
public Access Access { get; set; }
public bool IsVirtual { get; set; }
public bool IsStatic { get; set; }
public string RetType { get; set; }
public CppType RetType { get; set; }
public IEnumerable<Parameter> Parameters { get; set; }
@ -32,13 +32,15 @@ namespace Mono.VisualC.Code.Atoms { @@ -32,13 +32,15 @@ namespace Mono.VisualC.Code.Atoms {
CodeMemberMethod method = null;
if (decl.IsInterface) {
method = new CodeMemberMethod ();
method.Name = Name;
Type managedReturn = new CppType (RetType).ToManagedType ();
if (managedReturn != null)
method.ReturnType = new CodeTypeReference (managedReturn);
method = new CodeMemberMethod { Name = this.Name };
Type managedType = RetType.ToManagedType ();
if (managedType != null && managedType.IsByRef)
method.ReturnType = new CodeTypeReference (typeof (IntPtr));
else if (managedType != null && managedType != typeof (ICppObject))
method.ReturnType = new CodeTypeReference (managedType);
else
method.ReturnType = new CodeTypeReference (RetType);
method.ReturnType = new CodeTypeReference (RetType.ElementTypeName);
if (IsVirtual)
method.CustomAttributes.Add (new CodeAttributeDeclaration ("Virtual"));
@ -46,18 +48,24 @@ namespace Mono.VisualC.Code.Atoms { @@ -46,18 +48,24 @@ namespace Mono.VisualC.Code.Atoms {
if (IsStatic)
method.CustomAttributes.Add (new CodeAttributeDeclaration ("Static"));
else
method.Parameters.Add (new CodeParameterDeclarationExpression (typeof (CppInstancePtr), "this"));
method.Parameters.Add (new CodeParameterDeclarationExpression (typeof (CppInstancePtr).Name, "this"));
foreach (var param in Parameters) {
CodeParameterDeclarationExpression paramDecl;
Type managedType = new CppType (param.Type).ToManagedType ();
if (managedType != null)
managedType = param.Type.ToManagedType ();
// BOO work around bug in Codedom dealing with byref types!
if (managedType != null && managedType.IsByRef)
paramDecl = new CodeParameterDeclarationExpression (managedType.GetElementType (), param.Name) { Direction = FieldDirection.Ref };
else if (managedType != null && managedType != typeof (ICppObject))
paramDecl = new CodeParameterDeclarationExpression (managedType, param.Name);
else
paramDecl = new CodeParameterDeclarationExpression (param.Type, param.Name);
paramDecl = new CodeParameterDeclarationExpression (param.Type.ElementTypeName, param.Name);
// FIXME: Only add MangleAs attribute if the managed type chosen would mangle differently by default
if (!IsVirtual)
paramDecl.CustomAttributes.Add (new CodeAttributeDeclaration ("MangleAs", new CodeAttributeArgument (new CodePrimitiveExpression (param.Type))));
paramDecl.CustomAttributes.Add (new CodeAttributeDeclaration ("MangleAs", new CodeAttributeArgument (new CodePrimitiveExpression (param.Type.ToString ()))));
method.Parameters.Add (paramDecl);
}

184
Mono.VisualC.Interop/CppType.cs

@ -14,6 +14,8 @@ using System.Text.RegularExpressions; @@ -14,6 +14,8 @@ using System.Text.RegularExpressions;
using System.Reflection;
using System.Collections.Generic;
using Mono.VisualC.Interop.Util;
namespace Mono.VisualC.Interop {
public enum CppModifiers {
@ -50,61 +52,77 @@ namespace Mono.VisualC.Interop { @@ -50,61 +52,77 @@ namespace Mono.VisualC.Interop {
{ "\\&", CppModifiers.Reference }
};
/*
public static Dictionary<CppModifiers,string> Stringify = new Dictionary<CppModifiers, string> () {
{ CppModifiers.Pointer, "*" },
{ CppModifiers.Array, "[]" },
{ CppModifiers.Reference, "&" }
};
*/
public static List<Func<CppType,Type>> ElementTypeToManagedMap = new List<Func<CppType, Type>> () {
(t) => { return t.ElementType == CppTypes.Class || t.ElementType == CppTypes.Struct? typeof (ICppObject) : null; },
(t) => { return t.ElementType == CppTypes.Char && t.Modifiers.Contains (CppModifiers.Pointer)? typeof (string) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Short) && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (ushort) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Long) && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (ulong) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Short)? typeof (short) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Long)? typeof (long) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (uint) : null; },
(t) => { return t.ElementType == CppTypes.Void? typeof (void) : null; },
(t) => { return t.ElementType == CppTypes.Bool? typeof (bool) : null; },
(t) => { return t.ElementType == CppTypes.Char? typeof (char) : null; },
(t) => { return t.ElementType == CppTypes.Int? typeof (int) : null; },
(t) => { return t.ElementType == CppTypes.Float? typeof (float) : null; },
(t) => { return t.ElementType == CppTypes.Double? typeof (double) : null; }
};
// FIXME: Passing these as delegates allows for the flexibility of doing processing on the
// type (i.e. to correctly mangle the function pointer arguments if the managed type is a delegate),
// however this does not make it very easy to override the default mappings at runtime.
public static List<Func<CppType,Type>> CppTypeToManagedMap = new List<Func<CppType, Type>> () {
(t) => (t.ElementType == CppTypes.Class ||
t.ElementType == CppTypes.Struct ||
(t.ElementType == CppTypes.Unknown && t.ElementTypeName != null)) &&
(t.Modifiers.Count (m => m == CppModifiers.Pointer) == 1 ||
t.Modifiers.Contains (CppModifiers.Reference))? typeof (ICppObject) : null,
// void* gets IntPtr
(t) => t.ElementType == CppTypes.Void && t.Modifiers.Contains (CppModifiers.Pointer)? typeof (IntPtr) : null,
// single pointer to char gets string
(t) => t.ElementType == CppTypes.Char && t.Modifiers.Count (m => m == CppModifiers.Pointer) == 1? typeof (string) : null,
// pointer to pointer to char gets StringBuilder
(t) => t.ElementType == CppTypes.Char && t.Modifiers.Count (m => m == CppModifiers.Pointer) == 2? typeof (StringBuilder) : null,
// convert single pointers to primatives to managed byref
(t) => t.Modifiers.Count (m => m == CppModifiers.Pointer) == 1? t.WithoutModifier (CppModifiers.Pointer).ToManagedType ().MakeByRefType () : null,
// more than one level of indirection gets IntPtr type
(t) => t.Modifiers.Contains (CppModifiers.Pointer)? typeof (IntPtr) : null,
(t) => t.Modifiers.Contains (CppModifiers.Reference)? t.WithoutModifier (CppModifiers.Reference).ToManagedType ().MakeByRefType () : null,
(t) => t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Short) && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (ushort) : null,
(t) => t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Long) && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (ulong) : null,
(t) => t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Short)? typeof (short) : null,
(t) => t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Long)? typeof (long) : null,
(t) => t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (uint) : null,
(t) => t.ElementType == CppTypes.Void? typeof (void) : null,
(t) => t.ElementType == CppTypes.Bool? typeof (bool) : null,
(t) => t.ElementType == CppTypes.Char? typeof (char) : null,
(t) => t.ElementType == CppTypes.Int? typeof (int) : null,
(t) => t.ElementType == CppTypes.Float? typeof (float) : null,
(t) => t.ElementType == CppTypes.Double? typeof (double) : null
};
public static List<Func<Type,CppType>> ManagedToCppTypeMap = new List<Func<Type,CppType>> () {
(t) => { return typeof (void).Equals (t) ? CppTypes.Void : CppTypes.Unknown; },
(t) => { return typeof (bool).Equals (t) ? CppTypes.Bool : CppTypes.Unknown; },
(t) => { return typeof (char).Equals (t) ? CppTypes.Char : CppTypes.Unknown; },
(t) => { return typeof (int).Equals (t) ? CppTypes.Int : CppTypes.Unknown; },
(t) => { return typeof (float).Equals (t) ? CppTypes.Float : CppTypes.Unknown; },
(t) => { return typeof (double).Equals (t)? CppTypes.Double : CppTypes.Unknown; },
(t) => { return typeof (short).Equals (t) ? new CppType (CppModifiers.Short, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (long).Equals (t) ? new CppType (CppModifiers.Long, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (uint).Equals (t) ? new CppType (CppModifiers.Unsigned, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (ushort).Equals (t)? new CppType (CppModifiers.Unsigned, CppModifiers.Short, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (ulong).Equals (t)? new CppType (CppModifiers.Unsigned, CppModifiers.Long, CppTypes.Int) : CppTypes.Unknown; },
(t) => typeof (void).Equals (t) ? CppTypes.Void : CppTypes.Unknown,
(t) => typeof (bool).Equals (t) ? CppTypes.Bool : CppTypes.Unknown,
(t) => typeof (char).Equals (t) ? CppTypes.Char : CppTypes.Unknown,
(t) => typeof (int).Equals (t) ? CppTypes.Int : CppTypes.Unknown,
(t) => typeof (float).Equals (t) ? CppTypes.Float : CppTypes.Unknown,
(t) => typeof (double).Equals (t)? CppTypes.Double : CppTypes.Unknown,
(t) => typeof (short).Equals (t) ? new CppType (CppModifiers.Short, CppTypes.Int) : CppTypes.Unknown,
(t) => typeof (long).Equals (t) ? new CppType (CppModifiers.Long, CppTypes.Int) : CppTypes.Unknown,
(t) => typeof (uint).Equals (t) ? new CppType (CppModifiers.Unsigned, CppTypes.Int) : CppTypes.Unknown,
(t) => typeof (ushort).Equals (t)? new CppType (CppModifiers.Unsigned, CppModifiers.Short, CppTypes.Int) : CppTypes.Unknown,
(t) => typeof (ulong).Equals (t)? new CppType (CppModifiers.Unsigned, CppModifiers.Long, CppTypes.Int) : CppTypes.Unknown,
// strings mangle as "const char*" by default
(t) => { return typeof (string).Equals (t)? new CppType (CppModifiers.Const, CppTypes.Char, CppModifiers.Pointer) : CppTypes.Unknown; },
(t) => typeof (string).Equals (t)? new CppType (CppModifiers.Const, CppTypes.Char, CppModifiers.Pointer) : CppTypes.Unknown,
// StringBuilder gets "char*"
(t) => { return typeof (StringBuilder).Equals (t)? new CppType (CppTypes.Char, CppModifiers.Pointer) : CppTypes.Unknown; },
(t) => typeof (StringBuilder).Equals (t)? new CppType (CppTypes.Char, CppModifiers.Pointer) : CppTypes.Unknown,
// delegate types get special treatment
(t) => { return typeof (Delegate).IsAssignableFrom (t)? CppType.ForDelegate (t) : CppTypes.Unknown; },
(t) => typeof (Delegate).IsAssignableFrom (t)? CppType.ForDelegate (t) : CppTypes.Unknown,
// ... and of course ICppObjects do too!
// FIXME: We assume c++ class not struct. There should probably be an attribute
// we can apply to managed wrappers to indicate if the underlying C++ type is actually declared struct
(t) => { return typeof (ICppObject).IsAssignableFrom (t)? new CppType (CppTypes.Class, t.Name, CppModifiers.Pointer) : CppTypes.Unknown; },
(t) => typeof (ICppObject).IsAssignableFrom (t)? new CppType (CppTypes.Class, t.Name, CppModifiers.Pointer) : CppTypes.Unknown,
// convert managed type modifiers to C++ type modifiers like so:
// ref types to C++ references
@ -218,7 +236,7 @@ namespace Mono.VisualC.Interop { @@ -218,7 +236,7 @@ namespace Mono.VisualC.Interop {
// and combines its modifiers into this instance.
// Use when THIS instance may have attributes you want,
// but want the element type of the passed instance.
public void ApplyTo (CppType type)
public CppType ApplyTo (CppType type)
{
ElementType = type.ElementType;
ElementTypeName = type.ElementTypeName;
@ -228,14 +246,58 @@ namespace Mono.VisualC.Interop { @@ -228,14 +246,58 @@ namespace Mono.VisualC.Interop {
if (oldModifiers != null)
Modifiers.AddRange (oldModifiers);
return this;
}
// Removes the modifiers from the passed instance from this instance
public CppType Subtract (CppType type)
{
if (internalModifiers == null)
return this;
foreach (var modifier in type.Modifiers) {
for (int i = 0; i < internalModifiers.Count; i++) {
if (internalModifiers [i] == modifier)
internalModifiers.RemoveAt (i--);
}
}
return this;
}
/*
public override bool Equals (object obj)
{
if (obj == null)
return false;
if (obj.GetType () != typeof(CppType))
return false;
CppType other = (CppType)obj;
// FIXME: the order of some modifiers is not significant
return ((internalModifiers == null && other.internalModifiers == null) ||
internalModifiers.SequenceEqual (other.internalModifiers)) &&
ElementType == other.ElementType &&
ElementTypeName == other.ElementTypeName;
}
public override int GetHashCode ()
{
unchecked {
return (internalModifiers != null? internalModifiers.SequenceHashCode () : 0) ^
ElementType.GetHashCode () ^
(ElementTypeName != null? ElementTypeName.GetHashCode () : 0);
}
}
public override string ToString ()
{
StringBuilder cppTypeString = new StringBuilder ();
cppTypeString.Append (Enum.GetName (typeof (CppTypes), ElementType).ToLower ());
if (ElementType != CppTypes.Unknown)
cppTypeString.Append (Enum.GetName (typeof (CppTypes), ElementType).ToLower ());
if (ElementTypeName != null)
cppTypeString.Append (" ").Append (ElementTypeName);
@ -250,43 +312,43 @@ namespace Mono.VisualC.Interop { @@ -250,43 +312,43 @@ namespace Mono.VisualC.Interop {
return cppTypeString.ToString ();
}
*/
public Type ToManagedType ()
{
return ToManagedType (false);
}
public Type ToManagedType (bool usePointerTypes)
{
CppType me = this;
Type mappedType = (from checkType in ElementTypeToManagedMap
Type mappedType = (from checkType in CppTypeToManagedMap
where checkType (me) != null
select checkType (me)).FirstOrDefault ();
if (mappedType == null)
return null;
return mappedType;
}
// FIXME: not ideal to have this test here
if (typeof (string).Equals (mappedType) || typeof (ICppObject).Equals (mappedType))
return mappedType;
public CppType Modify (CppModifiers modifier)
{
CppType newType = this;
var newModifier = new CppModifiers [] { modifier };
if (newType.internalModifiers != null)
newType.internalModifiers.AddFirst (newModifier);
else
newType.internalModifiers = new List<CppModifiers> (newModifier);
if (Modifiers.Contains (CppModifiers.Pointer) && !usePointerTypes)
return typeof (IntPtr);
else if (Modifiers.Contains (CppModifiers.Pointer))
mappedType = mappedType.MakePointerType ();
else if (Modifiers.Contains (CppModifiers.Array))
mappedType = mappedType.MakeArrayType ();
return newType;
}
return mappedType;
public CppType WithoutModifier (CppModifiers modifier)
{
CppType newType = this;
newType.internalModifiers = new List<CppModifiers> (newType.Modifiers.Without (modifier));
return newType;
}
public static CppType ForManagedType (Type type)
{
var mappedType = (from checkType in ManagedToCppTypeMap
where checkType (type).ElementType != CppTypes.Unknown
select checkType (type)).FirstOrDefault ();
CppType mappedType = (from checkType in ManagedToCppTypeMap
where checkType (type).ElementType != CppTypes.Unknown
select checkType (type)).FirstOrDefault ();
return mappedType;
}
@ -299,8 +361,6 @@ namespace Mono.VisualC.Interop { @@ -299,8 +361,6 @@ namespace Mono.VisualC.Interop {
throw new NotImplementedException ();
}
public static implicit operator CppType (CppTypes type) {
return new CppType (type);
}

8
Mono.VisualC.Interop/Util/IEnumerableTransform.cs

@ -103,6 +103,14 @@ namespace Mono.VisualC.Interop.Util { @@ -103,6 +103,14 @@ namespace Mono.VisualC.Interop.Util {
yield return additionalValue;
}
public static IEnumerable<T> Without<T> (this IEnumerable<T> current, T unwantedValue)
{
foreach (var output in current)
if (!output.Equals (unwantedValue))
yield return output;
}
public static int SequenceHashCode<T> (this IEnumerable<T> sequence)
{
int hash = 0;

90
generator/Main.cs

@ -2,12 +2,14 @@ using System; @@ -2,12 +2,14 @@ using System;
using NDesk.Options;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Linq;
using Mono.VisualC.Interop;
using Mono.VisualC.Code;
using Mono.VisualC.Code.Atoms;
@ -16,6 +18,8 @@ using Microsoft.CSharp; @@ -16,6 +18,8 @@ using Microsoft.CSharp;
namespace CPPInterop {
class Generator {
public static readonly Regex TemplateRegEx = new Regex ("([^\\<]+)\\<(.+)\\>$");
public static readonly string [] genericTypeArgs = new string [] { "T", "U", "V", "W", "X", "Y", "Z" };
public string Source { get; set; }
public Dictionary<string, string> Classes;
@ -73,15 +77,48 @@ namespace CPPInterop { @@ -73,15 +77,48 @@ namespace CPPInterop {
XmlNode find (XmlNode root, string id)
{
XmlNode n = root.SelectSingleNode ("/GCC_XML/*[@id='" + id + "']");
if (n.Name == "Typedef")
return n;
//if (n.Name == "Typedef")
// return n;
if (n.Attributes["type"] != null)
return find (root, n.Attributes["type"].Value);
return n;
}
CppType findType (XmlNode root, string id)
{
return findType (root, id, new CppType ());
}
CppType findType (XmlNode root, string id, CppType modifiers)
{
XmlNode n = root.SelectSingleNode ("/GCC_XML/*[@id='" + id + "']");
switch (n.Name) {
case "ArrayType": return findType (root, n.Attributes ["type"].Value, modifiers.Modify (CppModifiers.Array));
case "PointerType": return findType (root, n.Attributes ["type"].Value, modifiers.Modify (CppModifiers.Pointer));
case "ReferenceType": return findType (root, n.Attributes ["type"].Value, modifiers.Modify (CppModifiers.Reference));
case "CvQualifiedType": return findType (root, n.Attributes ["type"].Value, modifiers.Modify (n.Attributes ["const"].Value == "1"? CppModifiers.Const : CppModifiers.Volatile));
case "Typedef": return findType (root, n.Attributes ["type"].Value, modifiers);
case "FundamentalType": return modifiers.ApplyTo (new CppType (n.Attributes ["name"].Value));
case "Class": return modifiers.ApplyTo (new CppType (CppTypes.Class, n.Attributes ["name"].Value));
case "Struct": return modifiers.ApplyTo (new CppType (CppTypes.Struct, n.Attributes ["name"].Value));
case "Enumeration": return modifiers.ApplyTo (new CppType (CppTypes.Enum, n.Attributes ["name"].Value));
// FIXME: support function pointers better
case "FunctionType": return modifiers.ApplyTo (CppTypes.Void);
}
throw new NotImplementedException ("Unknown type node: " + n.Name);
}
public void Run ()
{
var csharp = new CSharpCodeProvider ();
var options = new CodeGeneratorOptions {
BlankLinesBetweenMembers = false
};
XmlDocument xmldoc = new XmlDocument ();
xmldoc.Load (Source);
XmlNodeList namespaces = xmldoc.SelectNodes ("/GCC_XML/Namespace[@name != '::' and @name != '' and @name != 'std']");
@ -96,8 +133,31 @@ namespace CPPInterop { @@ -96,8 +133,31 @@ namespace CPPInterop {
if (Classes.ContainsKey (name))
continue;
// FIXME: better way to do this
CppType [] replaceArgs = null;
Match m = TemplateRegEx.Match (name);
if (m.Success) {
string baseName = m.Groups [1].Value;
if (Classes.ContainsKey (baseName))
continue;
replaceArgs = m.Groups [2].Value.Split (',').Select (s => new CppType (s)).ToArray ();
string [] ras = new string [replaceArgs.Length];
string [] letters = new string [replaceArgs.Length];
for (int i = 0; i < replaceArgs.Length; i++) {
letters [i] = genericTypeArgs [i];
ras [i] = string.Format ("{0} with {1}", replaceArgs [i].ToString (), letters [i]);
}
Console.WriteLine ("Warning: Creating generic type {0}<{1}> from the instantiated template {2} by replacing {3} (very buggy!!!)", baseName, string.Join (",", letters), name, string.Join (", ", ras));
name = baseName;
}
var cu = new CodeUnit { ManagedNamespace = "Qt.Core" };
var classAtom = new Class (name) { StaticCppLibrary = "Qt.Libs.QtCore" };
if (replaceArgs != null)
for (int i = 0; i < replaceArgs.Length; i++)
classAtom.TemplateArguments.Add (genericTypeArgs [i]);
cu.Atoms.AddLast (classAtom);
string size = clas.Attributes["size"].Value;
@ -122,9 +182,15 @@ namespace CPPInterop { @@ -122,9 +182,15 @@ namespace CPPInterop {
//str.Append ("\t\t\t");
string mname = n.Attributes["name"].Value;
XmlNode ret = find (xmldoc.DocumentElement, n.Attributes["returns"]);
CppType retType = findType (xmldoc.DocumentElement, n.Attributes["returns"].Value);
if (replaceArgs != null)
for (int i = 0; i < replaceArgs.Length; i++)
if (replaceArgs [i].ElementTypeName == retType.ElementTypeName) {
retType.Subtract (replaceArgs [i]);
retType.ElementTypeName = genericTypeArgs [i];
}
string rett = ret.Attributes["name"].Value;
bool virt = n.Attributes["virtual"] != null && n.Attributes["virtual"].Value == "1";
bool stat = n.Attributes["static"] != null && n.Attributes["static"].Value == "1";
@ -135,7 +201,7 @@ namespace CPPInterop { @@ -135,7 +201,7 @@ namespace CPPInterop {
List<Method.Parameter> args = new List<Method.Parameter> ();
var methodAtom = new Method (mname) {
RetType = rett,
RetType = retType,
IsVirtual = virt,
IsStatic = stat,
Parameters = args
@ -149,8 +215,14 @@ namespace CPPInterop { @@ -149,8 +215,14 @@ namespace CPPInterop {
else
argname = arg.Attributes["name"].Value;
XmlNode argt = find (xmldoc.DocumentElement, arg.Attributes["type"].Value);
string argtype = argt.Attributes["name"].Value;
CppType argtype = findType (xmldoc.DocumentElement, arg.Attributes["type"].Value);
if (replaceArgs != null)
for (int i = 0; i < replaceArgs.Length; i++)
if (replaceArgs [i].ElementTypeName == argtype.ElementTypeName) {
argtype.Subtract (replaceArgs [i]);
argtype.ElementTypeName = genericTypeArgs [i];
}
//str.Append (", " + argtype + " " + argname);
args.Add (new Method.Parameter { Name = argname, Type = argtype });
@ -162,7 +234,7 @@ namespace CPPInterop { @@ -162,7 +234,7 @@ namespace CPPInterop {
classAtom.Atoms.AddLast (methodAtom);
}
Classes.Add (name, sanitize(name) + ".cs");
Classes.Add (name, sanitize (name) + ".cs");
FileStream fs = File.Create (Path.Combine (Dir, Classes[name]));
StreamWriter sw = new StreamWriter(fs);
@ -180,7 +252,7 @@ namespace CPPInterop { @@ -180,7 +252,7 @@ namespace CPPInterop {
size));
sw.Write (sb.ToString());
*/
new CSharpCodeProvider ().GenerateCodeFromCompileUnit (cu.WrapperToCodeDom (), sw, new CodeGeneratorOptions ());
csharp.GenerateCodeFromCompileUnit (cu.WrapperToCodeDom (), sw, options);
sw.Flush ();
sw.Close ();

6
generator/generator.csproj

@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Commandlineparameters>-f=qobject.xml</Commandlineparameters>
<Commandlineparameters>-f=/Users/Alex/OpenSource/gccxml/gccxml-build/bin/qobject.xml -o=.</Commandlineparameters>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
@ -62,5 +62,9 @@ @@ -62,5 +62,9 @@
<Project>{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}</Project>
<Name>Mono.VisualC.Code</Name>
</ProjectReference>
<ProjectReference Include="..\Mono.VisualC.Interop\Mono.VisualC.Interop.csproj">
<Project>{4A864586-93C5-4DC1-8A80-F094A88506D7}</Project>
<Name>Mono.VisualC.Interop</Name>
</ProjectReference>
</ItemGroup>
</Project>
Loading…
Cancel
Save