Browse Source

Generator: add support for enums and namespaces

pull/1/head
Alexander Corrado 14 years ago
parent
commit
588165294d
  1. 28
      src/generator/Class.cs
  2. 21
      src/generator/Enumeration.cs
  3. 2
      src/generator/Filter.cs
  4. 277
      src/generator/Generator.cs
  5. 33
      src/generator/Lib.cs
  6. 4
      src/generator/Makefile.am
  7. 4
      src/generator/Method.cs
  8. 37
      src/generator/Namespace.cs
  9. 28
      src/generator/Templates/BaseMembers.cs
  10. 430
      src/generator/Templates/CSharp/CSharpClass.cs
  11. 60
      src/generator/Templates/CSharp/CSharpClass.tt
  12. 184
      src/generator/Templates/CSharp/CSharpEnum.cs
  13. 28
      src/generator/Templates/CSharp/CSharpEnum.tt
  14. 2
      src/generator/Templates/CSharp/CSharpLanguage.cs
  15. 40
      src/generator/Templates/CSharp/CSharpLibs.cs
  16. 12
      src/generator/Templates/CSharp/CSharpLibs.tt
  17. 18
      src/generator/generator.csproj

28
src/generator/Class.cs

@ -30,31 +30,28 @@ @@ -30,31 +30,28 @@
using System;
using System.Collections.Generic;
public class Class {
public class Class : Namespace {
public Class (Node n) {
Node = n;
public Class (Node n)
: base (n)
{
BaseClasses = new List<Class> ();
Methods = new List<Method> ();
Fields = new List<Field> ();
Properties = new List<Property> ();
Methods = new List<Method> ();
NestedClasses = new List<Class> ();
NestedEnums = new List<Enumeration> ();
}
public Node Node {
public List<Class> BaseClasses {
get; set;
}
public string Name {
get {
return Node.Name;
}
}
public List<Class> BaseClasses {
public List<Class> NestedClasses {
get; set;
}
public List<Method> Methods {
public List<Enumeration> NestedEnums {
get; set;
}
@ -66,6 +63,11 @@ public class Class { @@ -66,6 +63,11 @@ public class Class {
get; set;
}
public List<Method> Methods {
get;
set;
}
public bool Disable {
get; set;
}

21
src/generator/Enumeration.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
public class Enumeration : Namespace {
public struct Item {
public string Name;
public int Value;
}
public Enumeration (Node n)
: base (n)
{
this.Items = new List<Item> ();
}
public List<Item> Items {
get; set;
}
}

2
src/generator/Filter.cs

@ -28,7 +28,7 @@ public struct Filter { @@ -28,7 +28,7 @@ public struct Filter {
var rules = from rule in doc.Root.Elements ()
let mode = (FilterMode)Enum.Parse (typeof (FilterMode), rule.Name.LocalName)
let impl = (value = (string)rule.Attribute ("implementation")) != null ? (ImplementationType)Enum.Parse (typeof (ImplementationType), value) : ImplementationType.@class
select new Filter { TypeName = rule.Value, Mode = mode, ImplType = impl };
select new Filter { TypeName = rule.Value, Mode = mode, ImplType = impl };
return rules.ToDictionary<Filter,string> (r => r.TypeName);

277
src/generator/Generator.cs

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
using System;
using System.IO;
using System.Diagnostics;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Linq;
@ -18,24 +19,24 @@ using Mono.Cxxi; @@ -18,24 +19,24 @@ using Mono.Cxxi;
public class Generator {
// Command line arguments
public string OutputDir { get; set; }
public string Namespace { get; set; }
public string LibBaseName { get; set; }
public string InputFileName { get; set; }
public string OutputDir { get; set; }
public string FilterFile { get; set; }
public InlineMethods InlinePolicy { get; set; }
// In the future we might support more than one of these at once...
public Lib Lib { get; set; }
// Classes to generate code for
public List<Class> Classes { get; set; }
public Dictionary<Node, Class> NodeToClass { get; set; }
public Dictionary<Node, Namespace> NodeToNamespace { get; set; }
private FilterMode default_filter_mode;
public FilterMode DefaultFilterMode { get { return default_filter_mode; } set { default_filter_mode = value; } }
public Dictionary<string, Filter> Filters { get; set; }
// Code templates
public ITemplate Libs { get; set; }
public ITemplate Class { get; set; }
public LibsBase LibsTemplate { get; set; }
public ClassBase ClassTemplate { get; set; }
public EnumBase EnumTemplate { get; set; }
public static int Main (String[] args) {
var generator = new Generator ();
@ -44,6 +45,9 @@ public class Generator { @@ -44,6 +45,9 @@ public class Generator {
}
void Run (String[] args) {
Lib = new Lib ();
NodeToNamespace = new Dictionary<Node, Namespace> ();
if (ParseArguments (args) != 0) {
Environment.Exit (1);
}
@ -53,9 +57,9 @@ public class Generator { @@ -53,9 +57,9 @@ public class Generator {
if (FilterFile != null)
Filters = Filter.Load (XDocument.Load (FilterFile), out default_filter_mode);
CreateClasses (root);
CreateTypes (root);
CreateMethods ();
CreateMembers ();
GenerateCode ();
}
@ -66,10 +70,10 @@ public class Generator { @@ -66,10 +70,10 @@ public class Generator {
var p = new OptionSet {
{ "h|?|help", "Show this help message", v => help = v != null },
{ "o=|out=", "Set the output directory", v => OutputDir = v },
{ "ns=|namespace=", "Set the namespace of the generated code", v => Namespace = v },
{ "lib=", "The base name of the C++ library, i.e. 'qt' for libqt.so", v =>LibBaseName = v },
{ "ns=|namespace=", "Set the namespace of the generated code", v => Lib.BaseNamespace = v },
{ "lib=", "The base name of the C++ library, i.e. 'qt' for libqt.so", v =>Lib.BaseName = v },
{ "filters=", "A file containing filter directives for filtering classes", v => FilterFile = v },
{ "inline=", "Inline methods in lib are: notpresent (default), present, surrogatelib (present in %lib%-inline)", v => InlinePolicy = (InlineMethods)Enum.Parse (typeof (InlineMethods), v, true) }
{ "inline=", "Inline methods in lib are: notpresent (default), present, surrogatelib (present in %lib%-inline)", v => Lib.InlinePolicy = (InlineMethods)Enum.Parse (typeof (InlineMethods), v, true) }
};
try {
@ -90,16 +94,21 @@ public class Generator { @@ -90,16 +94,21 @@ public class Generator {
}
// Code templates
Libs = new CSharpLibs ();
Class = new CSharpClass ();
LibsTemplate = new CSharpLibs ();
ClassTemplate = new CSharpClass ();
EnumTemplate = new CSharpEnum ();
InputFileName = args [0];
if (LibBaseName == null) {
if (Lib.BaseName == null) {
Console.WriteLine ("The --lib= option is required.");
return 1;
}
if (Lib.BaseNamespace == null) {
Lib.BaseNamespace = Path.GetFileNameWithoutExtension (Lib.BaseName);
}
if (OutputDir == null)
OutputDir = "output";
@ -151,44 +160,104 @@ public class Generator { @@ -151,44 +160,104 @@ public class Generator {
return root;
}
void CreateClasses (Node root) {
List<Node> classNodes = root.Children.Where (o =>
(o.Type == "Class" ||
o.Type == "Struct") &&
!(o.IsTrue ("incomplete") ||
!o.HasValue ("name")
)).ToList ();
void CreateTypes (Node root) {
foreach (Node n in root.Children) {
if (n.IsTrue ("incomplete") || !n.HasValue ("name") || n.Attributes ["name"] == "::")
continue;
List<Class> classes = new List<Class> ();
NodeToClass = new Dictionary <Node, Class> ();
Namespace ns;
switch (n.Type) {
foreach (Node n in classNodes) {
var filter = GetFilterOrDefault (n.Name);
if (filter.Mode == FilterMode.Exclude)
case "Class":
case "Struct":
ns = new Class (n);
break;
case "Enumeration":
ns = new Enumeration (n);
break;
case "Namespace":
ns = new Namespace (n);
break;
default:
continue;
var klass = new Class (n);
NodeToClass [n] = klass;
}
if (filter.Mode != FilterMode.External)
classes.Add (klass);
NodeToNamespace [n] = ns;
Lib.Namespaces.Add (ns);
}
// Compute bases
foreach (Class klass in classes) {
for (var i = 0; i < Lib.Namespaces.Count; i++) {
Namespace ns = Lib.Namespaces [i];
SetParentNamespace (ns);
var filter = GetFilterOrDefault (ns);
if (filter.Mode == FilterMode.Exclude)
NodeToNamespace.Remove (ns.Node);
if (filter.Mode != FilterMode.Include) {
Lib.Namespaces.RemoveAt (i);
i--;
continue;
}
var klass = ns as Class;
if (klass == null)
continue;
// Compute bases
foreach (Node bn in klass.Node.Children.Where (o => o.Type == "Base")) {
Class baseClass = NodeToClass [bn.NodeForAttr ("type")];
Class baseClass = NodeToNamespace [bn.NodeForAttr ("type")] as Class;
Debug.Assert (baseClass != null);
klass.BaseClasses.Add (baseClass);
}
}
}
Classes = classes;
void SetParentNamespace (Namespace ns)
{
Namespace parent = null;
if (ns.Node.HasValue ("context") && NodeToNamespace.TryGetValue (Node.IdToNode [ns.Node.Attributes ["context"]], out parent))
{
SetParentNamespace (parent);
ns.ParentNamespace = parent;
}
}
void CreateMethods () {
foreach (Class klass in Classes) {
if (!klass.Node.HasValue ("members"))
void CreateMembers () {
foreach (var ns in Lib.Namespaces) {
var parentClass = ns.ParentNamespace as Class;
var @enum = ns as Enumeration;
if (@enum != null) {
if (parentClass != null)
parentClass.NestedEnums.Add (@enum);
foreach (var enumValue in @enum.Node.Children.Where (o => o.Type == "EnumValue")) {
int val;
var item = new Enumeration.Item { Name = enumValue.Attributes ["name"] };
if (enumValue.HasValue ("init") && int.TryParse (enumValue.Attributes ["init"], out val))
item.Value = val;
@enum.Items.Add (item);
}
continue;
}
var klass = ns as Class;
if (klass == null || !klass.Node.HasValue ("members"))
continue;
if (parentClass != null)
parentClass.NestedClasses.Add (klass);
int fieldCount = 0;
foreach (Node n in klass.Node ["members"].Split (new[] {' '}, StringSplitOptions.RemoveEmptyEntries).Select (id => Node.IdToNode [id])) {
@ -198,7 +267,7 @@ public class Generator { @@ -198,7 +267,7 @@ public class Generator {
switch (n.Type) {
case "Field":
CppType fieldType = GetType (GetTypeNode (n));
var fieldType = GetType (GetTypeNode (n));
if (fieldType.ElementType == CppTypes.Unknown && fieldType.ElementTypeName == null)
fieldType = new CppType (CppTypes.Void, CppModifiers.Pointer);
@ -210,6 +279,7 @@ public class Generator { @@ -210,6 +279,7 @@ public class Generator {
klass.Fields.Add (new Field (fieldName, fieldType, (Access)Enum.Parse (typeof (Access), n ["access"])));
break;
case "Constructor":
ctor = true;
break;
@ -222,20 +292,21 @@ public class Generator { @@ -222,20 +292,21 @@ public class Generator {
continue;
}
if (n.Name == "timerEvent")
Console.WriteLine ("foo");
if ((!dtor && n.HasValue ("overrides") && CheckPrimaryBases (klass, b => b.Node.CheckValueList ("members", n.Attributes ["overrides"]))) || // excl. virtual methods from primary base (except dtor)
(!n.IsTrue ("extern") && !n.IsTrue ("inline")))
continue;
if (!n.CheckValue ("access", "public")) // exclude non-public methods
skip = true;
if (n.IsTrue ("inline") && InlinePolicy == InlineMethods.NotPresent)
if (n.IsTrue ("inline") && Lib.InlinePolicy == InlineMethods.NotPresent)
skip = true;
string name = dtor ? "Destruct" : n.Name;
var method = new Method (n) {
Name = name,
Access = (Access)Enum.Parse (typeof (Access), n.Attributes ["access"]),
IsVirtual = n.IsTrue ("virtual"),
IsStatic = n.IsTrue ("static"),
IsConst = n.IsTrue ("const"),
@ -245,6 +316,9 @@ public class Generator { @@ -245,6 +316,9 @@ public class Generator {
IsDestructor = dtor
};
if (method.Access == Access.@private)
skip = true;
if (dtor || method.IsArtificial)
method.GenWrapperMethod = false;
@ -266,7 +340,7 @@ public class Generator { @@ -266,7 +340,7 @@ public class Generator {
method.ReturnType = retType;
int c = 0;
List<CppType> argTypes = new List<CppType> ();
var argTypes = new List<CppType> ();
foreach (Node arg in n.Children.Where (o => o.Type == "Argument")) {
string argname;
if (arg.Name == null || arg.Name == "")
@ -274,7 +348,7 @@ public class Generator { @@ -274,7 +348,7 @@ public class Generator {
else
argname = arg.Name;
CppType argtype = GetType (GetTypeNode (arg));
var argtype = GetType (GetTypeNode (arg));
if (argtype.ElementType == CppTypes.Unknown) {
//Console.WriteLine ("Skipping method " + klass.Name + "::" + member.Name + " () because it has an argument with unknown type '" + TypeNodeToString (arg) + "'.");
argtype = new CppType (CppTypes.Void, CppModifiers.Pointer);
@ -306,8 +380,8 @@ public class Generator { @@ -306,8 +380,8 @@ public class Generator {
klass.Methods.Add (method);
}
foreach (Method method in klass.Methods) {
if (AddAsQtProperty (klass, method))
foreach (var method in klass.Methods) {
if (AddAsProperty (klass, method))
method.GenWrapperMethod = false;
}
@ -321,9 +395,8 @@ public class Generator { @@ -321,9 +395,8 @@ public class Generator {
//
// Property support
// This is QT specific
//
bool AddAsQtProperty (Class klass, Method method) {
bool AddAsProperty (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 () &&
@ -393,6 +466,8 @@ public class Generator { @@ -393,6 +466,8 @@ public class Generator {
}
CppType GetType (Node n, CppType modifiers) {
var fundamental = CppTypes.Unknown;
switch (n.Type) {
case "Typedef":
return GetType (GetTypeNode (n), modifiers);
@ -410,15 +485,24 @@ public class Generator { @@ -410,15 +485,24 @@ public class Generator {
else
throw new NotImplementedException ();
case "Class":
fundamental = CppTypes.Class;
break;
case "Struct":
if (!NodeToClass.ContainsKey (n)) {
// FIXME: Do something better
return CppTypes.Unknown;
}
return modifiers.CopyTypeFrom (new CppType (n.Type == "Class"? CppTypes.Class : CppTypes.Struct, NodeToClass [n].Name));
fundamental = CppTypes.Struct;
break;
case "Enumeration":
fundamental = CppTypes.Enum;
break;
default:
return CppTypes.Unknown;
}
if (!NodeToNamespace.ContainsKey (n)) {
// FIXME: Do something better
return CppTypes.Unknown;
}
return modifiers.CopyTypeFrom (new CppType (fundamental, NodeToNamespace [n].FullyQualifiedName));
}
Node GetTypeNode (Node n) {
@ -438,13 +522,15 @@ public class Generator { @@ -438,13 +522,15 @@ public class Generator {
case CppTypes.Class:
case CppTypes.Struct:
// FIXME: Full name
case CppTypes.Enum:
var filter = GetFilterOrDefault (t.ElementTypeName);
if (filter.ImplType == ImplementationType.@struct)
return t.ElementTypeName + "&";
var filter = GetFilterOrDefault (t);
var qname = filter.TypeName.Replace ("::", ".");
if (filter.ImplType == ImplementationType.@struct && !IsByVal (t))
return qname + "&";
else
return t.ElementTypeName;
return qname;
}
@ -456,30 +542,77 @@ public class Generator { @@ -456,30 +542,77 @@ public class Generator {
// Generate Libs file
using (TextWriter w = File.CreateText (Path.Combine (OutputDir, "Libs.cs"))) {
Libs.Generator = this;
w.Write (Libs.TransformText ());
LibsTemplate.Generator = this;
LibsTemplate.Libs = new[] { Lib };
w.Write (LibsTemplate.TransformText ());
}
// Generate user classes
foreach (Class klass in Classes) {
if (klass.Disable)
// Generate user types
foreach (Namespace ns in Lib.Namespaces) {
if (ns.ParentNamespace is Class)
continue;
using (TextWriter w = File.CreateText (Path.Combine (OutputDir, klass.Name + ".cs"))) {
Class.Generator = this;
Class.Class = klass;
w.Write (Class.TransformText ());
var klass = ns as Class;
if (klass != null) {
if (klass.Disable)
continue;
using (TextWriter w = File.CreateText (Path.Combine (OutputDir, klass.Name + ".cs"))) {
ClassTemplate.Generator = this;
ClassTemplate.Class = klass;
ClassTemplate.Nested = false;
w.Write (ClassTemplate.TransformText ());
}
continue;
}
var @enum = ns as Enumeration;
if (@enum != null) {
using (TextWriter w = File.CreateText (Path.Combine (OutputDir, @enum.Name + ".cs"))) {
EnumTemplate.Generator = this;
EnumTemplate.Enum = @enum;
EnumTemplate.Nested = false;
w.Write (EnumTemplate.TransformText ());
}
continue;
}
}
}
Filter GetFilterOrDefault (string typeName)
static public bool IsByVal (CppType t)
{
return ((t.ElementType == CppTypes.Class || t.ElementType == CppTypes.Struct) &&
!t.Modifiers.Contains (CppModifiers.Pointer) &&
!t.Modifiers.Contains (CppModifiers.Reference) &&
!t.Modifiers.Contains (CppModifiers.Array));
}
Filter GetFilterOrDefault (Namespace ns)
{
return GetFilterOrDefault (ns.FullyQualifiedName);
}
Filter GetFilterOrDefault (CppType cpptype)
{
var fqn = cpptype.ElementTypeName;
if (cpptype.Namespaces != null)
fqn = string.Join ("::", cpptype.Namespaces) + "::" + fqn;
var newtype = new CppType (fqn, cpptype.Modifiers.Where (m => m == CppModifiers.Template));
return GetFilterOrDefault (newtype.ToString ().Replace (" ", ""));
}
Filter GetFilterOrDefault (string fqn)
{
Filter result;
if (Filters != null && Filters.TryGetValue (typeName, out result))
if (Filters != null && Filters.TryGetValue (fqn, out result))
return result;
return new Filter { TypeName = typeName, Mode = default_filter_mode };
return new Filter { TypeName = fqn, Mode = default_filter_mode };
}
}

33
src/generator/Lib.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using Mono.Cxxi;
public class Lib {
public Lib ()
{
Namespaces = new List<Namespace> ();
}
public string BaseName {
get;
set;
}
public InlineMethods InlinePolicy {
get;
set;
}
public string BaseNamespace {
get;
set;
}
public IList<Namespace> Namespaces {
get;
set;
}
}

4
src/generator/Makefile.am

@ -50,10 +50,13 @@ all: $(ASSEMBLY) $(PROGRAMFILES) $(BINARIES) @@ -50,10 +50,13 @@ all: $(ASSEMBLY) $(PROGRAMFILES) $(BINARIES)
FILES = \
Access.cs \
Class.cs \
Enumeration.cs \
Field.cs \
Filter.cs \
Generator.cs \
Lib.cs \
Method.cs \
Namespace.cs \
Node.cs \
Options.cs \
Parameter.cs \
@ -62,6 +65,7 @@ FILES = \ @@ -62,6 +65,7 @@ FILES = \
Templates/BaseMembers.cs \
Templates/Context.cs \
Templates/CSharp/CSharpClass.cs \
Templates/CSharp/CSharpEnum.cs \
Templates/CSharp/CSharpLanguage.cs \
Templates/CSharp/CSharpLibs.cs

4
src/generator/Method.cs

@ -44,6 +44,10 @@ public class Method { @@ -44,6 +44,10 @@ public class Method {
get; set;
}
public Access Access {
get; set;
}
public string Name {
get; set;
}

37
src/generator/Namespace.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
public class Namespace {
public Namespace (string name)
{
this.Name = name;
}
public Namespace (Node node)
: this (node.Name)
{
this.Node = node;
}
public Node Node {
get; set;
}
// Back ref to enclosing namespace (may be null)
public Namespace ParentNamespace {
get; set;
}
public string Name {
get; set;
}
public string FullyQualifiedName {
get {
return ParentNamespace != null? ParentNamespace.FullyQualifiedName + "::" + Name : Name;
}
}
}

28
src/generator/Templates/BaseMembers.cs

@ -1,16 +1,36 @@ @@ -1,16 +1,36 @@
using System;
using System.Collections.Generic;
namespace Templates {
public interface ITemplate {
public interface ITemplate<T> {
Generator Generator { get; set; }
Class Class { get; set; }
T Current { get; set; }
bool Nested { get; set; }
string TransformText ();
}
public partial class Base : ITemplate {
public partial class LibsBase : Base, ITemplate<ICollection<Lib>> {
public Generator Generator { get; set; }
public Class Class { get; set; }
public ICollection<Lib> Current { get; set; }
public bool Nested { get; set; }
public ICollection<Lib> Libs { get { return Current; } set { Current = value; } }
}
public partial class ClassBase : Base, ITemplate<Class> {
public Generator Generator { get; set; }
public Class Current { get; set; }
public bool Nested { get; set; }
public Class Class { get { return Current; } set { Current = value; } }
}
public partial class EnumBase : Base, ITemplate<Enumeration> {
public Generator Generator { get; set; }
public Enumeration Current { get; set; }
public bool Nested { get; set; }
public Enumeration Enum { get { return Current; } set { Current = value; } }
}
}

430
src/generator/Templates/CSharp/CSharpClass.cs

File diff suppressed because it is too large Load Diff

60
src/generator/Templates/CSharp/CSharpClass.tt

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
<#@ template language="C#" inherits="Base" #>
<#@ template language="C#" inherits="ClassBase" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
@ -11,6 +11,9 @@ @@ -11,6 +11,9 @@
var layoutClass = (hasBase? "\t: base (impl.TypeInfo)\n\t\t{" : "{") + "\n\t\t\t__cxxi_LayoutClass ();";
var overrideInitBases = Generator.CheckPrimaryBases (Class, c => c.BaseClasses.Count > 1);
var initBases = ((overrideInitBases || Class.BaseClasses.Count > 1) ? "\t__cxxi_InitBases ();\n\t\t}" : "}");
var @namespace = Generator.Lib.BaseNamespace + (Class.ParentNamespace != null? "." + Class.ParentNamespace.FullyQualifiedName : "");
if (!Nested) {
#>
// -------------------------------------------------------------------------
// Managed wrapper for <#= Class.Name #>
@ -22,11 +25,11 @@ @@ -22,11 +25,11 @@
using System;
using Mono.Cxxi;
namespace <#= Generator.Namespace #> {
namespace <#= @namespace #> {
<# } /* if !Nested */ #>
public partial class <#= wrapper #> : <#= GetBaseString () #> {
private static readonly <#= iface #> impl = Libs.<#= Generator.LibBaseName #>.GetClass<<#= iface + "," + layout + "," + wrapper #>> ("<#= Class.Name #>");
private static readonly <#= iface #> impl = Libs.<#= Generator.Lib.BaseName #>.GetClass<<#= iface + "," + layout + "," + wrapper #>> ("<#= Class.Name #>");
<# if (!hasBase) { #>
public CppInstancePtr Native { get; protected set; }
<# } #>
@ -46,7 +49,7 @@ namespace <#= Generator.Namespace #> { @@ -46,7 +49,7 @@ namespace <#= Generator.Namespace #> {
if (method.IsDestructor) Write ("[Destructor] ");
if (method.IsCopyCtor) Write ("[CopyConstructor] ");
if (IsByVal (method.ReturnType)) {
if (Generator.IsByVal (method.ReturnType)) {
Write ("[return: ByVal] ");
}
if (method.IsConstructor)
@ -69,7 +72,7 @@ namespace <#= Generator.Namespace #> { @@ -69,7 +72,7 @@ namespace <#= Generator.Namespace #> {
foreach (var field in Class.Fields.Where (f => f.Access != Access.@private)) {
WriteLine ("CppField<{0}> {1} {{ get; }}", CSharpLanguage.TypeName (Generator.CppTypeToManaged (field.Type), Context.Generic), CSharpLanguage.SafeIdentifier (field.Name));
}
ClearIndent (); #>
PopIndent (); #>
}
<# /* Native layout */ #>
private struct <#= layout #> {
@ -90,7 +93,29 @@ namespace <#= Generator.Namespace #> { @@ -90,7 +93,29 @@ namespace <#= Generator.Namespace #> {
impl.<#= fieldName #> [Native] = value;
}
}
<# } ClearIndent(); #>
<# } PopIndent(); #>
<# /* Nested classes */ #>
<# foreach (var klass in Class.NestedClasses) {
var oldClass = this.Class;
var wasNested = this.Nested;
this.Class = klass;
this.Nested = true;
Write (this.TransformText ());
this.Class = oldClass;
this.Nested = wasNested;
} #>
<# /* Nested enums */ #>
<# foreach (var @enum in Class.NestedEnums) {
Generator.EnumTemplate.Generator = Generator;
Generator.EnumTemplate.Enum = @enum;
Generator.EnumTemplate.Nested = true;
Write (Generator.EnumTemplate.TransformText ());
} #>
<# /* Subclass constructor */ #>
public <#= wrapper #> (CppTypeInfo subClass)
@ -132,7 +157,7 @@ namespace <#= Generator.Namespace #> { @@ -132,7 +157,7 @@ namespace <#= Generator.Namespace #> {
else
WriteLine ("}");
}
ClearIndent (); #>
PopIndent (); #>
<# /* Wrapper properties */ #>
<# PushIndent ("\t\t");
@ -178,7 +203,7 @@ namespace <#= Generator.Namespace #> { @@ -178,7 +203,7 @@ namespace <#= Generator.Namespace #> {
PopIndent ();
WriteLine ("}\n");
}
ClearIndent (); #>
PopIndent (); #>
partial void BeforeDestruct ();
partial void AfterDestruct ();
@ -238,7 +263,7 @@ foreach (var npBase in Class.BaseClasses.Skip (1)) { #> @@ -238,7 +263,7 @@ foreach (var npBase in Class.BaseClasses.Skip (1)) { #>
PopIndent ();
Write (");\n{0}}}\n\n", CurrentIndent);
}
ClearIndent (); #>
PopIndent (); #>
}
private <#= wrapper #>__<#= npBase.Name #> __cxxi_<#= npBase.Name #>;
public <#= npBase.Name #> <#= npBase.Name #> { get { return __cxxi_<#= npBase.Name #>; } }
@ -269,7 +294,7 @@ foreach (var npBase in Class.BaseClasses.Skip (1)) { #> @@ -269,7 +294,7 @@ foreach (var npBase in Class.BaseClasses.Skip (1)) { #>
PopIndent ();
Write (");\n{0}}}\n\n", CurrentIndent);
}
ClearIndent ();
PopIndent ();
WriteLine ("#endregion");
}
@ -283,7 +308,9 @@ if (overrideInitBases || Class.BaseClasses.Count > 1) { #> @@ -283,7 +308,9 @@ if (overrideInitBases || Class.BaseClasses.Count > 1) { #>
}
<# } #>
}
<# if (!Nested) { #>
}
<# } #>
<#+
private void WriteMethodHeader (Method method, string layoutClass, bool isNonPrimaryOverride, bool @protected)
@ -293,7 +320,7 @@ private void WriteMethodHeader (Method method, string layoutClass, bool isNonPri @@ -293,7 +320,7 @@ private void WriteMethodHeader (Method method, string layoutClass, bool isNonPri
if (!isNonPrimaryOverride && method.IsVirtual)
WriteLine ("[OverrideNative (\"{0}\")]", method.Name);
Write (CurrentIndent + (@protected? "protected " : "public "));
Write (CurrentIndent + (@protected? "protected" : method.Access.ToString ()) + " ");
if (method.IsConstructor) {
Write (method.FormattedName);
} else {
@ -334,7 +361,7 @@ private void WriteParameters (IList<Parameter> parameters, bool writeType, bool @@ -334,7 +361,7 @@ private void WriteParameters (IList<Parameter> parameters, bool writeType, bool
var mangleAs = parameters [i].Type.ToString ();
if (mangleAs != "" && mangleAs != type)
Write ("[MangleAs (\"{0}\")] ", mangleAs);
if (IsByVal (parameters [i].Type))
if (Generator.IsByVal (parameters [i].Type))
Write ("[ByVal] ");
}
@ -363,11 +390,4 @@ private string GetBaseString () @@ -363,11 +390,4 @@ private string GetBaseString ()
return str;
}
private bool IsByVal (CppType t)
{
return ((t.ElementType == CppTypes.Class || t.ElementType == CppTypes.Struct) &&
!t.Modifiers.Contains (CppModifiers.Pointer) &&
!t.Modifiers.Contains (CppModifiers.Reference) &&
!t.Modifiers.Contains (CppModifiers.Array));
}
#>

184
src/generator/Templates/CSharp/CSharpEnum.cs

@ -0,0 +1,184 @@ @@ -0,0 +1,184 @@
// ------------------------------------------------------------------------------
// <autogenerated>
// This code was generated by a tool.
// Mono Runtime Version: 4.0.30319.1
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </autogenerated>
// ------------------------------------------------------------------------------
namespace Templates {
using System.IO;
using System.Linq;
using System.Collections.Generic;
using Mono.Cxxi;
using System;
public partial class CSharpEnum : EnumBase {
public override string TransformText() {
this.GenerationEnvironment = null;
#line 6 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
var @namespace = Generator.Lib.BaseNamespace + (Enum.ParentNamespace != null? "." + Enum.ParentNamespace.FullyQualifiedName : "");
if (!Nested) {
#line default
#line hidden
#line 11 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write("\n// -------------------------------------------------------------------------\n// Managed enum for ");
#line default
#line hidden
#line 13 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Enum.Name ));
#line default
#line hidden
#line 13 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write("\n// Generated from ");
#line default
#line hidden
#line 14 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Path.GetFileName (Generator.InputFileName) ));
#line default
#line hidden
#line 14 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(" on ");
#line default
#line hidden
#line 14 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( DateTime.Now ));
#line default
#line hidden
#line 14 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write("\n//\n// This file was auto generated. Do not edit.\n// -------------------------------------------------------------------------\n\nnamespace ");
#line default
#line hidden
#line 19 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( @namespace ));
#line default
#line hidden
#line 19 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(" {\n");
#line default
#line hidden
#line 20 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
} /* if !Nested */
#line default
#line hidden
#line 21 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write("\tpublic enum ");
#line default
#line hidden
#line 21 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Enum.Name ));
#line default
#line hidden
#line 21 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(" {\n");
#line default
#line hidden
#line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
foreach (var item in Enum.Items) {
#line default
#line hidden
#line 23 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write("\t\t");
#line default
#line hidden
#line 23 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( item.Name ));
#line default
#line hidden
#line 23 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(" = ");
#line default
#line hidden
#line 23 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( item.Value ));
#line default
#line hidden
#line 23 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write(",\n");
#line default
#line hidden
#line 24 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
}
#line default
#line hidden
#line 25 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write("\t}\n");
#line default
#line hidden
#line 26 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
if (!Nested) {
#line default
#line hidden
#line 27 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
this.Write("}\n");
#line default
#line hidden
#line 28 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpEnum.tt"
}
#line default
#line hidden
return this.GenerationEnvironment.ToString();
}
protected override void Initialize() {
base.Initialize();
}
}
}

28
src/generator/Templates/CSharp/CSharpEnum.tt

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
<#@ template language="C#" inherits="EnumBase" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="Mono.Cxxi" #>
<#
var @namespace = Generator.Lib.BaseNamespace + (Enum.ParentNamespace != null? "." + Enum.ParentNamespace.FullyQualifiedName : "");
if (!Nested) {
#>
// -------------------------------------------------------------------------
// Managed enum for <#= Enum.Name #>
// Generated from <#= Path.GetFileName (Generator.InputFileName) #> on <#= DateTime.Now #>
//
// This file was auto generated. Do not edit.
// -------------------------------------------------------------------------
namespace <#= @namespace #> {
<# } /* if !Nested */ #>
public enum <#= Enum.Name #> {
<# foreach (var item in Enum.Items) { #>
<#= item.Name #> = <#= item.Value #>,
<# } #>
}
<# if (!Nested) { #>
}
<# } #>

2
src/generator/Templates/CSharp/CSharpLanguage.cs

@ -1,4 +1,5 @@ @@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cxxi;
@ -24,6 +25,7 @@ namespace Templates { @@ -24,6 +25,7 @@ namespace Templates {
public static string SafeIdentifier (string proposedName)
{
proposedName = new string (((IEnumerable<char>)proposedName).Select (c => char.IsLetterOrDigit (c)? c : '_').ToArray ());
return keywords.Contains (proposedName)? "@" + proposedName : proposedName;
}

40
src/generator/Templates/CSharp/CSharpLibs.cs

@ -12,13 +12,13 @@ namespace Templates { @@ -12,13 +12,13 @@ namespace Templates {
using System;
public partial class CSharpLibs : Base {
public partial class CSharpLibs : LibsBase {
public override string TransformText() {
this.GenerationEnvironment = null;
#line 2 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write("// -------------------------------------------------------------------------\n// C++ libarary declarations\n// Generated on ");
this.Write("// -------------------------------------------------------------------------\n// C++ library declarations\n// Generated on ");
#line default
#line hidden
@ -36,19 +36,31 @@ namespace Templates { @@ -36,19 +36,31 @@ namespace Templates {
#line hidden
#line 12 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Generator.Namespace ));
this.Write(this.ToStringHelper.ToStringWithCulture( Generator.Lib.BaseNamespace ));
#line default
#line hidden
#line 12 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write(" {\n\n\tpublic static partial class Libs {\n\n\t\tpublic static readonly CppLibrary ");
this.Write(" {\n\n\tpublic static partial class Libs {\n");
#line default
#line hidden
#line 15 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
foreach (var lib in Libs) {
#line default
#line hidden
#line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write("\t\tpublic static readonly CppLibrary ");
#line default
#line hidden
#line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Generator.LibBaseName ));
this.Write(this.ToStringHelper.ToStringWithCulture( CSharpLanguage.SafeIdentifier (lib.BaseName) ));
#line default
#line hidden
@ -60,7 +72,7 @@ namespace Templates { @@ -60,7 +72,7 @@ namespace Templates {
#line hidden
#line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Generator.LibBaseName ));
this.Write(this.ToStringHelper.ToStringWithCulture( lib.BaseName ));
#line default
#line hidden
@ -72,13 +84,25 @@ namespace Templates { @@ -72,13 +84,25 @@ namespace Templates {
#line hidden
#line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write(this.ToStringHelper.ToStringWithCulture( Generator.InlinePolicy ));
this.Write(this.ToStringHelper.ToStringWithCulture( lib.InlinePolicy ));
#line default
#line hidden
#line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write(");\n\n\t}\n}\n");
this.Write(");\n");
#line default
#line hidden
#line 17 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
}
#line default
#line hidden
#line 18 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt"
this.Write("\t}\n}\n");
#line default
#line hidden

12
src/generator/Templates/CSharp/CSharpLibs.tt

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<#@ template language="C#" inherits="Base" #>
<#@ template language="C#" inherits="LibsBase" #>
// -------------------------------------------------------------------------
// C++ libarary declarations
// C++ library declarations
// Generated on <#= DateTime.Now #>
//
// This file was auto generated. Do not edit.
@ -9,11 +9,11 @@ @@ -9,11 +9,11 @@
using System;
using Mono.Cxxi;
namespace <#= Generator.Namespace #> {
namespace <#= Generator.Lib.BaseNamespace #> {
public static partial class Libs {
public static readonly CppLibrary <#= Generator.LibBaseName #> = new CppLibrary ("<#= Generator.LibBaseName #>", InlineMethods.<#= Generator.InlinePolicy #>);
<# foreach (var lib in Libs) { #>
public static readonly CppLibrary <#= CSharpLanguage.SafeIdentifier (lib.BaseName) #> = new CppLibrary ("<#= lib.BaseName #>", InlineMethods.<#= lib.InlinePolicy #>);
<# } #>
}
}

18
src/generator/generator.csproj

@ -72,6 +72,12 @@ @@ -72,6 +72,12 @@
<Compile Include="Templates\CSharp\CSharpLanguage.cs" />
<Compile Include="Templates\Context.cs" />
<Compile Include="Filter.cs" />
<Compile Include="Enumeration.cs" />
<Compile Include="Lib.cs" />
<Compile Include="Templates\CSharp\CSharpEnum.cs">
<DependentUpon>CSharpEnum.tt</DependentUpon>
</Compile>
<Compile Include="Namespace.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System">
@ -121,10 +127,6 @@ @@ -121,10 +127,6 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Templates\Base.tt">
<Generator>TextTemplatingFilePreprocessor</Generator>
<LastGenOutput>Base.cs</LastGenOutput>
</None>
<None Include="Templates\CSharp\CSharpClass.tt">
<Generator>TextTemplatingFilePreprocessor</Generator>
<LastGenOutput>CSharpClass.cs</LastGenOutput>
@ -133,6 +135,14 @@ @@ -133,6 +135,14 @@
<Generator>TextTemplatingFilePreprocessor</Generator>
<LastGenOutput>CSharpLibs.cs</LastGenOutput>
</None>
<None Include="Templates\Base.tt">
<Generator>TextTemplatingFilePreprocessor</Generator>
<LastGenOutput>Base.cs</LastGenOutput>
</None>
<None Include="Templates\CSharp\CSharpEnum.tt">
<Generator>TextTemplatingFilePreprocessor</Generator>
<LastGenOutput>CSharpEnum.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Templates\" />

Loading…
Cancel
Save