codegenerator.cs
来自「SharpDevelop2.0.0 c#开发免费工具」· CS 代码 · 共 688 行 · 第 1/2 页
CS
688 行
// <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 =
@" ~TheType()" + "\r\n" +
@" {" + "\r\n" +
@" object o = wrappedObject;" + "\r\n" +
@" wrappedObject = null;" + "\r\n" +
@" ResourceManager.ReleaseCOMObject(o, typeof(TheType));" + "\r\n" +
@" }" + "\r\n" +
@" " + "\r\n" +
@" 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.IsPartial = true;
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")));
codeConstructor.Statements.Add(
new CodeMethodInvokeExpression(
new CodeMethodReferenceExpression(
new CodeTypeReferenceExpression("ResourceManager"),
"TrackCOMObject"),
new CodeArgumentReferenceExpression("wrappedObject"),
new CodeTypeOfExpression(type.Name)));
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(
// if
new CodeConditionStatement(
// objectToWrap != null
new CodeBinaryOperatorExpression(
new CodeArgumentReferenceExpression("objectToWrap"),
CodeBinaryOperatorType.IdentityInequality,
new CodePrimitiveExpression(null)),
// return new TheType(objectToWrap);
new CodeStatement[] {
new CodeMethodReturnStatement(
new CodeObjectCreateExpression(
wrappedType.Name,
new CodeArgumentReferenceExpression("objectToWrap")))},
// else return null;
new CodeStatement[] {
new CodeMethodReturnStatement(
new CodePrimitiveExpression(null))}));
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"),
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?