From 2ade762c7ec75f73bc3327ee83aa3152cca1034b Mon Sep 17 00:00:00 2001 From: Alex Corrado Date: Mon, 13 Jun 2011 05:13:07 -0400 Subject: [PATCH] Generator: rewrite to use T4 templates instead of CodeDom --- src/Mono.VisualC.Interop/Attributes.cs | 11 +- src/generator/Class.cs | 156 +--- src/generator/Field.cs | 4 +- src/generator/Generator.cs | 189 ++-- src/generator/Makefile.am | 6 +- src/generator/Method.cs | 154 +--- src/generator/Node.cs | 2 +- src/generator/Property.cs | 30 +- src/generator/Templates/Base.cs | 181 ++++ src/generator/Templates/Base.tt | 2 + src/generator/Templates/BaseMembers.cs | 16 + src/generator/Templates/CSharp/CSharpClass.cs | 828 ++++++++++++++++++ src/generator/Templates/CSharp/CSharpClass.tt | 318 +++++++ src/generator/Templates/CSharp/CSharpLibs.cs | 92 ++ src/generator/Templates/CSharp/CSharpLibs.tt | 19 + src/generator/generator.csproj | 40 +- 16 files changed, 1575 insertions(+), 473 deletions(-) create mode 100644 src/generator/Templates/Base.cs create mode 100644 src/generator/Templates/Base.tt create mode 100644 src/generator/Templates/BaseMembers.cs create mode 100644 src/generator/Templates/CSharp/CSharpClass.cs create mode 100644 src/generator/Templates/CSharp/CSharpClass.tt create mode 100644 src/generator/Templates/CSharp/CSharpLibs.cs create mode 100644 src/generator/Templates/CSharp/CSharpLibs.tt diff --git a/src/Mono.VisualC.Interop/Attributes.cs b/src/Mono.VisualC.Interop/Attributes.cs index 19058b5..7240d51 100644 --- a/src/Mono.VisualC.Interop/Attributes.cs +++ b/src/Mono.VisualC.Interop/Attributes.cs @@ -86,7 +86,16 @@ namespace Mono.VisualC.Interop { #region Wrapper method attributes [AttributeUsage (AttributeTargets.Method)] - public class OverrideNativeAttribute : Attribute {} + public class OverrideNativeAttribute : Attribute { + public string NativeMethod { get; set; } + public OverrideNativeAttribute () + { + } + public OverrideNativeAttribute (string nativeMethod) + { + this.NativeMethod = nativeMethod; + } + } #endregion } diff --git a/src/generator/Class.cs b/src/generator/Class.cs index b675b10..77f887e 100644 --- a/src/generator/Class.cs +++ b/src/generator/Class.cs @@ -28,14 +28,14 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System; +using System.Linq; using System.Collections.Generic; using System.Reflection; -using System.Linq; -using System.CodeDom; -using System.CodeDom.Compiler; -class Class -{ +using Templates; + +public class Class { + public Class (Node n) { Node = n; BaseClasses = new List (); @@ -74,150 +74,4 @@ class Class get; set; } - public CodeTypeDeclaration GenerateClass (Generator g, CodeTypeDeclaration libDecl, string libFieldName) { - var decl = new CodeTypeDeclaration (Name); - var hasBase = BaseClasses.Count > 0; - decl.IsPartial = true; - - if (hasBase) - decl.BaseTypes.Add (new CodeTypeReference (BaseClasses [0].Name)); - else - decl.BaseTypes.Add (new CodeTypeReference ("ICppObject")); - - var layout = new CodeTypeDeclaration ("_" + Name) { - IsStruct = true, - TypeAttributes = TypeAttributes.NotPublic - }; - decl.Members.Add (layout); - - foreach (var f in Fields) { - var field = new CodeMemberField { - Name = f.Name, - Type = g.CppTypeToCodeDomType (f.Type), - Attributes = MemberAttributes.Public - }; - layout.Members.Add (field); - } - - var iface = new CodeTypeDeclaration ("I" + Name); - iface.IsInterface = true; - iface.BaseTypes.Add (new CodeTypeReference ("ICppClassOverridable", new CodeTypeReference [] { new CodeTypeReference (decl.Name) })); - decl.Members.Add (iface); - - var implField = new CodeMemberField (new CodeTypeReference (iface.Name), "impl") { - Attributes = MemberAttributes.Private | MemberAttributes.Static - }; - var getclass = new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (libDecl.Name), libFieldName), "GetClass", new CodeTypeReference [] { new CodeTypeReference (iface.Name), new CodeTypeReference (layout.Name), new CodeTypeReference (decl.Name) }); - implField.InitExpression = new CodeMethodInvokeExpression (getclass, new CodeExpression [] { new CodePrimitiveExpression (Name) }); - decl.Members.Add (implField); - //private static IClass impl = global::CppTests.Libs.Test.GetClass ("Class"); - - if (!hasBase) { - var ptrField = new CodeMemberField (new CodeTypeReference ("CppInstancePtr"), "native_ptr") { - Attributes = MemberAttributes.Family - }; - decl.Members.Add (ptrField); - } - - var implTypeInfo = new CodeFieldReferenceExpression (new CodeFieldReferenceExpression { FieldName = "impl" }, "TypeInfo"); - CodeStatement [] initNonPrimaryBases = null; - if (BaseClasses.Count > 1) { - initNonPrimaryBases = new CodeStatement [BaseClasses.Count - 1]; - for (var i = 1; i <= initNonPrimaryBases.Length; i++) { - initNonPrimaryBases [i - 1] = new CodeExpressionStatement (new CodeObjectCreateExpression (BaseClasses [i].Name, implTypeInfo)); - } - } - - var nativeCtor = new CodeConstructor () { - Attributes = MemberAttributes.Public - }; - if (hasBase) { - nativeCtor.BaseConstructorArgs.Add (implTypeInfo); - if (initNonPrimaryBases != null) - nativeCtor.Statements.AddRange (initNonPrimaryBases); - } - nativeCtor.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("CppInstancePtr"), "native")); - nativeCtor.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "native_ptr"), new CodeArgumentReferenceExpression ("native"))); - decl.Members.Add (nativeCtor); - - var subclassCtor = new CodeConstructor () { - Attributes = MemberAttributes.Public - }; - if (hasBase) { - subclassCtor.BaseConstructorArgs.Add (implTypeInfo); - if (initNonPrimaryBases != null) - subclassCtor.Statements.AddRange (initNonPrimaryBases); - } - subclassCtor.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("CppTypeInfo"), "subClass")); - subclassCtor.Statements.Add (new CodeExpressionStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeArgumentReferenceExpression ("subClass"), "AddBase"), new CodeExpression [] { new CodeFieldReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), "TypeInfo") }))); - decl.Members.Add (subclassCtor); - - if (!hasBase) { - var nativeProperty = new CodeMemberProperty () { - Name = "Native", - Type = new CodeTypeReference ("CppInstancePtr"), - Attributes = MemberAttributes.Public|MemberAttributes.Final - }; - nativeProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), "native_ptr"))); - decl.Members.Add (nativeProperty); - } - - var disposeMethod = new CodeMemberMethod () { - Name = "Dispose", - Attributes = MemberAttributes.Public - }; - if (hasBase) - disposeMethod.Attributes |= MemberAttributes.Override; - if (Methods.Any (m => m.IsDestructor)) - disposeMethod.Statements.Add (new CodeExpressionStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), "Destruct"), new CodeExpression [] { new CodeFieldReferenceExpression (null, "Native") }))); - disposeMethod.Statements.Add (new CodeExpressionStatement (new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "Native"), "Dispose")))); - decl.Members.Add (disposeMethod); - - foreach (Method m in Methods) { - iface.Members.Add (m.GenerateIFaceMethod (g)); - - if (m.GenWrapperMethod) { - var cm = m.GenerateWrapperMethod (g); - if (m.IsConstructor && hasBase) { - (cm as CodeConstructor).BaseConstructorArgs.Add (implTypeInfo); - if (initNonPrimaryBases != null) { - foreach (var init in initNonPrimaryBases.Reverse ()) - cm.Statements.Insert (0, init); - } - } - decl.Members.Add (cm); - } - } - - // Add all members inherited from non-primary bases - // With the exception of virtual methods that have been overridden, these methods must be called - // thru a cast to the base class that performs a this ptr adjustment - foreach (var baseClass in BaseClasses.Skip (1)) { - foreach (var method in baseClass.Methods) { - if (method.IsConstructor || (method.IsVirtual && Methods.Any (m => m.Node.CheckValue ("overrides", method.Node.Id)))) - continue; - - if (method.GenWrapperMethod) - decl.Members.Add (method.GenerateInheritedWrapperMethod (g, baseClass)); - } - foreach (var prop in baseClass.Properties) { - decl.Members.Add (prop.GenerateInheritedProperty (g, baseClass)); - } - - // generate implicit cast to base class - // 1. Create field to cache base casts - decl.Members.Add (new CodeMemberField (baseClass.Name, baseClass.Name + "_base")); - - // 2. Add op_Implicit - // FIXME: Can't figure out language-neutral way to do this with codedom.. C# only for now - decl.Members.Add (new CodeSnippetTypeMember (string.Format ("public static implicit operator {0}({1} subClass) {{\n\t\t\tif (subClass.{2} == null)\n\t\t\t\tsubClass.{2} = impl.TypeInfo.Cast<{0}>(subClass);\n\t\t\treturn subClass.{2};\n\t\t}}\n\t\t", baseClass.Name, Name, baseClass.Name + "_base"))); - - } - - foreach (Property p in Properties) { - decl.Members.Add (p.GenerateProperty (g)); - } - - return decl; - } } diff --git a/src/generator/Field.cs b/src/generator/Field.cs index 9955e0e..4792a37 100644 --- a/src/generator/Field.cs +++ b/src/generator/Field.cs @@ -34,8 +34,8 @@ using System.CodeDom.Compiler; using Mono.VisualC.Interop; -class Field -{ +public class Field { + public Field (string name, CppType type) { Name = name; Type = type; diff --git a/src/generator/Generator.cs b/src/generator/Generator.cs index fbbeb0f..60eedeb 100644 --- a/src/generator/Generator.cs +++ b/src/generator/Generator.cs @@ -9,29 +9,29 @@ using System.Collections.Generic; using System.Xml; using System.Linq; using System.Reflection; -using System.CodeDom; -using System.CodeDom.Compiler; -using Microsoft.CSharp; +using Templates; using NDesk.Options; - using Mono.VisualC.Interop; -public class Generator -{ - // Command line arguments - string OutputDir; - string Namespace; - string LibBaseName; - string InputFileName; - string FilterFile; - InlineMethods InlinePolicy; +public class Generator { - CodeDomProvider Provider; - CodeGeneratorOptions CodeGenOptions; + // 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 FilterFile { get; set; } + public InlineMethods InlinePolicy { get; set; } // Classes to generate code for - Dictionary Filters; + public List Classes { get; set; } + public Dictionary NodeToClass { get; set; } + public Dictionary Filters { get; set; } + + // Code templates + public ITemplate Libs { get; set; } + public ITemplate Class { get; set; } public static int Main (String[] args) { var generator = new Generator (); @@ -39,6 +39,23 @@ public class Generator return 0; } + void Run (String[] args) { + if (ParseArguments (args) != 0) { + Environment.Exit (1); + } + + Node root = LoadXml (InputFileName); + + if (FilterFile != null) + LoadFilters (FilterFile); + + CreateClasses (root); + + CreateMethods (); + + GenerateCode (); + } + int ParseArguments (String[] args) { bool help = false; @@ -68,6 +85,10 @@ public class Generator return 1; } + // Code templates + Libs = new CSharpLibs (); + Class = new CSharpClass (); + InputFileName = args [0]; if (LibBaseName == null) { @@ -81,23 +102,6 @@ public class Generator return 0; } - void Run (String[] args) { - if (ParseArguments (args) != 0) { - Environment.Exit (1); - } - - Node root = LoadXml (InputFileName); - - if (FilterFile != null) - LoadFilters (FilterFile); - - CreateClasses (root); - - CreateMethods (); - - GenerateCode (); - } - Node LoadXml (string file) { XmlReader reader = XmlReader.Create (file, new XmlReaderSettings ()); @@ -150,9 +154,6 @@ public class Generator } } - List Classes; - Dictionary NodeToClass; - void CreateClasses (Node root) { List classNodes = root.Children.Where (o => o.Type == "Class" || o.Type == "Struct").ToList (); classNodes.RemoveAll (o => o.IsTrue ("incomplete") || !o.HasValue ("name")); @@ -207,9 +208,7 @@ public class Generator fieldName = n.Name; else fieldName = "field" + fieldCount++; - if (CppTypeToCodeDomType (fieldType) == null) - // FIXME: Assume IntPtr - fieldType = ((CppType)CppTypes.Void).Modify (CppModifiers.Pointer); + klass.Fields.Add (new Field (fieldName, fieldType)); break; case "Constructor": @@ -254,7 +253,7 @@ public class Generator retType = CppTypes.Void; if (retType.ElementType == CppTypes.Unknown) skip = true; - if (CppTypeToCodeDomType (retType) == null) { + if (CppTypeToManaged (retType) == null) { //Console.WriteLine ("\t\tS: " + retType); skip = true; } @@ -276,7 +275,7 @@ public class Generator skip = true; } - if (CppTypeToCodeDomType (argtype) == null) { + if (CppTypeToManaged (argtype) == null) { //Console.WriteLine ("\t\tS: " + argtype); skip = true; } @@ -409,120 +408,46 @@ public class Generator return Node.IdToNode [n.Attributes ["type"]]; } - // Return the CodeDom type reference corresponding to T, or null - public CodeTypeReference CppTypeToCodeDomType (CppType t, out bool byref) { - CodeTypeReference rtype = null; + // Return the System.Type name corresponding to T, or null + // Returned as a string, because other wrappers do not have System.Types yet + public string CppTypeToManaged (CppType t) { - byref = false; Type mtype = t.ToManagedType (); if (mtype != null && mtype != typeof (ICppObject)) { - if (mtype.IsByRef) { - byref = true; - mtype = mtype.GetElementType (); - } - return new CodeTypeReference (mtype); + return mtype.FullName; } - // Why is this here? - //if (t.Modifiers.Count > 0 && t.ElementType != CppTypes.Void && t.ElementType != CppTypes.Class) - // return null; switch (t.ElementType) { - // These cases should all be handled by ToManagedType, no? - /* - case CppTypes.Void: - if (t.Modifiers.Count > 0) { - if (t.Modifiers.Count == 1 && t.Modifiers [0] == CppModifiers.Pointer) - rtype = new CodeTypeReference (typeof (IntPtr)); - else - return null; - } else { - rtype = new CodeTypeReference (typeof (void)); - } - break; - case CppTypes.Bool: - rtype = new CodeTypeReference (typeof (bool)); - break; - case CppTypes.Int: - rtype = new CodeTypeReference (typeof (int)); - break; - case CppTypes.Float: - rtype = new CodeTypeReference (typeof (float)); - break; - case CppTypes.Double: - rtype = new CodeTypeReference (typeof (double)); - break; - case CppTypes.Char: - rtype = new CodeTypeReference (typeof (char)); - break; - */ + case CppTypes.Class: case CppTypes.Struct: // FIXME: Full name - rtype = new CodeTypeReference (t.ElementTypeName); - break; - default: - return null; - } - return rtype; - } + return t.ElementTypeName; - public CodeTypeReference CppTypeToCodeDomType (CppType t) { - bool byref; - - return CppTypeToCodeDomType (t, out byref); + } + + return null; } void GenerateCode () { Directory.CreateDirectory (OutputDir); - Provider = new CSharpCodeProvider (); - CodeGenOptions = new CodeGeneratorOptions { BlankLinesBetweenMembers = false, IndentString = "\t" }; - - CodeTypeDeclaration libDecl = null; - - // Generate Libs class - { - var cu = new CodeCompileUnit (); - var ns = new CodeNamespace (Namespace); - ns.Imports.Add(new CodeNamespaceImport("System")); - ns.Imports.Add(new CodeNamespaceImport("Mono.VisualC.Interop")); - cu.Namespaces.Add (ns); - - var decl = new CodeTypeDeclaration ("Libs"); - - var field = new CodeMemberField (new CodeTypeReference ("CppLibrary"), LibBaseName); - field.Attributes = MemberAttributes.Public|MemberAttributes.Static; - field.InitExpression = new CodeObjectCreateExpression (new CodeTypeReference ("CppLibrary"), new CodeExpression [] { new CodePrimitiveExpression (LibBaseName), new CodeFieldReferenceExpression (new CodeTypeReferenceExpression (typeof (InlineMethods).Name), InlinePolicy.ToString ()) }); - decl.Members.Add (field); - - ns.Types.Add (decl); - - libDecl = decl; - - //Provider.GenerateCodeFromCompileUnit(cu, Console.Out, CodeGenOptions); - using (TextWriter w = File.CreateText (Path.Combine (OutputDir, "Libs.cs"))) { - Provider.GenerateCodeFromCompileUnit(cu, w, CodeGenOptions); - } + // Generate Libs file + using (TextWriter w = File.CreateText (Path.Combine (OutputDir, "Libs.cs"))) { + Libs.Generator = this; + w.Write (Libs.TransformText ()); } + // Generate user classes foreach (Class klass in Classes) { if (klass.Disable) continue; - var cu = new CodeCompileUnit (); - var ns = new CodeNamespace (Namespace); - ns.Imports.Add(new CodeNamespaceImport("System")); - ns.Imports.Add(new CodeNamespaceImport("Mono.VisualC.Interop")); - cu.Namespaces.Add (ns); - - ns.Types.Add (klass.GenerateClass (this, libDecl, LibBaseName)); - - //Provider.GenerateCodeFromCompileUnit(cu, Console.Out, CodeGenOptions); using (TextWriter w = File.CreateText (Path.Combine (OutputDir, klass.Name + ".cs"))) { - // These are reported for the fields of the native layout structures - //Provider.GenerateCodeFromCompileUnit (new CodeSnippetCompileUnit("#pragma warning disable 0414, 0169"), w, CodeGenOptions); - Provider.GenerateCodeFromCompileUnit(cu, w, CodeGenOptions); + Class.Generator = this; + Class.Class = klass; + w.Write (Class.TransformText ()); } } } diff --git a/src/generator/Makefile.am b/src/generator/Makefile.am index e1c1a29..31adddf 100644 --- a/src/generator/Makefile.am +++ b/src/generator/Makefile.am @@ -55,7 +55,11 @@ FILES = \ Node.cs \ Options.cs \ Parameter.cs \ - Property.cs + Property.cs \ + Templates/Base.cs \ + Templates/BaseMembers.cs \ + Templates/CSharp/CSharpClass.cs \ + Templates/CSharp/CSharpLibs.cs DATA_FILES = diff --git a/src/generator/Method.cs b/src/generator/Method.cs index 7397ff6..f90b177 100644 --- a/src/generator/Method.cs +++ b/src/generator/Method.cs @@ -30,13 +30,11 @@ using System; using System.Linq; using System.Collections.Generic; -using System.CodeDom; -using System.CodeDom.Compiler; using Mono.VisualC.Interop; -class Method -{ +public class Method { + public Method (Node node) { Node = node; Parameters = new List (); @@ -101,152 +99,4 @@ class Method return "" + Char.ToUpper (Name [0]) + Name.Substring (1); } } - - string GetCSharpMethodName (string name) { - return "" + Char.ToUpper (name [0]) + name.Substring (1); - } - - public CodeMemberMethod GenerateIFaceMethod (Generator g) { - var method = new CodeMemberMethod () { - Name = Name - }; - - if (!IsStatic) - method.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference ("CppInstancePtr"), "this")); - - CodeTypeReference rtype = g.CppTypeToCodeDomType (ReturnType); - method.ReturnType = rtype; - if ((ReturnType.ElementType == CppTypes.Class || ReturnType.ElementType == CppTypes.Struct) && - !ReturnType.Modifiers.Contains (CppModifiers.Pointer) && - !ReturnType.Modifiers.Contains (CppModifiers.Reference) && - !ReturnType.Modifiers.Contains (CppModifiers.Array)) - { - method.ReturnTypeCustomAttributes.Add (new CodeAttributeDeclaration ("ByVal")); - } - - foreach (var p in Parameters) { - CppType ptype = p.Type; - bool byref; - var ctype = g.CppTypeToCodeDomType (ptype, out byref); - var param = new CodeParameterDeclarationExpression (ctype, p.Name); - if (byref) - param.Direction = FieldDirection.Ref; - if (!IsVirtual && !ptype.ToString ().Equals (string.Empty)) - param.CustomAttributes.Add (new CodeAttributeDeclaration ("MangleAsAttribute", new CodeAttributeArgument (new CodePrimitiveExpression (ptype.ToString ())))); - if ((ptype.ElementType == CppTypes.Class || ptype.ElementType == CppTypes.Struct) && - !ptype.Modifiers.Contains (CppModifiers.Pointer) && - !ptype.Modifiers.Contains (CppModifiers.Reference) && - !ptype.Modifiers.Contains (CppModifiers.Array)) - { - param.CustomAttributes.Add (new CodeAttributeDeclaration ("ByVal")); - } - method.Parameters.Add (param); - } - - // FIXME: Copy ctor - - if (IsVirtual) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("Virtual")); - if (IsConstructor) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("Constructor")); - if (IsDestructor) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("Destructor")); - if (IsConst) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("Const")); - if (IsInline) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("Inline")); - if (IsArtificial) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("Artificial")); - if (IsCopyCtor) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("CopyConstructor")); - if (IsStatic) - method.CustomAttributes.Add (new CodeAttributeDeclaration ("Static")); - - return method; - } - - public CodeMemberMethod GenerateWrapperDeclaration (Generator g) { - CodeMemberMethod method; - - if (IsConstructor) - method = new CodeConstructor () { - Name = GetCSharpMethodName (Name) - }; - else - method = new CodeMemberMethod () { - Name = GetCSharpMethodName (Name) - }; - method.Attributes = MemberAttributes.Public; - if (IsStatic) - method.Attributes |= MemberAttributes.Static; - - method.ReturnType = g.CppTypeToCodeDomType (ReturnType); - - foreach (var p in Parameters) { - bool byref; - 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); - } - - return method; - } - - IEnumerable GetArgumentExpressions (Generator g) { - for (int i = 0; i < Parameters.Count; ++i) { - bool byref; - g.CppTypeToCodeDomType (Parameters [i].Type, out byref); - CodeExpression arg = new CodeArgumentReferenceExpression (Parameters [i].Name); - if (byref) - arg = new CodeDirectionExpression (FieldDirection.Ref, arg); - yield return arg; - } - yield break; - } - - // for methods inherited from non-primary bases - public CodeMemberMethod GenerateInheritedWrapperMethod (Generator g, Class baseClass) { - var method = GenerateWrapperDeclaration (g); - var args = GetArgumentExpressions (g).ToArray (); - - var call = new CodeMethodInvokeExpression (new CodeCastExpression (baseClass.Name, new CodeThisReferenceExpression ()), method.Name, args); - - if (method.ReturnType.BaseType == "System.Void") - method.Statements.Add (call); - else - method.Statements.Add (new CodeMethodReturnStatement (call)); - - return method; - } - - public CodeMemberMethod GenerateWrapperMethod (Generator g) { - var method = GenerateWrapperDeclaration (g); - - if (IsConstructor) { - //this.native_ptr = impl.Alloc(this); - method.Statements.Add (new CodeAssignStatement (new CodeFieldReferenceExpression (null, "native_ptr"), new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), "Alloc"), new CodeExpression [] { new CodeThisReferenceExpression () }))); - } - - // Call the iface method - var args = new CodeExpression [Parameters.Count + (IsStatic ? 0 : 1)]; - if (!IsStatic) - args [0] = new CodeFieldReferenceExpression (null, "Native"); - - var i = 0; - foreach (var arg in GetArgumentExpressions (g)) { - args [i + (IsStatic ? 0 : 1)] = arg; - i++; - } - - var call = new CodeMethodInvokeExpression (new CodeMethodReferenceExpression (new CodeFieldReferenceExpression (null, "impl"), Name), args); - - if (method.ReturnType.BaseType == "System.Void" || IsConstructor) - method.Statements.Add (call); - else - method.Statements.Add (new CodeMethodReturnStatement (call)); - - return method; - } } diff --git a/src/generator/Node.cs b/src/generator/Node.cs index 4f9deb4..27eab7f 100644 --- a/src/generator/Node.cs +++ b/src/generator/Node.cs @@ -36,7 +36,7 @@ using System.Collections.Generic; // // This class represents an XML node read from the output of gccxml // -class Node { +public class Node { // The XML element type public string Type { diff --git a/src/generator/Property.cs b/src/generator/Property.cs index bfe20e7..a8aa1c8 100644 --- a/src/generator/Property.cs +++ b/src/generator/Property.cs @@ -27,13 +27,11 @@ using System; using System.Collections.Generic; -using System.CodeDom; -using System.CodeDom.Compiler; using Mono.VisualC.Interop; -class Property -{ +public class Property { + public Property (string name, CppType type) { Name = name; Type = type; @@ -54,28 +52,4 @@ class Property 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 CodePropertySetValueReferenceExpression () })); - } - return p; - } - - public CodeMemberProperty GenerateInheritedProperty (Generator g, Class baseClass) { - 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 CodePropertyReferenceExpression (new CodeCastExpression (baseClass.Name, new CodeThisReferenceExpression ()), GetMethod.Name))); - } - if (SetMethod != null) { - p.SetStatements.Add (new CodeAssignStatement (new CodePropertyReferenceExpression (new CodeCastExpression (baseClass.Name, new CodeThisReferenceExpression ()), SetMethod.Name), new CodePropertySetValueReferenceExpression ())); - } - return p; - } } diff --git a/src/generator/Templates/Base.cs b/src/generator/Templates/Base.cs new file mode 100644 index 0000000..3da0088 --- /dev/null +++ b/src/generator/Templates/Base.cs @@ -0,0 +1,181 @@ +// ------------------------------------------------------------------------------ +// +// 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. +// +// ------------------------------------------------------------------------------ + +namespace Templates { + using System; + + + public partial class Base : BaseBase { + + public virtual string TransformText() { + this.GenerationEnvironment = null; + + #line 2 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/Base.tt" + /* This is a dummy template that language-specific templates may inherit from */ + + #line default + #line hidden + return this.GenerationEnvironment.ToString(); + } + + protected virtual void Initialize() { + } + } + + public class BaseBase { + + private global::System.Text.StringBuilder builder; + + private global::System.Collections.Generic.IDictionary session; + + private global::System.CodeDom.Compiler.CompilerErrorCollection errors; + + private string currentIndent = string.Empty; + + private global::System.Collections.Generic.Stack indents; + + private ToStringInstanceHelper _toStringHelper = new ToStringInstanceHelper(); + + public virtual global::System.Collections.Generic.IDictionary Session { + get { + return this.session; + } + set { + this.session = value; + } + } + + public global::System.Text.StringBuilder GenerationEnvironment { + get { + if ((this.builder == null)) { + this.builder = new global::System.Text.StringBuilder(); + } + return this.builder; + } + set { + this.builder = value; + } + } + + protected global::System.CodeDom.Compiler.CompilerErrorCollection Errors { + get { + if ((this.errors == null)) { + this.errors = new global::System.CodeDom.Compiler.CompilerErrorCollection(); + } + return this.errors; + } + } + + public string CurrentIndent { + get { + return this.currentIndent; + } + } + + private global::System.Collections.Generic.Stack Indents { + get { + if ((this.indents == null)) { + this.indents = new global::System.Collections.Generic.Stack(); + } + return this.indents; + } + } + + public ToStringInstanceHelper ToStringHelper { + get { + return this._toStringHelper; + } + } + + public void Error(string message) { + this.Errors.Add(new global::System.CodeDom.Compiler.CompilerError(null, -1, -1, null, message)); + } + + public void Warning(string message) { + global::System.CodeDom.Compiler.CompilerError val = new global::System.CodeDom.Compiler.CompilerError(null, -1, -1, null, message); + val.IsWarning = true; + this.Errors.Add(val); + } + + public string PopIndent() { + if ((this.Indents.Count == 0)) { + return string.Empty; + } + int lastPos = (this.currentIndent.Length - this.Indents.Pop()); + string last = this.currentIndent.Substring(lastPos); + this.currentIndent = this.currentIndent.Substring(0, lastPos); + return last; + } + + public void PushIndent(string indent) { + this.Indents.Push(indent.Length); + this.currentIndent = (this.currentIndent + indent); + } + + public void ClearIndent() { + this.currentIndent = string.Empty; + this.Indents.Clear(); + } + + public void Write(string textToAppend) { + this.GenerationEnvironment.Append(textToAppend); + } + + public void Write(string format, params object[] args) { + this.GenerationEnvironment.AppendFormat(format, args); + } + + public void WriteLine(string textToAppend) { + this.GenerationEnvironment.Append(this.currentIndent); + this.GenerationEnvironment.AppendLine(textToAppend); + } + + public void WriteLine(string format, params object[] args) { + this.GenerationEnvironment.Append(this.currentIndent); + this.GenerationEnvironment.AppendFormat(format, args); + this.GenerationEnvironment.AppendLine(); + } + + public class ToStringInstanceHelper { + + private global::System.IFormatProvider formatProvider = global::System.Globalization.CultureInfo.InvariantCulture; + + public global::System.IFormatProvider FormatProvider { + get { + return this.formatProvider; + } + set { + if ((this.formatProvider == null)) { + throw new global::System.ArgumentNullException("formatProvider"); + } + this.formatProvider = value; + } + } + + public string ToStringWithCulture(object objectToConvert) { + if ((objectToConvert == null)) { + throw new global::System.ArgumentNullException("objectToConvert"); + } + global::System.Type type = objectToConvert.GetType(); + global::System.Type iConvertibleType = typeof(global::System.IConvertible); + if (iConvertibleType.IsAssignableFrom(type)) { + return ((global::System.IConvertible)(objectToConvert)).ToString(this.formatProvider); + } + global::System.Reflection.MethodInfo methInfo = type.GetMethod("ToString", new global::System.Type[] { + iConvertibleType}); + if ((methInfo != null)) { + return ((string)(methInfo.Invoke(objectToConvert, new object[] { + this.formatProvider}))); + } + return objectToConvert.ToString(); + } + } + } +} diff --git a/src/generator/Templates/Base.tt b/src/generator/Templates/Base.tt new file mode 100644 index 0000000..b6a83ca --- /dev/null +++ b/src/generator/Templates/Base.tt @@ -0,0 +1,2 @@ +<#@ template language="C#" #> +<# /* This is a dummy template that language-specific templates may inherit from */ #> diff --git a/src/generator/Templates/BaseMembers.cs b/src/generator/Templates/BaseMembers.cs new file mode 100644 index 0000000..7e4536a --- /dev/null +++ b/src/generator/Templates/BaseMembers.cs @@ -0,0 +1,16 @@ +using System; + +namespace Templates { + + public interface ITemplate { + Generator Generator { get; set; } + Class Class { get; set; } + string TransformText (); + } + + public partial class Base : ITemplate { + + public Generator Generator { get; set; } + public Class Class { get; set; } + } +} diff --git a/src/generator/Templates/CSharp/CSharpClass.cs b/src/generator/Templates/CSharp/CSharpClass.cs new file mode 100644 index 0000000..6e8c5eb --- /dev/null +++ b/src/generator/Templates/CSharp/CSharpClass.cs @@ -0,0 +1,828 @@ +// ------------------------------------------------------------------------------ +// +// 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. +// +// ------------------------------------------------------------------------------ + +namespace Templates { + using System.IO; + using System.Linq; + using System.Collections.Generic; + using Mono.VisualC.Interop; + using System; + + + public partial class CSharpClass : Base { + + + #line 204 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + +private void WriteMethodHeader (Method method, string initBases) +{ + var returnType = GetCSharpType (Generator.CppTypeToManaged (method.ReturnType)); + + if (method.IsVirtual) + WriteLine (string.Format ("[OverrideNative (\"{0}\")]", method.Name)); + + Write (CurrentIndent + "public "); + if (method.IsConstructor) { + Write (method.FormattedName); + } else { + if (method.IsStatic) Write ("static "); + if (method.IsVirtual) Write ("virtual "); + // ...? + Write (returnType); + Write (" "); + Write (method.FormattedName); + } + + Write (" ("); + WriteParameters (method.Parameters, true, false); + Write (")\n"); + + if (method.IsConstructor) + WriteLine (initBases); + else + WriteLine ("{"); + + PushIndent ("\t"); + Write (CurrentIndent); + + if (returnType != "void") + Write ("return "); +} + +private void WriteParameters (IList parameters, bool writeType, bool writeAttributes) +{ + for (var i = 0; i < parameters.Count; i++) { + if (i != 0) + Write (", "); + + var type = GetCSharpType (Generator.CppTypeToManaged (parameters [i].Type)); + + if (writeAttributes) { + var mangleAs = parameters [i].Type.ToString (); + if (mangleAs != "" && mangleAs != type) + Write (string.Format ("[MangleAs (\"{0}\")] ", mangleAs)); + if (IsByVal (parameters [i].Type)) + Write ("[ByVal] "); + } + + if (type.EndsWith ("&")) { + Write ("ref "); + type = GetCSharpType (type.TrimEnd ('&')); + } + + if (writeType) { + Write (type); + Write (" "); + } + + Write (parameters [i].Name); + } +} + +private string GetCSharpType (string str) +{ + switch (str) { + case "System.Void": return "void"; + case "System.Boolean": return "bool"; + case "System.Byte": return "byte"; + case "System.SByte": return "sbyte"; + case "System.Char": return "char"; + case "System.Int16": return "short"; + case "System.UInt16": return "ushort"; + case "System.Decimal": return "decimal"; + case "System.Single": return "float"; + case "System.Double": return "double"; + case "System.Int32": return "int"; + case "System.UInt32": return "uint"; + case "System.Int64": return "long"; + case "System.UInt64": return "ulong"; + case "System.Object": return "object"; + case "System.String": return "string"; + } + + var lastDot = str.LastIndexOf ('.'); + if (str.StartsWith ("System") && lastDot == "System".Length) + return str.Substring (lastDot + 1); + + return str; +} + +private string GetBaseString () +{ + if (Class.BaseClasses.Count == 0) + return "ICppObject"; + + var str = Class.BaseClasses [0].Name; + if (Class.BaseClasses.Count > 1) { + str = string.Format ("{0} /*, {1} */", str, string.Join (", ", Class.BaseClasses.Skip (1).Select (bc => bc.Name).ToArray ())); + } + + 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)); +} + + #line default + #line hidden + + public override string TransformText() { + this.GenerationEnvironment = null; + + #line 6 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + + var hasBase = Class.BaseClasses.Count > 0; + var wrapper = Class.Name; + var iface = "I" + Class.Name; + var layout = "_" + Class.Name; + + var initBases = "{"; + if (hasBase) { + initBases = "\t: base (impl.TypeInfo) {"; + foreach (var nonPrimaryBase in Class.BaseClasses.Skip (1)) { + initBases = string.Format ("{0}\n\t\t\tnew {1} (impl.TypeInfo);", initBases, nonPrimaryBase.Name); + } + } + + + #line default + #line hidden + + #line 20 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("// -------------------------------------------------------------------------\n// Managed wrapper for "); + + #line default + #line hidden + + #line 21 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Class.Name )); + + #line default + #line hidden + + #line 21 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n// Generated from "); + + #line default + #line hidden + + #line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Path.GetFileName (Generator.InputFileName) )); + + #line default + #line hidden + + #line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" on "); + + #line default + #line hidden + + #line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( DateTime.Now )); + + #line default + #line hidden + + #line 22 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n//\n// This file was auto generated. Do not edit.\n// -------------------------------------------------------------------------\n\nusing System;\nusing Mono.VisualC.Interop;\n\nnamespace "); + + #line default + #line hidden + + #line 30 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Generator.Namespace )); + + #line default + #line hidden + + #line 30 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" {\n\n\tpublic partial class "); + + #line default + #line hidden + + #line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); + + #line default + #line hidden + + #line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" : "); + + #line default + #line hidden + + #line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( GetBaseString () )); + + #line default + #line hidden + + #line 32 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" {\n\n\t\tprivate static readonly "); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( iface )); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" impl = Libs."); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Generator.LibBaseName )); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(".GetClass<"); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( iface + "," + layout + "," + wrapper )); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("> (\""); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Class.Name )); + + #line default + #line hidden + + #line 34 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\");\n"); + + #line default + #line hidden + + #line 35 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + if (!hasBase) { + + #line default + #line hidden + + #line 36 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\tpublic CppInstancePtr Native { get; protected set; }\n"); + + #line default + #line hidden + + #line 37 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + } + + #line default + #line hidden + + #line 38 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n"); + + #line default + #line hidden + + #line 39 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + /* Interface */ + + #line default + #line hidden + + #line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\tpublic interface "); + + #line default + #line hidden + + #line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( iface )); + + #line default + #line hidden + + #line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" : ICppClassOverridable<"); + + #line default + #line hidden + + #line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); + + #line default + #line hidden + + #line 40 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("> {\n"); + + #line default + #line hidden + + #line 41 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + PushIndent ("\t\t\t"); + foreach (var method in Class.Methods) { + Write (CurrentIndent); + + if (method.IsVirtual) Write ("[Virtual] "); + if (method.IsStatic) Write ("[Static] "); + if (method.IsArtificial) Write ("[Artificial] "); + if (method.IsInline) Write ("[Inline] "); + if (method.IsConst) Write ("[Const] "); + if (method.IsConstructor) Write ("[Constructor] "); + if (method.IsDestructor) Write ("[Destructor] "); + if (method.IsCopyCtor) Write ("[CopyConstructor] "); + + if (IsByVal (method.ReturnType)) { + Write ("[return: ByVal] "); + } + Write (GetCSharpType (Generator.CppTypeToManaged (method.ReturnType))); + Write (" "); + Write (method.Name); + + Write (" ("); + if (!method.IsStatic) { + Write ("CppInstancePtr @this"); + if (method.Parameters.Count != 0) + Write (", "); + } + + WriteParameters (method.Parameters, true, !method.IsVirtual); + Write (");\n"); + } + ClearIndent (); + + #line default + #line hidden + + #line 72 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\t}\n"); + + #line default + #line hidden + + #line 73 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + /* Native layout */ + + #line default + #line hidden + + #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\tprivate struct "); + + #line default + #line hidden + + #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( layout )); + + #line default + #line hidden + + #line 74 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" {\n"); + + #line default + #line hidden + + #line 75 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + foreach (var field in Class.Fields) { + + #line default + #line hidden + + #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\t\tpublic "); + + #line default + #line hidden + + #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( GetCSharpType (Generator.CppTypeToManaged (field.Type)) )); + + #line default + #line hidden + + #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" "); + + #line default + #line hidden + + #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( field.Name )); + + #line default + #line hidden + + #line 76 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(";\n"); + + #line default + #line hidden + + #line 77 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + } + + #line default + #line hidden + + #line 78 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\t}\n\n"); + + #line default + #line hidden + + #line 80 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + /* Native constructor */ + + #line default + #line hidden + + #line 81 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\tpublic "); + + #line default + #line hidden + + #line 81 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); + + #line default + #line hidden + + #line 81 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" (CppInstancePtr native)\n\t\t"); + + #line default + #line hidden + + #line 82 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( initBases )); + + #line default + #line hidden + + #line 82 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n\t\t\tNative = native;\n\t\t}\n\n"); + + #line default + #line hidden + + #line 86 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + /* Subclass constructor */ + + #line default + #line hidden + + #line 87 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\tpublic "); + + #line default + #line hidden + + #line 87 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); + + #line default + #line hidden + + #line 87 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" (CppTypeInfo subClass)\n\t\t"); + + #line default + #line hidden + + #line 88 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( initBases )); + + #line default + #line hidden + + #line 88 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n\t\t\tsubClass.AddBase (impl.TypeInfo);\n\t\t}\n\n"); + + #line default + #line hidden + + #line 92 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + /* Wrapper methods */ + + #line default + #line hidden + + #line 93 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + PushIndent ("\t\t"); + foreach (var method in Class.Methods.Where (m => m.GenWrapperMethod)) { + + WriteMethodHeader (method, initBases); + + if (method.IsConstructor) { + Write ("Native = impl.Alloc (this);\n"); + Write (CurrentIndent); + } + + Write (string.Format ("impl.{0} (", method.Name)); + if (!method.IsStatic) { + Write ("Native"); + if (method.Parameters.Count != 0) + Write (", "); + } + + WriteParameters (method.Parameters, false, false); + PopIndent (); + Write (string.Format (");\n{0}}}\n\n", CurrentIndent)); + } + ClearIndent (); + + #line default + #line hidden + + #line 115 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n"); + + #line default + #line hidden + + #line 116 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + /* Wrapper properties */ + + #line default + #line hidden + + #line 117 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + PushIndent ("\t\t"); + foreach (var prop in Class.Properties) { + var type = GetCSharpType (Generator.CppTypeToManaged (prop.Type)); + + Write (CurrentIndent + "public "); + + if ((prop.GetMethod == null || prop.GetMethod.IsVirtual) && + (prop.SetMethod == null || prop.SetMethod.IsVirtual)) + Write ("virtual "); + + Write (type); + Write (" "); + Write (prop.Name); + Write (" {\n"); + + PushIndent ("\t"); + Write (CurrentIndent); + + if (prop.GetMethod != null) { + if (prop.GetMethod.IsVirtual) + Write (string.Format ("[OverrideNative (\"{0}\")] ", prop.GetMethod.Name)); + + Write ("get {\n"); + PushIndent ("\t"); + WriteLine (string.Format ("return impl.{0} (Native);", prop.GetMethod.Name)); + PopIndent (); + WriteLine ("}"); + } + if (prop.SetMethod != null) { + if (prop.SetMethod.IsVirtual) + Write (string.Format ("[OverrideNative (\"{0}\")] ", prop.SetMethod.Name)); + + Write ("set {\n"); + PushIndent ("\t"); + WriteLine (string.Format ("impl.{0} (Native, value);", prop.SetMethod.Name)); + PopIndent (); + WriteLine ("}"); + } + + PopIndent (); + WriteLine ("}\n"); + } + ClearIndent (); + + #line default + #line hidden + + #line 160 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n"); + + #line default + #line hidden + + #line 161 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + /* Make this wrapper castable to non-primary bases */ +foreach (var npBase in Class.BaseClasses.Skip (1)) { + var npImpl = npBase.Name + "_impl"; + + + #line default + #line hidden + + #line 165 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\t// Non-primary base class implementation for "); + + #line default + #line hidden + + #line 165 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); + + #line default + #line hidden + + #line 165 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(":\n\t\tprivate "); + + #line default + #line hidden + + #line 166 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); + + #line default + #line hidden + + #line 166 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" "); + + #line default + #line hidden + + #line 166 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npImpl )); + + #line default + #line hidden + + #line 166 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(";\n\t\tpublic static implicit operator "); + + #line default + #line hidden + + #line 167 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); + + #line default + #line hidden + + #line 167 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("("); + + #line default + #line hidden + + #line 167 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( wrapper )); + + #line default + #line hidden + + #line 167 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" subClass)\n\t\t{\n\t\t\tif (subClass."); + + #line default + #line hidden + + #line 169 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npImpl )); + + #line default + #line hidden + + #line 169 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" == null)\n\t\t\t\tsubClass."); + + #line default + #line hidden + + #line 170 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npImpl )); + + #line default + #line hidden + + #line 170 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" = impl.TypeInfo.Cast<"); + + #line default + #line hidden + + #line 170 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npBase.Name )); + + #line default + #line hidden + + #line 170 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("> (subClass);\n\t\t\treturn subClass."); + + #line default + #line hidden + + #line 171 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( npImpl )); + + #line default + #line hidden + + #line 171 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(";\n\t\t}\n\n"); + + #line default + #line hidden + + #line 174 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + PushIndent ("\t\t"); + foreach (var method in npBase.Methods) { + // With the exception of virtual methods that have been overridden, these methods must be called + // thru a cast to the base class that performs a this ptr adjustment + if (!method.GenWrapperMethod || method.IsConstructor || method.IsStatic || + (method.IsVirtual && Class.Methods.Any (m => m.Node.CheckValue ("overrides", method.Node.Id)))) + continue; + + WriteMethodHeader (method, initBases); + + Write (string.Format ("(({0})this).{1} (", npBase.Name, method.FormattedName)); + + WriteParameters (method.Parameters, false, false); + PopIndent (); + Write (string.Format (");\n{0}}}\n\n", CurrentIndent)); + } + ClearIndent (); +} + + #line default + #line hidden + + #line 192 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\n\t\tpublic "); + + #line default + #line hidden + + #line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( hasBase? "override" : "virtual" )); + + #line default + #line hidden + + #line 193 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write(" void Dispose ()\n\t\t{\n"); + + #line default + #line hidden + + #line 195 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + if (Class.Methods.Any (m => m.IsDestructor && !m.IsArtificial)) { + + #line default + #line hidden + + #line 196 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\t\timpl.Destruct (Native);\n"); + + #line default + #line hidden + + #line 197 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + } + + #line default + #line hidden + + #line 198 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpClass.tt" + this.Write("\t\t\tNative.Dispose ();\n\t\t}\n\n\t}\n}\n\n"); + + #line default + #line hidden + return this.GenerationEnvironment.ToString(); + } + + protected override void Initialize() { + base.Initialize(); + } + } +} diff --git a/src/generator/Templates/CSharp/CSharpClass.tt b/src/generator/Templates/CSharp/CSharpClass.tt new file mode 100644 index 0000000..e6c3d58 --- /dev/null +++ b/src/generator/Templates/CSharp/CSharpClass.tt @@ -0,0 +1,318 @@ +<#@ template language="C#" inherits="Base" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="Mono.VisualC.Interop" #> +<# + var hasBase = Class.BaseClasses.Count > 0; + var wrapper = Class.Name; + var iface = "I" + Class.Name; + var layout = "_" + Class.Name; + + var initBases = "{"; + if (hasBase) { + initBases = "\t: base (impl.TypeInfo) {"; + foreach (var nonPrimaryBase in Class.BaseClasses.Skip (1)) { + initBases = string.Format ("{0}\n\t\t\tnew {1} (impl.TypeInfo);", initBases, nonPrimaryBase.Name); + } + } +#> +// ------------------------------------------------------------------------- +// Managed wrapper for <#= Class.Name #> +// Generated from <#= Path.GetFileName (Generator.InputFileName) #> on <#= DateTime.Now #> +// +// This file was auto generated. Do not edit. +// ------------------------------------------------------------------------- + +using System; +using Mono.VisualC.Interop; + +namespace <#= Generator.Namespace #> { + + public partial class <#= wrapper #> : <#= GetBaseString () #> { + + private static readonly <#= iface #> impl = Libs.<#= Generator.LibBaseName #>.GetClass<<#= iface + "," + layout + "," + wrapper #>> ("<#= Class.Name #>"); +<# if (!hasBase) { #> + public CppInstancePtr Native { get; protected set; } +<# } #> + +<# /* Interface */ #> + public interface <#= iface #> : ICppClassOverridable<<#= wrapper #>> { +<# PushIndent ("\t\t\t"); + foreach (var method in Class.Methods) { + Write (CurrentIndent); + + if (method.IsVirtual) Write ("[Virtual] "); + if (method.IsStatic) Write ("[Static] "); + if (method.IsArtificial) Write ("[Artificial] "); + if (method.IsInline) Write ("[Inline] "); + if (method.IsConst) Write ("[Const] "); + if (method.IsConstructor) Write ("[Constructor] "); + if (method.IsDestructor) Write ("[Destructor] "); + if (method.IsCopyCtor) Write ("[CopyConstructor] "); + + if (IsByVal (method.ReturnType)) { + Write ("[return: ByVal] "); + } + Write (GetCSharpType (Generator.CppTypeToManaged (method.ReturnType))); + Write (" "); + Write (method.Name); + + Write (" ("); + if (!method.IsStatic) { + Write ("CppInstancePtr @this"); + if (method.Parameters.Count != 0) + Write (", "); + } + + WriteParameters (method.Parameters, true, !method.IsVirtual); + Write (");\n"); + } + ClearIndent (); #> + } +<# /* Native layout */ #> + private struct <#= layout #> { +<# foreach (var field in Class.Fields) { #> + public <#= GetCSharpType (Generator.CppTypeToManaged (field.Type)) #> <#= field.Name #>; +<# } #> + } + +<# /* Native constructor */ #> + public <#= wrapper #> (CppInstancePtr native) + <#= initBases #> + Native = native; + } + +<# /* Subclass constructor */ #> + public <#= wrapper #> (CppTypeInfo subClass) + <#= initBases #> + subClass.AddBase (impl.TypeInfo); + } + +<# /* Wrapper methods */ #> +<# PushIndent ("\t\t"); + foreach (var method in Class.Methods.Where (m => m.GenWrapperMethod)) { + + WriteMethodHeader (method, initBases); + + if (method.IsConstructor) { + Write ("Native = impl.Alloc (this);\n"); + Write (CurrentIndent); + } + + Write (string.Format ("impl.{0} (", method.Name)); + if (!method.IsStatic) { + Write ("Native"); + if (method.Parameters.Count != 0) + Write (", "); + } + + WriteParameters (method.Parameters, false, false); + PopIndent (); + Write (string.Format (");\n{0}}}\n\n", CurrentIndent)); + } + ClearIndent (); #> + +<# /* Wrapper properties */ #> +<# PushIndent ("\t\t"); + foreach (var prop in Class.Properties) { + var type = GetCSharpType (Generator.CppTypeToManaged (prop.Type)); + + Write (CurrentIndent + "public "); + + if ((prop.GetMethod == null || prop.GetMethod.IsVirtual) && + (prop.SetMethod == null || prop.SetMethod.IsVirtual)) + Write ("virtual "); + + Write (type); + Write (" "); + Write (prop.Name); + Write (" {\n"); + + PushIndent ("\t"); + Write (CurrentIndent); + + if (prop.GetMethod != null) { + if (prop.GetMethod.IsVirtual) + Write (string.Format ("[OverrideNative (\"{0}\")] ", prop.GetMethod.Name)); + + Write ("get {\n"); + PushIndent ("\t"); + WriteLine (string.Format ("return impl.{0} (Native);", prop.GetMethod.Name)); + PopIndent (); + WriteLine ("}"); + } + if (prop.SetMethod != null) { + if (prop.SetMethod.IsVirtual) + Write (string.Format ("[OverrideNative (\"{0}\")] ", prop.SetMethod.Name)); + + Write ("set {\n"); + PushIndent ("\t"); + WriteLine (string.Format ("impl.{0} (Native, value);", prop.SetMethod.Name)); + PopIndent (); + WriteLine ("}"); + } + + PopIndent (); + WriteLine ("}\n"); + } + ClearIndent (); #> + +<# /* Make this wrapper castable to non-primary bases */ +foreach (var npBase in Class.BaseClasses.Skip (1)) { + var npImpl = npBase.Name + "_impl"; +#> + // Non-primary base class implementation for <#= npBase.Name #>: + private <#= npBase.Name #> <#= npImpl #>; + public static implicit operator <#= npBase.Name #>(<#= wrapper #> subClass) + { + if (subClass.<#= npImpl #> == null) + subClass.<#= npImpl #> = impl.TypeInfo.Cast<<#= npBase.Name #>> (subClass); + return subClass.<#= npImpl #>; + } + +<# PushIndent ("\t\t"); + foreach (var method in npBase.Methods) { + // With the exception of virtual methods that have been overridden, these methods must be called + // thru a cast to the base class that performs a this ptr adjustment + if (!method.GenWrapperMethod || method.IsConstructor || method.IsStatic || + (method.IsVirtual && Class.Methods.Any (m => m.Node.CheckValue ("overrides", method.Node.Id)))) + continue; + + WriteMethodHeader (method, initBases); + + Write (string.Format ("(({0})this).{1} (", npBase.Name, method.FormattedName)); + + WriteParameters (method.Parameters, false, false); + PopIndent (); + Write (string.Format (");\n{0}}}\n\n", CurrentIndent)); + } + ClearIndent (); +} #> + + public <#= hasBase? "override" : "virtual" #> void Dispose () + { +<# if (Class.Methods.Any (m => m.IsDestructor && !m.IsArtificial)) { #> + impl.Destruct (Native); +<# } #> + Native.Dispose (); + } + + } +} + +<#+ +private void WriteMethodHeader (Method method, string initBases) +{ + var returnType = GetCSharpType (Generator.CppTypeToManaged (method.ReturnType)); + + if (method.IsVirtual) + WriteLine (string.Format ("[OverrideNative (\"{0}\")]", method.Name)); + + Write (CurrentIndent + "public "); + if (method.IsConstructor) { + Write (method.FormattedName); + } else { + if (method.IsStatic) Write ("static "); + if (method.IsVirtual) Write ("virtual "); + // ...? + Write (returnType); + Write (" "); + Write (method.FormattedName); + } + + Write (" ("); + WriteParameters (method.Parameters, true, false); + Write (")\n"); + + if (method.IsConstructor) + WriteLine (initBases); + else + WriteLine ("{"); + + PushIndent ("\t"); + Write (CurrentIndent); + + if (returnType != "void") + Write ("return "); +} + +private void WriteParameters (IList parameters, bool writeType, bool writeAttributes) +{ + for (var i = 0; i < parameters.Count; i++) { + if (i != 0) + Write (", "); + + var type = GetCSharpType (Generator.CppTypeToManaged (parameters [i].Type)); + + if (writeAttributes) { + var mangleAs = parameters [i].Type.ToString (); + if (mangleAs != "" && mangleAs != type) + Write (string.Format ("[MangleAs (\"{0}\")] ", mangleAs)); + if (IsByVal (parameters [i].Type)) + Write ("[ByVal] "); + } + + if (type.EndsWith ("&")) { + Write ("ref "); + type = GetCSharpType (type.TrimEnd ('&')); + } + + if (writeType) { + Write (type); + Write (" "); + } + + Write (parameters [i].Name); + } +} + +private string GetCSharpType (string str) +{ + switch (str) { + case "System.Void": return "void"; + case "System.Boolean": return "bool"; + case "System.Byte": return "byte"; + case "System.SByte": return "sbyte"; + case "System.Char": return "char"; + case "System.Int16": return "short"; + case "System.UInt16": return "ushort"; + case "System.Decimal": return "decimal"; + case "System.Single": return "float"; + case "System.Double": return "double"; + case "System.Int32": return "int"; + case "System.UInt32": return "uint"; + case "System.Int64": return "long"; + case "System.UInt64": return "ulong"; + case "System.Object": return "object"; + case "System.String": return "string"; + } + + var lastDot = str.LastIndexOf ('.'); + if (str.StartsWith ("System") && lastDot == "System".Length) + return str.Substring (lastDot + 1); + + return str; +} + +private string GetBaseString () +{ + if (Class.BaseClasses.Count == 0) + return "ICppObject"; + + var str = Class.BaseClasses [0].Name; + if (Class.BaseClasses.Count > 1) { + str = string.Format ("{0} /*, {1} */", str, string.Join (", ", Class.BaseClasses.Skip (1).Select (bc => bc.Name).ToArray ())); + } + + 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)); +} +#> \ No newline at end of file diff --git a/src/generator/Templates/CSharp/CSharpLibs.cs b/src/generator/Templates/CSharp/CSharpLibs.cs new file mode 100644 index 0000000..fca550b --- /dev/null +++ b/src/generator/Templates/CSharp/CSharpLibs.cs @@ -0,0 +1,92 @@ +// ------------------------------------------------------------------------------ +// +// 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. +// +// ------------------------------------------------------------------------------ + +namespace Templates { + using System; + + + public partial class CSharpLibs : Base { + + 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 "); + + #line default + #line hidden + + #line 4 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( DateTime.Now )); + + #line default + #line hidden + + #line 4 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write("\n//\n// This file was auto generated. Do not edit.\n// -------------------------------------------------------------------------\n\nusing System;\nusing Mono.VisualC.Interop;\n\nnamespace "); + + #line default + #line hidden + + #line 12 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Generator.Namespace )); + + #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 "); + + #line default + #line hidden + + #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Generator.LibBaseName )); + + #line default + #line hidden + + #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write(" = new CppLibrary (\""); + + #line default + #line hidden + + #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Generator.LibBaseName )); + + #line default + #line hidden + + #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write("\", InlineMethods."); + + #line default + #line hidden + + #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write(this.ToStringHelper.ToStringWithCulture( Generator.InlinePolicy.ToString () )); + + #line default + #line hidden + + #line 16 "/Users/alex/OpenSource/cppinterop/src/generator/Templates/CSharp/CSharpLibs.tt" + this.Write(");\n\n\t}\n}\n"); + + #line default + #line hidden + return this.GenerationEnvironment.ToString(); + } + + protected override void Initialize() { + base.Initialize(); + } + } +} diff --git a/src/generator/Templates/CSharp/CSharpLibs.tt b/src/generator/Templates/CSharp/CSharpLibs.tt new file mode 100644 index 0000000..31dd61d --- /dev/null +++ b/src/generator/Templates/CSharp/CSharpLibs.tt @@ -0,0 +1,19 @@ +<#@ template language="C#" inherits="Base" #> +// ------------------------------------------------------------------------- +// C++ libarary declarations +// Generated on <#= DateTime.Now #> +// +// This file was auto generated. Do not edit. +// ------------------------------------------------------------------------- + +using System; +using Mono.VisualC.Interop; + +namespace <#= Generator.Namespace #> { + + public static partial class Libs { + + public static readonly CppLibrary <#= Generator.LibBaseName #> = new CppLibrary ("<#= Generator.LibBaseName #>", InlineMethods.<#= Generator.InlinePolicy.ToString () #>); + + } +} diff --git a/src/generator/generator.csproj b/src/generator/generator.csproj index 00d8e02..b6f73ff 100644 --- a/src/generator/generator.csproj +++ b/src/generator/generator.csproj @@ -7,7 +7,6 @@ 2.0 {AD0F9378-789C-4AF1-B0DD-6DD9A63C3401} Exe - generator generator v3.5 @@ -30,6 +29,7 @@ true false true + Templates true @@ -58,6 +58,16 @@ + + Base.tt + + + + CSharpClass.tt + + + CSharpLibs.tt + @@ -67,10 +77,6 @@ - - False - ..\..\bin\Debug\Mono.VisualC.Interop.dll - @@ -105,4 +111,28 @@ + + + {4A864586-93C5-4DC1-8A80-F094A88506D7} + Mono.VisualC.Interop + + + + + TextTemplatingFilePreprocessor + Base.cs + + + TextTemplatingFilePreprocessor + CSharpClass.cs + + + TextTemplatingFilePreprocessor + CSharpLibs.cs + + + + + + \ No newline at end of file