Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@927 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
12 changed files with 1083 additions and 0 deletions
@ -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.*")] |
||||||
|
|
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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
|
||||||
|
} |
||||||
|
} |
Binary file not shown.
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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;
|
||||||
|
//}
|
||||||
|
} |
||||||
|
} |
@ -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> |
@ -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 |
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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…
Reference in new issue