Browse Source

Added WrapperGenerator

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@927 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 20 years ago
parent
commit
e097527450
  1. 27
      src/Tools/WrapperGenerator/AssemblyInfo.cs
  2. 615
      src/Tools/WrapperGenerator/CodeGenerator.cs
  3. 46
      src/Tools/WrapperGenerator/CorDebugGenerator.cs
  4. 69
      src/Tools/WrapperGenerator/FileGenerator.cs
  5. 85
      src/Tools/WrapperGenerator/MainForm.cs
  6. BIN
      src/Tools/WrapperGenerator/MainForm.resources
  7. 53
      src/Tools/WrapperGenerator/Test.cs
  8. 25
      src/Tools/WrapperGenerator/Wrapper.cs
  9. 43
      src/Tools/WrapperGenerator/WrapperGenerator.csproj
  10. 16
      src/Tools/WrapperGenerator/WrapperGenerator.sln
  11. 87
      src/Tools/WrapperGenerator/WrapperProxy.cs
  12. 17
      src/Tools/WrapperGenerator/WrappingClassAttribute.cs

27
src/Tools/WrapperGenerator/AssemblyInfo.cs

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly: AssemblyVersion("1.0.*")]

615
src/Tools/WrapperGenerator/CodeGenerator.cs

@ -0,0 +1,615 @@ @@ -0,0 +1,615 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Microsoft.CSharp;
namespace WrapperGenerator
{
public class CodeGenerator
{
Assembly assembly;
protected string wrapperNamespace;
string comparsionCode =
@" public bool Is<T>() where T: class" + "\r\n" +
@" {" + "\r\n" +
@" try {" + "\r\n" +
@" CastTo<T>();" + "\r\n" +
@" return true;" + "\r\n" +
@" } catch {" + "\r\n" +
@" return false;" + "\r\n" +
@" }" + "\r\n" +
@" }" + "\r\n" +
@" " + "\r\n" +
@" public T As<T>() where T: class" + "\r\n" +
@" {" + "\r\n" +
@" try {" + "\r\n" +
@" return CastTo<T>();" + "\r\n" +
@" } catch {" + "\r\n" +
@" return null;" + "\r\n" +
@" }" + "\r\n" +
@" }" + "\r\n" +
@" " + "\r\n" +
@" public T CastTo<T>() where T: class" + "\r\n" +
@" {" + "\r\n" +
@" return (T)Activator.CreateInstance(typeof(T), this.WrappedObject);" + "\r\n" +
@" }" + "\r\n" +
@" " + "\r\n" +
@" public static bool operator ==(TheType o1, TheType o2)" + "\r\n" +
@" {" + "\r\n" +
@" return ((object)o1 == null && (object)o2 == null) ||" + "\r\n" +
@" ((object)o1 != null && (object)o2 != null && o1.WrappedObject == o2.WrappedObject);" + "\r\n" +
@" }" + "\r\n" +
@" " + "\r\n" +
@" public static bool operator !=(TheType o1, TheType o2)" + "\r\n" +
@" {" + "\r\n" +
@" return !(o1 == o2);" + "\r\n" +
@" }" + "\r\n" +
@" " + "\r\n" +
@" public override int GetHashCode()" + "\r\n" +
@" {" + "\r\n" +
@" return base.GetHashCode();" + "\r\n" +
@" }" + "\r\n" +
@" " + "\r\n" +
@" public override bool Equals(object o)" + "\r\n" +
@" {" + "\r\n" +
@" TheType casted = o as TheType;" + "\r\n" +
@" return (casted != null) && (casted.WrappedObject == wrappedObject);" + "\r\n" +
@" }" + "\r\n" +
@" ";
public CodeGenerator(Assembly assembly)
{
this.assembly = assembly;
}
protected virtual bool ShouldIncludeType(Type type)
{
return true;
}
protected virtual Type GetBaseClass(Type type)
{
return null;
}
public IEnumerable<CodeCompileUnit> MakeCompileUnits()
{
foreach(Type type in assembly.GetTypes()) {
if (!ShouldIncludeType(type)) continue;
CodeCompileUnit codeCompileUnit;
codeCompileUnit = new CodeCompileUnit();
codeCompileUnit.UserData.Add("filename", type.Name);
codeCompileUnit.Namespaces.Add(MakeNamespace(type));
yield return codeCompileUnit;
}
}
CodeNamespace MakeNamespace(Type type)
{
CodeNamespace codeNamespace = new CodeNamespace(wrapperNamespace);
codeNamespace.Imports.Add(new CodeNamespaceImport("System"));
codeNamespace.Types.Add(MakeTypeDeclaration(type));
return codeNamespace;
}
CodeTypeDeclaration MakeTypeDeclaration(Type type)
{
if (type.IsEnum) {
return MakeEnumDeclaration(type);
} else {
return MakeClassDeclaration(type);
}
}
CodeTypeDeclaration MakeEnumDeclaration(Type type)
{
CodeTypeDeclaration enumDeclaration = new CodeTypeDeclaration();
enumDeclaration.Attributes = MemberAttributes.Private;
enumDeclaration.Name = type.Name;
enumDeclaration.IsEnum = true;
enumDeclaration.BaseTypes.Add(Enum.GetUnderlyingType(type));
if (type.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0) {
enumDeclaration.CustomAttributes.Add(new CodeAttributeDeclaration("Flags"));
}
foreach(string name in Enum.GetNames(type)) {
CodeMemberField field = new CodeMemberField();
field.Name = name;
object val = Convert.ChangeType(Enum.Parse(type, name), Enum.GetUnderlyingType(type));
field.InitExpression = new CodePrimitiveExpression(val);
enumDeclaration.Members.Add(field);
}
return enumDeclaration;
}
CodeTypeDeclaration MakeClassDeclaration(Type type)
{
Type baseType = GetBaseClass(type);
CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration();
codeTypeDeclaration.Attributes = MemberAttributes.Private;
codeTypeDeclaration.Name = type.Name;
if (baseType != null) {
codeTypeDeclaration.BaseTypes.Add(baseType.Name);
}
codeTypeDeclaration.Members.Add(MakeWrappedObjectField(type));
codeTypeDeclaration.Members.Add(MakeWrappedObjectProperty(type));
codeTypeDeclaration.Members.Add(MakeConstructor(type));
//codeTypeDeclaration.Members.Add(MakeCanWrapMethod(type));
codeTypeDeclaration.Members.Add(MakeWrapMethod(type));
codeTypeDeclaration.Members.Add(new CodeSnippetTypeMember(comparsionCode.Replace("TheType", type.Name)));
codeTypeDeclaration.Members.AddRange(MakeMembers(type));
return codeTypeDeclaration;
}
CodeMemberField MakeWrappedObjectField(Type type)
{
CodeMemberField codeWrappedObjectField = new CodeMemberField();
codeWrappedObjectField.Attributes = MemberAttributes.Private;
codeWrappedObjectField.Type = new CodeTypeReference(type.FullName);
codeWrappedObjectField.Name = "wrappedObject";
return codeWrappedObjectField;
}
CodeExpression ExpressionForWrappedObjectField {
get {
return new CodeFieldReferenceExpression(
new CodeThisReferenceExpression(),
"wrappedObject");
}
}
CodeMemberProperty MakeWrappedObjectProperty(Type type)
{
CodeMemberProperty codeWrappedObjectProperty = new CodeMemberProperty();
codeWrappedObjectProperty.Attributes = MemberAttributes.Assembly | MemberAttributes.Final;
codeWrappedObjectProperty.Type = new CodeTypeReference(type.FullName);
codeWrappedObjectProperty.Name = "WrappedObject";
codeWrappedObjectProperty.HasGet = true;
codeWrappedObjectProperty.HasSet = false;
CodeMethodReturnStatement codeGetter = new CodeMethodReturnStatement(ExpressionForWrappedObjectField);
codeWrappedObjectProperty.GetStatements.Add(codeGetter);
return codeWrappedObjectProperty;
}
CodeExpression ExpressionForWrappedObjectProperty {
get {
return new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "WrappedObject");
}
}
CodeConstructor MakeConstructor(Type type)
{
Type baseType = GetBaseClass(type);
CodeConstructor codeConstructor = new CodeConstructor();
codeConstructor.Attributes = MemberAttributes.Public;
codeConstructor.Parameters.Add(new CodeParameterDeclarationExpression(type, "wrappedObject"));
if (baseType != null) {
codeConstructor.BaseConstructorArgs.Add(
new CodeCastExpression(
GetBaseClass(type).FullName,
new CodeArgumentReferenceExpression("wrappedObject")));
}
codeConstructor.Statements.Add(
new CodeAssignStatement(
ExpressionForWrappedObjectField,
new CodeArgumentReferenceExpression("wrappedObject")));
return codeConstructor;
}
/*
CodeMemberMethod MakeCanWrapMethod(Type wrappedType)
{
CodeMemberMethod method = new CodeMemberMethod();
method.Attributes = MemberAttributes.Static | MemberAttributes.Public;
method.ReturnType = new CodeTypeReference(typeof(bool));
method.Name = "CanWrap";
method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "objectToWrap"));
method.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression("objectToWrap is " + wrappedType.FullName)));
return method;
}
*/
CodeMemberMethod MakeWrapMethod(Type wrappedType)
{
CodeMemberMethod method = new CodeMemberMethod();
method.Attributes = MemberAttributes.Static | MemberAttributes.Public;
method.ReturnType = new CodeTypeReference(wrappedType.Name);
method.Name = "Wrap";
method.Parameters.Add(new CodeParameterDeclarationExpression(wrappedType, "objectToWrap"));
/*
foreach(Type type in wrappedType.Assembly.GetTypes()) {
if (ShouldIncludeType(type) && GetBaseClass(type).Name == wrappedType.Name) {
method.Statements.Add(
new CodeConditionStatement(
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodeTypeReferenceExpression(type.Name),
"CanWrap"),
new CodeArgumentReferenceExpression("objectToWrap")),
new CodeMethodReturnStatement(
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodeTypeReferenceExpression(type.Name),
"Wrap"),
new CodeCastExpression(
namespaceToWrap + "." + type.Name,
new CodeArgumentReferenceExpression("objectToWrap"))))));
}
}
*/
method.Statements.Add(
new CodeMethodReturnStatement(
new CodeObjectCreateExpression(
wrappedType.Name,
new CodeArgumentReferenceExpression("objectToWrap"))));
return method;
}
CodeTypeMember[] MakeMembers(Type type)
{
List<CodeTypeMember> codeTypeMembers = new List<CodeTypeMember>();
foreach(MethodInfo method in type.GetMethods()) {
if (method.DeclaringType == type) {
codeTypeMembers.Add(MakeMember(method));
}
}
return codeTypeMembers.ToArray();
}
CodeExpression Unwrap(Type rawType, CodeExpression codeExpression)
{
if (rawType.IsEnum) {
return new CodeCastExpression(
new CodeTypeReference(rawType),
codeExpression);
} else {
return new CodePropertyReferenceExpression(codeExpression, "WrappedObject");
}
}
CodeExpression Wrap(Type rawType, CodeExpression codeExpression)
{
if (rawType.IsEnum) {
return new CodeCastExpression(
new CodeTypeReference(rawType.Name),
codeExpression);
} else {
return new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodeTypeReferenceExpression(rawType.Name),
"Wrap"),
codeExpression);
}
}
class MethodContext
{
CodeMemberMethod codeMemberMethod = new CodeMemberMethod();
CodeGenerator generator;
public string Name;
public bool IsReturnTypeWrapped;
public Type RawReturnType;
public string WrappedReturnType;
public List<CodeParameterDeclarationExpression> WrapperParams = new List<CodeParameterDeclarationExpression>();
public List<CodeStatement> DoBeforeInvoke = new List<CodeStatement>();
public List<CodeExpression> BaseMethodInvokeParams = new List<CodeExpression>();
public List<CodeStatement> DoAfterInvoke = new List<CodeStatement>();
public MethodContext(CodeGenerator generator, MethodInfo method)
{
this.generator = generator;
Name = method.Name;
RawReturnType = method.ReturnType;
IsReturnTypeWrapped = generator.ShouldIncludeType(method.ReturnType);
if (IsReturnTypeWrapped) {
WrappedReturnType = method.ReturnType.Name;
} else {
WrappedReturnType = method.ReturnType.FullName;
}
codeMemberMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
codeMemberMethod.ReturnType = new CodeTypeReference(WrappedReturnType);
codeMemberMethod.Name = method.Name;
}
public CodeMemberMethod Emit()
{
CodeExpression baseInvoke =
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
generator.ExpressionForWrappedObjectProperty,
Name),
BaseMethodInvokeParams.ToArray());
if (IsReturnTypeWrapped) {
baseInvoke = generator.Wrap(RawReturnType, baseInvoke);
}
CodeStatement doInvoke;
if (WrappedReturnType != typeof(void).FullName) {
if (DoAfterInvoke.Count == 0) {
doInvoke = new CodeMethodReturnStatement(baseInvoke);
} else {
DoBeforeInvoke.Insert(0,
new CodeVariableDeclarationStatement(WrappedReturnType, "returnValue"));
doInvoke =
new CodeAssignStatement(
new CodeVariableReferenceExpression("returnValue"),
baseInvoke);
DoAfterInvoke.Add(
new CodeMethodReturnStatement(
new CodeVariableReferenceExpression("returnValue")));
}
} else {
doInvoke = new CodeExpressionStatement(baseInvoke);
}
codeMemberMethod.Statements.AddRange(DoBeforeInvoke.ToArray());
codeMemberMethod.Statements.Add(doInvoke);
codeMemberMethod.Statements.AddRange(DoAfterInvoke.ToArray());
codeMemberMethod.Parameters.AddRange(WrapperParams.ToArray());
return codeMemberMethod;
}
}
class ParamContext
{
public string Name;
public bool IsWrapped;
public string WrappedType;
public Type RawType;
public CodeTypeReference TypeRef;
public FieldDirection Direction;
public CodeParameterDeclarationExpression ArgDeclaration;
public CodeArgumentReferenceExpression ArgRefExpression;
public CodeExpression UnwrappedArgExpression;
public CodeExpression UnwrappedDirectionalArgExpression;
public ParamContext(CodeGenerator generator, ParameterInfo par)
{
Name = par.Name;
if (par.ParameterType.IsByRef) {
RawType = par.ParameterType.GetElementType();
} else {
RawType = par.ParameterType;
}
IsWrapped = generator.ShouldIncludeType(RawType);
WrappedType = IsWrapped ? RawType.Name : RawType.FullName;
TypeRef = new CodeTypeReference(WrappedType);
if (!par.ParameterType.IsByRef) {
Direction = FieldDirection.In;
} else if (par.IsOut) {
Direction = FieldDirection.Out;
} else {
Direction = FieldDirection.Ref;
}
ArgDeclaration = new CodeParameterDeclarationExpression();
ArgDeclaration.Type = TypeRef;
ArgDeclaration.Name = par.Name;
ArgDeclaration.Direction = Direction;
ArgRefExpression = new CodeArgumentReferenceExpression(par.Name);
UnwrappedArgExpression = IsWrapped?generator.Unwrap(RawType, ArgRefExpression):ArgRefExpression;
UnwrappedDirectionalArgExpression = new CodeDirectionExpression(Direction, UnwrappedArgExpression);
}
}
CodeMemberMethod MakeMember(MethodInfo method)
{
MethodContext methodContext = new MethodContext(this, method);
foreach(ParameterInfo par in method.GetParameters()) {
ParamContext parContext = new ParamContext(this, par);
if (parContext.IsWrapped) {
if (parContext.Direction == FieldDirection.In) {
if (par.ParameterType.IsArray) {
UnwrapArrayArgument(methodContext, parContext);
} else {
UnwrapArgument(methodContext, parContext);
}
} else {
UnwrapRefArgument(methodContext, parContext);
}
} else {
PassArgument(methodContext, parContext);
}
}
return methodContext.Emit();
}
void PassArgument(MethodContext methodContext, ParamContext parContext)
{
methodContext.WrapperParams.Add(parContext.ArgDeclaration);
methodContext.BaseMethodInvokeParams.Add(parContext.UnwrappedDirectionalArgExpression);
}
void UnwrapArgument(MethodContext methodContext, ParamContext parContext)
{
methodContext.WrapperParams.Add(parContext.ArgDeclaration);
methodContext.BaseMethodInvokeParams.Add(parContext.UnwrappedDirectionalArgExpression);
}
void UnwrapRefArgument(MethodContext methodContext, ParamContext parContext)
{
methodContext.WrapperParams.Add(parContext.ArgDeclaration);
CodeVariableDeclarationStatement tmpVariableDeclaration = new CodeVariableDeclarationStatement(parContext.RawType, ((parContext.Direction==FieldDirection.Ref)?"ref":"out") + "_" + parContext.Name);
if (parContext.Direction == FieldDirection.Ref) {
tmpVariableDeclaration.InitExpression = parContext.UnwrappedArgExpression;
}
CodeExpression tmpVariableExpression = new CodeVariableReferenceExpression(tmpVariableDeclaration.Name);
CodeExpression tmpVariableDirectionalExpression = new CodeDirectionExpression(parContext.Direction, tmpVariableExpression);
methodContext.DoBeforeInvoke.Add(tmpVariableDeclaration);
methodContext.BaseMethodInvokeParams.Add(tmpVariableDirectionalExpression);
CodeAssignStatement assignExpression = new CodeAssignStatement(parContext.ArgRefExpression, Wrap(parContext.RawType, tmpVariableExpression));
methodContext.DoAfterInvoke.Add(assignExpression);
}
void UnwrapArrayArgument(MethodContext methodContext, ParamContext parContext)
{
//OUTPUT:
//
// public void void__array(Test[] arg)
// {
// Debugger.Interop.CorDebug.Test[] array_arg = new Debugger.Interop.CorDebug.Test[arg.Length];
// for (int i = 0; (i < arg.Length); i = (i + 1))
// {
// if ((arg[i] != null))
// {
// array_arg[i] = arg[i].WrappedObject;
// }
// }
// this.WrappedObject.void__array(array_arg);
// for (int i = 0; (i < arg.Length); i = (i + 1))
// {
// if ((array_arg[i] != null))
// {
// arg[i] = Test.Wrap(array_arg[i]);
// } else
// {
// arg[i] = null;
// }
// }
// }
methodContext.WrapperParams.Add(parContext.ArgDeclaration);
string rawArrayName = "array_" + parContext.Name;
CodeExpression arg_Length =
// arg.Length
new CodePropertyReferenceExpression(parContext.ArgRefExpression, "Length");
CodeExpression i =
// i
new CodeVariableReferenceExpression("i");
CodeStatement loopInit =
// int i = 0
new CodeVariableDeclarationStatement(typeof(int), "i", new CodePrimitiveExpression(0));
CodeExpression loopCondition =
// (i < arg.Length)
new CodeBinaryOperatorExpression(
i,
CodeBinaryOperatorType.LessThan,
arg_Length);
CodeStatement loopIteration =
// i = (i + 1)
new CodeAssignStatement(
i,
new CodeBinaryOperatorExpression(
i,
CodeBinaryOperatorType.Add,
new CodePrimitiveExpression(1)));
CodeExpression arg_i =
// arg[i]
new CodeIndexerExpression(
parContext.ArgRefExpression,
i);
CodeVariableReferenceExpression array_arg =
// array_arg
new CodeVariableReferenceExpression(rawArrayName);
CodeExpression array_arg_i =
// array_arg[i]
new CodeIndexerExpression(
array_arg,
i);
// Debugger.Interop.CorDebug.Test[] array_arg = new Debugger.Interop.CorDebug.Test[arg.Length];
methodContext.DoBeforeInvoke.Add(
new CodeVariableDeclarationStatement(
new CodeTypeReference(parContext.RawType),
array_arg.VariableName,
new CodeArrayCreateExpression(parContext.RawType, arg_Length)));
methodContext.DoBeforeInvoke.Add(
new CodeIterationStatement(
loopInit,
loopCondition,
loopIteration,
// if
new CodeConditionStatement(
// (arg[i] != null)
new CodeBinaryOperatorExpression(
arg_i,
CodeBinaryOperatorType.IdentityInequality,
new CodePrimitiveExpression(null)),
// array_arg[i] = arg[i].WrappedObject;
new CodeAssignStatement(
array_arg_i,
Unwrap(parContext.RawType, arg_i)))));
methodContext.DoAfterInvoke.Add(
new CodeIterationStatement(
loopInit,
loopCondition,
loopIteration,
// if
new CodeConditionStatement(
// (array_arg[i] != null)
new CodeBinaryOperatorExpression(
array_arg_i,
CodeBinaryOperatorType.IdentityInequality,
new CodePrimitiveExpression(null)),
//
new CodeStatement [] {
// arg[i] = Test.Wrap(array_arg[i]);
new CodeAssignStatement(
arg_i,
Wrap(
parContext.RawType.Assembly.GetType(parContext.RawType.FullName.Replace("[]","")),
array_arg_i))},
// else
new CodeStatement [] {
// arg[i] = null;
new CodeAssignStatement(
arg_i,
new CodePrimitiveExpression(null))})));
methodContext.BaseMethodInvokeParams.Add(array_arg);
}
}
}

46
src/Tools/WrapperGenerator/CorDebugGenerator.cs

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Microsoft.CSharp;
namespace WrapperGenerator
{
public class CorDebugGenerator: CodeGenerator
{
string namespaceToWrap = "Debugger.Interop.CorDebug";
public CorDebugGenerator(Assembly assembly):base(assembly)
{
wrapperNamespace = "Debugger.Wrappers.CorDebug";
}
protected override bool ShouldIncludeType(Type type)
{
return type.Namespace == namespaceToWrap &&
(type.IsClass || type.IsInterface || type.IsEnum);
}
protected override Type GetBaseClass(Type type)
{
// Type[] interfaces = type.GetInterfaces();
// if (interfaces.Length > 0) {
// return interfaces[0];
// }
// if (type.Name.EndsWith("2")) {
// return type.Assembly.GetType(type.FullName.Remove(type.FullName.Length - 1));
// }
return null;
}
}
}

69
src/Tools/WrapperGenerator/FileGenerator.cs

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Microsoft.CSharp;
namespace WrapperGenerator
{
public class FileGenerator
{
CodeGenerator codeGenerator;
string header;
public FileGenerator(CodeGenerator codeGenerator, string header)
{
this.codeGenerator = codeGenerator;
this.header = header;
}
public string SaveFiles(string saveDirectory)
{
string allCode = "";
foreach(CodeCompileUnit compileUnit in codeGenerator.MakeCompileUnits()) {
string code = GenerateCode(compileUnit);
code = code.Remove(0, code.IndexOf("namespace"));
allCode += code;
string className = (string)compileUnit.UserData["filename"];
TextWriter textWriter = new StreamWriter(Path.Combine(saveDirectory, className + ".cs"));
textWriter.Write(header);
textWriter.Write(code);
textWriter.Close();
}
return allCode;
}
string GenerateCode(CodeCompileUnit compileUnit)
{
CSharpCodeProvider provider = new CSharpCodeProvider();
TextWriter stringWriter = new StringWriter();
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BlankLinesBetweenMembers = true;
options.BracingStyle = "C";
options.ElseOnClosing = true;
options.IndentString = "\t";
options.VerbatimOrder = true;
provider.GenerateCodeFromCompileUnit(compileUnit, stringWriter, options);
return stringWriter.ToString();
}
}
}

85
src/Tools/WrapperGenerator/MainForm.cs

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections.Generic;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using Microsoft.CSharp;
namespace WrapperGenerator
{
public class MainForm : System.Windows.Forms.Form
{
string header =
"// <file>" + "\r\n" +
"// <copyright see=\"prj:///doc/copyright.txt\"/>" + "\r\n" +
"// <license see=\"prj:///doc/license.txt\"/>" + "\r\n" +
"// <owner name=\"David Srbecký\" email=\"dsrbecky@gmail.com\"/>" + "\r\n" +
"// <version>$Revision$</version>" + "\r\n" +
"// </file>" + "\r\n" +
"\r\n";
//string dllFileName = Assembly.GetExecutingAssembly().Location;
string dllFileName = Path.Combine(Assembly.GetExecutingAssembly().Location, @"..\..\..\..\..\..\AddIns\AddIns\Misc\Debugger\Debugger.Core.dll");
string saveDirectory = Path.Combine(Assembly.GetExecutingAssembly().Location, @"..\..\..\..\..\..\src\AddIns\Misc\Debugger\Debugger.Core\Project\Src\Wrappers\CorDebug");
public MainForm()
{
InitializeComponent();
CodeGenerator codeGenerator = new CorDebugGenerator(Assembly.LoadFile(dllFileName));
textBox1.Text = new FileGenerator(codeGenerator, header).SaveFiles(saveDirectory);
}
[STAThread]
public static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
#region Windows Forms Designer generated code
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(949, 717);
//
// textBox1
//
textBox1.Dock = System.Windows.Forms.DockStyle.Fill;
textBox1.Location = new System.Drawing.Point(0, 0);
textBox1.Multiline = true;
textBox1.Name = "textBox1";
textBox1.ScrollBars = System.Windows.Forms.ScrollBars.Both;
textBox1.Size = new System.Drawing.Size(949, 717);
textBox1.TabIndex = 0;
this.Controls.Add(textBox1);
this.Name = "MainForm";
this.Text = "MainForm";
this.PerformLayout();
this.ResumeLayout(false);
}
private System.Windows.Forms.TextBox textBox1;
#endregion
}
}

BIN
src/Tools/WrapperGenerator/MainForm.resources

Binary file not shown.

53
src/Tools/WrapperGenerator/Test.cs

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
namespace Debugger.Interop.CorDebug
{
[Flags]
public enum Enumeration:byte { A = 1, B = 2, C = 4, D = 16 };
public interface Test {
// Return values
void void__void();
int int__void();
string string__void();
Test Test__void();
// Direction of parameter - base type
void void__inString(string str);
void void__outString(out string str);
void void__refString(ref string str);
// Direction of parameter - wrapped type
void void__inTest(Test str);
void void__outTest(out Test t);
void void__refTest(ref Test t);
// Direction of many parameters + return value - base type
void void__out_ref_in_out_ref__string(out string p1, ref string p2, string p3, out string p4, ref string p5);
string string__out_ref_in_out_ref__string(out string p1, ref string p2, string p3, out string p4, ref string p5);
// Direction of many parameters + return value - wrapped type
void void__out_ref_in_out_ref__Test(out Test p1, ref Test p2, Test p3, out Test p4, ref Test p5);
Test Test__out_ref_in_out_ref__Test(out Test p1, ref Test p2, Test p3, out Test p4, ref Test p5);
// Arrays
void void__array(Test[] arg);
}
}

25
src/Tools/WrapperGenerator/Wrapper.cs

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
namespace Debugger.Wrappers.CorDebug
{
using System;
public abstract class Wrapper : MarshalByRefObject
{
public abstract object WrappedObject
{
get;
}
//public staticType WrappedObjectType
//{
// get;
//}
}
}

43
src/Tools/WrapperGenerator/WrapperGenerator.csproj

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<RootNamespace>WrapperGenerator</RootNamespace>
<AssemblyName>WrapperGenerator</AssemblyName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7ED425D8-30CA-422C-90DF-1CB901E46DE3}</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugSymbols>True</DebugSymbols>
<DebugType>Full</DebugType>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<Optimize>True</Optimize>
<DefineConstants>TRACE</DefineConstants>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs" />
<Compile Include="AssemblyInfo.cs" />
<EmbeddedResource Include="MainForm.resources" />
<Compile Include="CodeGenerator.cs" />
<Compile Include="CorDebugGenerator.cs" />
<Compile Include="Test.cs" />
<Compile Include="FileGenerator.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

16
src/Tools/WrapperGenerator/WrapperGenerator.sln

@ -0,0 +1,16 @@ @@ -0,0 +1,16 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# SharpDevelop 2.0.0.920
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WrapperGenerator", "WrapperGenerator.csproj", "{7ED425D8-30CA-422C-90DF-1CB901E46DE3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7ED425D8-30CA-422C-90DF-1CB901E46DE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7ED425D8-30CA-422C-90DF-1CB901E46DE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7ED425D8-30CA-422C-90DF-1CB901E46DE3}.Release|Any CPU.Build.0 = Release|Any CPU
{7ED425D8-30CA-422C-90DF-1CB901E46DE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
EndGlobalSection
EndGlobal

87
src/Tools/WrapperGenerator/WrapperProxy.cs

@ -0,0 +1,87 @@ @@ -0,0 +1,87 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
namespace Debugger.Wrappers.CorDebug
{
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Messaging;
public class WrapperProxy : RealProxy, IRemotingTypeInfo
{
Hashtable wrappingClassCache = new Hashtable();
MarshalByRefObject wrappedComObject;
public WrapperProxy(MarshalByRefObject objectToWrapp) :
base (typeof(MarshalByRefObject))
{
wrappedObject = objectToWrapp;
}
void GetWrappingClass(Type interfaceType)
{
object cachedItem = wrappingClassCache[interfaceType];
if (cachedItem != null) {
return cachedItem;
}
interfaceType.GetCustomAttributes(typeof(WrappingClassAttribute), false);
// TODO
Type wrappingClassType;
object wrappingClass = Activator.CreateInstance(wrappingClassType, wrappedComObject);
wrappingClassCache.Add(interfaceType, wrappingClass);
}
public override IMessage Invoke(IMessage msg)
{
Type interfaceType = (msg as IMethodCallMessage).MethodBase.ReflectedType;
MarshalByRefObject wrappingClass = GetWrappingClass(wrappingClassType);
return RemotingServices.ExecuteMessage(wrappingClass, msg as IMethodCallMessage);
}
public string TypeName {
get {
return wrappedObject.GetType().FullName;
}
set {
throw new NotImplementedException();
}
}
public bool CanCastTo(Type type, object o)
{
Wrapper wrappedObject = o as Wrapper;
if (wrappedObject == null) {
return false;
}
if (!type.IsSubclassOf(typeof(Wrapper))) {
return false;
}
try {
Activator.CreateInstance(type, wrappedObject.WrappedObject);
return true;
}
catch {
return false;
}
}
}
}

17
src/Tools/WrapperGenerator/WrappingClassAttribute.cs

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="David Srbecký" email="dsrbecky@gmail.com"/>
// <version>$Revision$</version>
// </file>
namespace Debugger.Wrappers.CorDebug
{
using System;
public class WrappingClassAttribute
{
}
}
Loading…
Cancel
Save