Browse Source

Merged Andreia's cppinterop/generator. Added start of new code generation backend based on CodeDom. Implemented CppType -> System.Type map.

git-svn-id: https://mono-soc-2010.googlecode.com/svn/trunk/cppinterop@115 a470b8cb-0e6f-1642-1b45-71e107334c4b
pull/1/head
alexander.corrado 15 years ago
parent
commit
8d424fc29a
  1. 12
      CPPInterop.sln
  2. 9
      Mono.VisualC.Code/Access.cs
  3. 29
      Mono.VisualC.Code/AssemblyInfo.cs
  4. 153
      Mono.VisualC.Code/Atoms/Class.cs
  5. 78
      Mono.VisualC.Code/Atoms/Method.cs
  6. 82
      Mono.VisualC.Code/Atoms/Preprocessor.cs
  7. 43
      Mono.VisualC.Code/CodeAtom.cs
  8. 40
      Mono.VisualC.Code/CodeContainer.cs
  9. 70
      Mono.VisualC.Code/CodeUnit.cs
  10. 60
      Mono.VisualC.Code/Mono.VisualC.Code.csproj
  11. 20
      Mono.VisualC.Code/Mono.VisualC.Code.sln
  12. 54
      Mono.VisualC.Interop/CppType.cs
  13. 44
      generator/Main.cs
  14. 14
      generator/generator.csproj

12
CPPInterop.sln

@ -11,6 +11,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTest", "QtTest\QtTest.csp @@ -11,6 +11,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtTest", "QtTest\QtTest.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QtBindings", "QtBindings\QtBindings.csproj", "{66212CA6-B8C2-4307-ADDE-DAFEAAB339B9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.VisualC.Code", "Mono.VisualC.Code\Mono.VisualC.Code.csproj", "{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "generator", "generator\generator.csproj", "{AD0F9378-789C-4AF1-B0DD-6DD9A63C3401}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -33,6 +37,14 @@ Global @@ -33,6 +37,14 @@ Global
{66212CA6-B8C2-4307-ADDE-DAFEAAB339B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66212CA6-B8C2-4307-ADDE-DAFEAAB339B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66212CA6-B8C2-4307-ADDE-DAFEAAB339B9}.Release|Any CPU.Build.0 = Release|Any CPU
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Release|Any CPU.Build.0 = Release|Any CPU
{AD0F9378-789C-4AF1-B0DD-6DD9A63C3401}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD0F9378-789C-4AF1-B0DD-6DD9A63C3401}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD0F9378-789C-4AF1-B0DD-6DD9A63C3401}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD0F9378-789C-4AF1-B0DD-6DD9A63C3401}.Release|Any CPU.Build.0 = Release|Any CPU
{B01E6282-144E-481A-8E1F-95F708DFBC2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B01E6282-144E-481A-8E1F-95F708DFBC2D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B01E6282-144E-481A-8E1F-95F708DFBC2D}.Release|Any CPU.ActiveCfg = Release|Any CPU

9
Mono.VisualC.Code/Access.cs

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
using System;
namespace Mono.VisualC.Code {
public enum Access {
Public,
Protected,
Private
}
}

29
Mono.VisualC.Code/AssemblyInfo.cs

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("Mono.VisualC.Code")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
[assembly: AssemblyVersion("1.0.*")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
[assembly: CLSCompliant(true)]

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

@ -0,0 +1,153 @@ @@ -0,0 +1,153 @@
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.CodeDom;
using Mono.VisualC.Interop;
namespace Mono.VisualC.Code.Atoms {
public class Class : CodeContainer {
// FIXME: This should be moved into Mono.VisualC.Interop and an attribute
// for name mangling purposes (MSVC mangles differently depending on defined as class or struct).
public enum Definition {
Class,
Struct
}
public struct BaseClass {
public Class Class;
public Access Access;
public bool IsVirtual;
}
public string Name { get; set; }
public string StaticCppLibrary { get; set; }
public IEnumerable<BaseClass> Bases { get; set; }
public Definition DefinedAs { get; set; }
public Class (string name)
{
Name = name;
Bases = Enumerable.Empty<BaseClass> ();
}
internal protected override CodeObject InsideCodeNamespace (CodeNamespace ns)
{
var wrapper = new CodeTypeDeclaration (Name) { TypeAttributes = TypeAttributes.Public };
var iface = CreateInterface ();
var native = CreateNativeLayout ();
wrapper.Members.Add (iface);
wrapper.Members.Add (native);
// FIXME: For now, we'll have the managed wrapper extend from the first public base class
string managedBase = Bases.Where (b => b.Access == Access.Public).Select (b => b.Class.Name).FirstOrDefault ();
if (managedBase == null) {
managedBase = typeof (ICppObject).Name;
// Add Native property
var nativeField = new CodeMemberField (typeof (CppInstancePtr), "native_ptr") { Attributes = MemberAttributes.Family };
var nativeProperty = new CodeMemberProperty {
Name = "Native",
Type = new CodeTypeReference (typeof (CppInstancePtr)),
HasSet = false,
Attributes = MemberAttributes.Public
};
nativeProperty.GetStatements.Add (new CodeMethodReturnStatement (new CodeFieldReferenceExpression (new CodeThisReferenceExpression (), nativeField.Name)));
wrapper.Members.Add (nativeField);
wrapper.Members.Add (nativeProperty);
}
wrapper.BaseTypes.Add (managedBase);
// add static impl field
var implField = new CodeMemberField (iface.Name, "impl") { Attributes = MemberAttributes.Static | MemberAttributes.Private };
if (StaticCppLibrary != null) {
CodeTypeReference [] types = new CodeTypeReference [] {
new CodeTypeReference (iface.Name),
new CodeTypeReference (native.Name),
new CodeTypeReference (wrapper.Name)
};
var getClassMethod = new CodeMethodReferenceExpression (new CodeTypeReferenceExpression (StaticCppLibrary), "GetClass", types);
implField.InitExpression = new CodeMethodInvokeExpression (getClassMethod, new CodePrimitiveExpression (Name));
}
wrapper.Members.Add (implField);
foreach (var atom in Atoms)
atom.Visit (wrapper);
ns.Types.Add (wrapper);
return wrapper;
}
private CodeTypeDeclaration CreateInterface ()
{
var iface = new CodeTypeDeclaration ("I" + Name) {
TypeAttributes = TypeAttributes.Interface | TypeAttributes.NestedPublic,
Attributes = MemberAttributes.Public,
IsInterface = true
};
iface.BaseTypes.Add (new CodeTypeReference (typeof (ICppClassOverridable<>).Name, new CodeTypeReference (Name)));
foreach (var atom in Atoms)
atom.Visit (iface);
return iface;
}
private CodeTypeDeclaration CreateNativeLayout ()
{
var native = new CodeTypeDeclaration ("_" + Name) {
TypeAttributes = TypeAttributes.NestedPrivate | TypeAttributes.SequentialLayout,
Attributes = MemberAttributes.Private,
IsStruct = true
};
foreach (var atom in Atoms)
atom.Visit (native);
return native;
}
public override void Write (TextWriter writer)
{
string declarator = (DefinedAs == Definition.Class? "class" : "struct");
writer.Write ("{0} {1}", declarator, Name);
var bce = Bases.GetEnumerator ();
if (bce.MoveNext ()) {
writer.Write (" : ");
while (true) {
var baseClass = bce.Current;
if (baseClass.IsVirtual) writer.Write ("virtual ");
switch (baseClass.Access) {
case Access.Public: writer.Write ("public "); break;
case Access.Protected: writer.Write ("protected "); break;
case Access.Private: writer.Write ("private "); break;
}
writer.Write (baseClass.Class.Name);
if (!bce.MoveNext ())
break;
writer.Write (", ");
}
}
writer.WriteLine (" {");
base.Write (writer);
writer.WriteLine ("};");
}
}
}

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

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.CodeDom;
using Mono.VisualC.Interop;
namespace Mono.VisualC.Code.Atoms {
public class Method : CodeContainer {
public struct Parameter {
public string Name;
public string Type;
}
public string Name { get; set; }
public Access Access { get; set; }
public bool IsVirtual { get; set; }
public bool IsStatic { get; set; }
public string RetType { get; set; }
public IEnumerable<Parameter> Parameters { get; set; }
public Method (string name)
{
Name = name;
}
internal protected override CodeObject InsideCodeTypeDeclaration (CodeTypeDeclaration decl)
{
CodeMemberMethod method = null;
if (decl.IsInterface) {
method = new CodeMemberMethod ();
method.Name = Name;
Type managedReturn = new CppType (RetType).ToManagedType ();
if (managedReturn != null)
method.ReturnType = new CodeTypeReference (managedReturn);
else
method.ReturnType = new CodeTypeReference (RetType);
if (IsVirtual)
method.CustomAttributes.Add (new CodeAttributeDeclaration ("Virtual"));
if (IsStatic)
method.CustomAttributes.Add (new CodeAttributeDeclaration ("Static"));
else
method.Parameters.Add (new CodeParameterDeclarationExpression (typeof (CppInstancePtr), "this"));
foreach (var param in Parameters) {
CodeParameterDeclarationExpression paramDecl;
Type managedType = new CppType (param.Type).ToManagedType ();
if (managedType != null)
paramDecl = new CodeParameterDeclarationExpression (managedType, param.Name);
else
paramDecl = new CodeParameterDeclarationExpression (param.Type, param.Name);
if (!IsVirtual)
paramDecl.CustomAttributes.Add (new CodeAttributeDeclaration ("MangleAs", new CodeAttributeArgument (new CodePrimitiveExpression (param.Type))));
method.Parameters.Add (paramDecl);
}
}
// FIXME: add wrapper method
if (method != null)
decl.Members.Add (method);
return method;
}
public override void Write (TextWriter writer)
{
throw new NotImplementedException ();
}
}
}

82
Mono.VisualC.Code/Atoms/Preprocessor.cs

@ -0,0 +1,82 @@ @@ -0,0 +1,82 @@
using System;
using System.Reflection;
using System.Linq;
using System.IO;
using System.CodeDom;
namespace Mono.VisualC.Code.Atoms {
// FIXME: support conditional compilation
public class PoundDefine<T> : CodeAtom {
public string Name {get; set;}
public T Value {get; set;}
private bool value_set = false;
public PoundDefine(string name) {
Name = name;
}
public PoundDefine (string name, T value) {
Name = name;
Value = value;
value_set = true;
}
public override void Write (TextWriter writer) {
if (value_set)
writer.WriteLine ("#define {0} {1}", Name, Value);
else
writer.WriteLine ("#define {0}", Name);
}
internal protected override CodeObject InsideCodeNamespace (CodeNamespace ns)
{
if (!value_set)
return null;
// create a new type Constants if it does not exist
CodeTypeDeclaration constants = (from type in ns.Types.Cast<CodeTypeDeclaration> ()
where type.Name.Equals ("Constants") select type).SingleOrDefault ();
if (constants == null) {
constants = new CodeTypeDeclaration ("Constants");
constants.TypeAttributes = TypeAttributes.Public | TypeAttributes.Sealed;
ns.Types.Add (constants);
}
return constants;
}
internal protected override CodeObject InsideCodeTypeDeclaration (CodeTypeDeclaration decl)
{
if (!value_set)
return null;
var constant = new CodeMemberField (typeof (T), Name);
constant.Attributes = MemberAttributes.Public | MemberAttributes.Const;
constant.InitExpression = new CodePrimitiveExpression (Value);
decl.Members.Add (constant);
return constant;
}
}
public class PoundIfDef : CodeContainer {
public enum Condition {
Defined,
NotDefined
}
public Condition IfCondition {get; set;}
public string Name {get; set;}
public PoundIfDef (Condition condition, string name) {
IfCondition = condition;
Name = name;
}
public override void Write (TextWriter writer) {
string directive = (IfCondition == Condition.Defined ? "#ifdef {0}" : "#ifndef {0}");
writer.WriteLine (directive, Name);
base.Write (writer);
writer.WriteLine ("#endif");
}
}
}

43
Mono.VisualC.Code/CodeAtom.cs

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
using System;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using System.CodeDom;
namespace Mono.VisualC.Code {
public abstract class CodeAtom {
internal protected virtual void Visit (CodeObject obj)
{
CodeObject result = obj;
while (result != null) {
if (result is CodeCompileUnit) { result = InsideCodeCompileUnit (result as CodeCompileUnit); continue; }
if (result is CodeNamespace) { result = InsideCodeNamespace (result as CodeNamespace); continue; }
if (result is CodeTypeDeclaration) { result = InsideCodeTypeDeclaration (result as CodeTypeDeclaration); continue; }
break;
}
}
internal protected virtual CodeObject InsideCodeCompileUnit (CodeCompileUnit ccu)
{
return null;
}
internal protected virtual CodeObject InsideCodeNamespace (CodeNamespace ns)
{
return null;
}
internal protected virtual CodeObject InsideCodeTypeDeclaration (CodeTypeDeclaration decl)
{
return null;
}
public abstract void Write (TextWriter writer);
}
}

40
Mono.VisualC.Code/CodeContainer.cs

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.CodeDom;
using System.CodeDom.Compiler;
namespace Mono.VisualC.Code {
public abstract class CodeContainer : CodeAtom {
private LinkedList<CodeAtom> containedAtoms;
public string IndentString {get; set;}
public CodeContainer (string indentString)
{
containedAtoms = new LinkedList<CodeAtom> ();
IndentString = indentString;
}
public CodeContainer() : this("\t")
{
}
public virtual LinkedList<CodeAtom> Atoms {
get { return containedAtoms; }
}
public override void Write (TextWriter writer)
{
IndentedTextWriter itw = new IndentedTextWriter (writer, IndentString);
itw.Indent = 1;
foreach (CodeAtom atom in containedAtoms) {
atom.Write (itw);
}
}
}
}

70
Mono.VisualC.Code/CodeUnit.cs

@ -0,0 +1,70 @@ @@ -0,0 +1,70 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.CodeDom;
namespace Mono.VisualC.Code {
public class CodeUnit : CodeContainer {
public string ManagedNamespace { get; set; }
public CodeUnit () : base (string.Empty)
{
}
public virtual CodeCompileUnit WrapperToCodeDom ()
{
CodeCompileUnit ccu = new CodeCompileUnit ();
Visit (ccu);
return ccu;
}
internal protected override CodeObject InsideCodeCompileUnit (CodeCompileUnit ccu)
{
CodeNamespace ns = new CodeNamespace (ManagedNamespace);
ns.Imports.Add (new CodeNamespaceImport ("Mono.VisualC.Interop"));
ccu.Namespaces.Add (ns);
return ns;
}
internal protected override CodeObject InsideCodeNamespace (CodeNamespace ns)
{
foreach (var atom in Atoms)
atom.Visit (ns);
return null;
}
public override string ToString ()
{
StringWriter str = new StringWriter ();
Write (str);
return str.ToString ();
}
public override void Write (TextWriter writer)
{
writer.WriteLine ("//------------------------------------------------------------------------------");
writer.WriteLine ("// <auto-generated>");
writer.WriteLine ("// This code was generated by a tool.");
writer.WriteLine ("// Runtime Version:{0}{1}//", Environment.Version, writer.NewLine);
writer.WriteLine ("// Changes to this file may cause incorrect behavior and will be lost if");
writer.WriteLine ("// the code is regenerated.");
writer.WriteLine ("// </auto-generated>");
writer.WriteLine ("//------------------------------------------------------------------------------{0}", writer.NewLine);
base.Write (writer);
}
public virtual void Save (string fileName)
{
using (StreamWriter stream = File.CreateText (fileName)) {
Write (stream);
}
}
}
}

60
Mono.VisualC.Code/Mono.VisualC.Code.csproj

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}</ProjectGuid>
<OutputType>Library</OutputType>
<AssemblyName>Mono.VisualC.Code</AssemblyName>
<RootNamespace>Mono.VisualC.Code</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="CodeAtom.cs" />
<Compile Include="Atoms\Preprocessor.cs" />
<Compile Include="CodeContainer.cs" />
<Compile Include="Atoms\Class.cs" />
<Compile Include="CodeUnit.cs" />
<Compile Include="Access.cs" />
<Compile Include="Atoms\Method.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Folder Include="Atoms\" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>
<Properties InternalTargetFrameworkVersion="3.5" />
</MonoDevelop>
</ProjectExtensions>
<ItemGroup>
<ProjectReference Include="..\Mono.VisualC.Interop\Mono.VisualC.Interop.csproj">
<Project>{4A864586-93C5-4DC1-8A80-F094A88506D7}</Project>
<Name>Mono.VisualC.Interop</Name>
</ProjectReference>
</ItemGroup>
</Project>

20
Mono.VisualC.Code/Mono.VisualC.Code.sln

@ -0,0 +1,20 @@ @@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.VisualC.Code", "Mono.VisualC.Code.csproj", "{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = Mono.VisualC.Code.csproj
EndGlobalSection
EndGlobal

54
Mono.VisualC.Interop/CppType.cs

@ -58,10 +58,28 @@ namespace Mono.VisualC.Interop { @@ -58,10 +58,28 @@ namespace Mono.VisualC.Interop {
};
*/
public static List<Func<CppType,Type>> ElementTypeToManagedMap = new List<Func<CppType, Type>> () {
(t) => { return t.ElementType == CppTypes.Class || t.ElementType == CppTypes.Struct? typeof (ICppObject) : null; },
(t) => { return t.ElementType == CppTypes.Char && t.Modifiers.Contains (CppModifiers.Pointer)? typeof (string) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Short) && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (ushort) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Long) && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (ulong) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Short)? typeof (short) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Long)? typeof (long) : null; },
(t) => { return t.ElementType == CppTypes.Int && t.Modifiers.Contains (CppModifiers.Unsigned)? typeof (uint) : null; },
(t) => { return t.ElementType == CppTypes.Void? typeof (void) : null; },
(t) => { return t.ElementType == CppTypes.Bool? typeof (bool) : null; },
(t) => { return t.ElementType == CppTypes.Char? typeof (char) : null; },
(t) => { return t.ElementType == CppTypes.Int? typeof (int) : null; },
(t) => { return t.ElementType == CppTypes.Float? typeof (float) : null; },
(t) => { return t.ElementType == CppTypes.Double? typeof (double) : null; }
};
// FIXME: Passing these as delegates allows for the flexibility of doing processing on the
// type (i.e. to correctly mangle the function pointer arguments if the managed type is a delegate),
// however this does not make it very easy to override the default mappings at runtime.
public static List<Func<Type,CppType>> ManagedTypeMap = new List<Func<Type,CppType>> () {
public static List<Func<Type,CppType>> ManagedToCppTypeMap = new List<Func<Type,CppType>> () {
(t) => { return typeof (void).Equals (t) ? CppTypes.Void : CppTypes.Unknown; },
(t) => { return typeof (bool).Equals (t) ? CppTypes.Bool : CppTypes.Unknown; },
(t) => { return typeof (char).Equals (t) ? CppTypes.Char : CppTypes.Unknown; },
@ -71,6 +89,9 @@ namespace Mono.VisualC.Interop { @@ -71,6 +89,9 @@ namespace Mono.VisualC.Interop {
(t) => { return typeof (short).Equals (t) ? new CppType (CppModifiers.Short, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (long).Equals (t) ? new CppType (CppModifiers.Long, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (uint).Equals (t) ? new CppType (CppModifiers.Unsigned, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (ushort).Equals (t)? new CppType (CppModifiers.Unsigned, CppModifiers.Short, CppTypes.Int) : CppTypes.Unknown; },
(t) => { return typeof (ulong).Equals (t)? new CppType (CppModifiers.Unsigned, CppModifiers.Long, CppTypes.Int) : CppTypes.Unknown; },
// strings mangle as "const char*" by default
(t) => { return typeof (string).Equals (t)? new CppType (CppModifiers.Const, CppTypes.Char, CppModifiers.Pointer) : CppTypes.Unknown; },
@ -231,10 +252,39 @@ namespace Mono.VisualC.Interop { @@ -231,10 +252,39 @@ namespace Mono.VisualC.Interop {
}
*/
public Type ToManagedType ()
{
return ToManagedType (false);
}
public Type ToManagedType (bool usePointerTypes)
{
CppType me = this;
Type mappedType = (from checkType in ElementTypeToManagedMap
where checkType (me) != null
select checkType (me)).FirstOrDefault ();
if (mappedType == null)
return null;
// FIXME: not ideal to have this test here
if (typeof (string).Equals (mappedType) || typeof (ICppObject).Equals (mappedType))
return mappedType;
if (Modifiers.Contains (CppModifiers.Pointer) && !usePointerTypes)
return typeof (IntPtr);
else if (Modifiers.Contains (CppModifiers.Pointer))
mappedType = mappedType.MakePointerType ();
else if (Modifiers.Contains (CppModifiers.Array))
mappedType = mappedType.MakeArrayType ();
return mappedType;
}
public static CppType ForManagedType (Type type)
{
var mappedType = (from checkType in ManagedTypeMap
var mappedType = (from checkType in ManagedToCppTypeMap
where checkType (type).ElementType != CppTypes.Unknown
select checkType (type)).FirstOrDefault ();

44
generator/Main.cs

@ -8,6 +8,12 @@ using System.Xml.Linq; @@ -8,6 +8,12 @@ using System.Xml.Linq;
using System.Collections.Generic;
using System.Linq;
using Mono.VisualC.Code;
using Mono.VisualC.Code.Atoms;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
namespace CPPInterop {
class Generator {
@ -76,7 +82,6 @@ namespace CPPInterop { @@ -76,7 +82,6 @@ namespace CPPInterop {
public void Run ()
{
XmlDocument xmldoc = new XmlDocument ();
xmldoc.Load (Source);
XmlNodeList namespaces = xmldoc.SelectNodes ("/GCC_XML/Namespace[@name != '::' and @name != '' and @name != 'std']");
@ -91,10 +96,14 @@ namespace CPPInterop { @@ -91,10 +96,14 @@ namespace CPPInterop {
if (Classes.ContainsKey (name))
continue;
var cu = new CodeUnit { ManagedNamespace = "Qt.Core" };
var classAtom = new Class (name) { StaticCppLibrary = "Qt.Libs.QtCore" };
cu.Atoms.AddLast (classAtom);
string size = clas.Attributes["size"].Value;
string members = clas.Attributes["members"].Value;
StringBuilder str = new StringBuilder();
//StringBuilder str = new StringBuilder();
foreach (string id in members.Split(new char[]{' '})) {
if (id.Equals (String.Empty))
continue;
@ -110,18 +119,27 @@ namespace CPPInterop { @@ -110,18 +119,27 @@ namespace CPPInterop {
if (n.Attributes["access"] == null || n.Attributes["access"].Value != "public")
continue;
str.Append ("\t\t\t");
//str.Append ("\t\t\t");
string mname = n.Attributes["name"].Value;
XmlNode ret = find (xmldoc.DocumentElement, n.Attributes["returns"]);
string rett = ret.Attributes["name"].Value;
bool virt = ret.Attributes["virtual"] != null && ret.Attributes["virtual"].Value == "1";
bool virt = n.Attributes["virtual"] != null && n.Attributes["virtual"].Value == "1";
bool stat = n.Attributes["static"] != null && n.Attributes["static"].Value == "1";
if (virt)
str.Append ("[Virtual] ");
str.Append (rett + " " + mname + " (CppInstancePtr @this");
//if (virt)
//str.Append ("[Virtual] ");
//str.Append (rett + " " + mname + " (CppInstancePtr @this");
List<Method.Parameter> args = new List<Method.Parameter> ();
var methodAtom = new Method (mname) {
RetType = rett,
IsVirtual = virt,
IsStatic = stat,
Parameters = args
};
int c = 0;
foreach (XmlNode arg in n.SelectNodes ("Argument")) {
@ -133,11 +151,15 @@ namespace CPPInterop { @@ -133,11 +151,15 @@ namespace CPPInterop {
XmlNode argt = find (xmldoc.DocumentElement, arg.Attributes["type"].Value);
string argtype = argt.Attributes["name"].Value;
str.Append (", " + argtype + " " + argname);
//str.Append (", " + argtype + " " + argname);
args.Add (new Method.Parameter { Name = argname, Type = argtype });
// tee hee
c++;
}
str.AppendLine (");");
//str.AppendLine (");");
classAtom.Atoms.AddLast (methodAtom);
}
Classes.Add (name, sanitize(name) + ".cs");
@ -145,6 +167,7 @@ namespace CPPInterop { @@ -145,6 +167,7 @@ namespace CPPInterop {
FileStream fs = File.Create (Path.Combine (Dir, Classes[name]));
StreamWriter sw = new StreamWriter(fs);
/*
StringBuilder sb = new StringBuilder();
string strstruct = String.Format (templateStruct, name);
string strinterface = String.Format (templateInterface, name, "", str.ToString());
@ -156,6 +179,9 @@ namespace CPPInterop { @@ -156,6 +179,9 @@ namespace CPPInterop {
strstruct,
size));
sw.Write (sb.ToString());
*/
new CSharpCodeProvider ().GenerateCodeFromCompileUnit (cu.WrapperToCodeDom (), sw, new CodeGeneratorOptions ());
sw.Flush ();
sw.Close ();
}

14
generator/generator.csproj

@ -29,22 +29,16 @@ @@ -29,22 +29,16 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AssemblyInfo.cs" />
<Compile Include="Options.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\mono\install\work\lib\mono\2.0\System.dll</HintPath>
</Reference>
<Reference Include="System.Xml">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\mono\install\work\lib\mono\2.0\System.Xml.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\mono\install\work\lib\mono\2.0\System.Xml.Linq.dll</HintPath>
</Reference>
<Reference Include="System.Core" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
@ -63,4 +57,10 @@ @@ -63,4 +57,10 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Mono.VisualC.Code\Mono.VisualC.Code.csproj">
<Project>{A22BF9D9-BBCB-4462-BE08-0F4D5280B180}</Project>
<Name>Mono.VisualC.Code</Name>
</ProjectReference>
</ItemGroup>
</Project>
Loading…
Cancel
Save