1
0
mirror of https://github.com/twiglet/cs2j.git synced 2025-01-18 13:15:17 +01:00
2010-10-20 18:51:41 +02:00

286 lines
8.9 KiB
C#

using System;
using System.Reflection;
using RusticiSoftware.Translator.CLR;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using RusticiSoftware.Translator.Utils;
using System.Text;
using NDesk.Options;
using System.Collections.Generic;
namespace cs2j.Template.Utils
{
public class TemplateFromDLL
{
private Assembly assembly = null;
private int verbose = 0;
public TemplateFromDLL (string DLLFileName)
{
assembly = Assembly.LoadFile(DLLFileName);
}
public TemplateFromDLL ()
{
}
public void listTypes(string DLLFileName) {
Assembly testAssembly = Assembly.LoadFile(DLLFileName);
Type[] exportedTypes = testAssembly.GetExportedTypes();
Console.WriteLine ("Enums:");
foreach (Type item in exportedTypes) {
if (item.IsEnum) {
Console.WriteLine (" * " + TypeHelper.buildTypeName(item));
}
}
Console.WriteLine ("Interfaces:");
foreach (Type item in exportedTypes) {
if (item.IsInterface) {
Console.WriteLine (" * " + TypeHelper.buildTypeName(item));
}
}
Console.WriteLine ("Classes:");
foreach (Type item in exportedTypes) {
if (item.IsClass) {
Console.WriteLine (" * " + TypeHelper.buildTypeName(item));
}
}
Console.WriteLine ("Arrays:");
foreach (Type item in exportedTypes) {
if (item.IsArray) {
Console.WriteLine (" * " + TypeHelper.buildTypeName(item));
}
}
Console.WriteLine ("Others:");
foreach (Type item in exportedTypes) {
if (!item.IsEnum && !item.IsInterface && !item.IsClass && !item.IsArray) {
Console.WriteLine (" * " + TypeHelper.buildTypeName(item));
}
}
}
private void buildParameters(ConstructorRepTemplate c, MethodBase m) {
foreach (ParameterInfo p in m.GetParameters()) {
ParamRepTemplate paramRep = new ParamRepTemplate();
paramRep.Type = TypeHelper.buildTypeName(p.ParameterType);
paramRep.Name = p.Name;
c.Params.Add(paramRep);
}
}
private void buildInterface(InterfaceRepTemplate iface, Type t) {
if (t.IsGenericType) {
iface.TypeName = t.GetGenericTypeDefinition().FullName;
string[] tParams = new string[t.GetGenericArguments().Length];
for (int i = 0; i < t.GetGenericArguments().Length; i++) {
tParams[i] = t.GetGenericArguments()[i].Name;
}
iface.TypeParams = tParams;
}
else {
iface.TypeName = t.FullName;
}
List<String> bases = new List<String>();
if (t.BaseType != null)
bases.Add(TypeHelper.buildTypeName(t.BaseType));
foreach (Type iTy in t.GetInterfaces()) {
bases.Add(TypeHelper.buildTypeName(iTy));
}
iface.Inherits = bases.ToArray();
// Grab Methods
foreach (MethodInfo m in t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance)) {
if (m.IsSpecialName) {
// e.g., a property's getter / setter method
continue;
}
MethodRepTemplate methRep = new MethodRepTemplate();
methRep.Name = m.Name;
methRep.Return = TypeHelper.buildTypeName(m.ReturnType);
if (m.IsGenericMethod) {
string[] tParams = new string[m.GetGenericArguments().Length];
for (int i = 0; i < m.GetGenericArguments().Length; i++) {
tParams[i] = m.GetGenericArguments()[i].Name;
}
methRep.TypeParams = tParams;
}
buildParameters(methRep, m);
if (m.IsStatic) {
methRep.IsStatic = true;
}
methRep.SurroundingTypeName = iface.TypeName;
iface.Methods.Add(methRep);
}
// Grab Properties
foreach (PropertyInfo p in t.GetProperties()) {
PropRepTemplate propRep = new PropRepTemplate();
propRep.Name = p.Name;
propRep.Type = TypeHelper.buildTypeName(p.PropertyType);
propRep.CanRead = p.CanRead;
propRep.CanWrite = p.CanWrite;
iface.Properties.Add(propRep);
}
// Grab Events
foreach (EventInfo e in t.GetEvents()) {
FieldRepTemplate eventRep = new FieldRepTemplate();
eventRep.Name = e.Name;
eventRep.Type = TypeHelper.buildTypeName(e.EventHandlerType);
iface.Events.Add(eventRep);
}
}
private void buildClass(ClassRepTemplate klass, Type t) {
// Grab common fields
buildInterface(klass, t);
// Grab Constructors
foreach (ConstructorInfo c in t.GetConstructors()) {
ConstructorRepTemplate consRep = new ConstructorRepTemplate();
buildParameters(consRep, c);
consRep.SurroundingTypeName = klass.TypeName;
klass.Constructors.Add(consRep);
}
// Grab Fields
foreach (FieldInfo f in t.GetFields()) {
FieldRepTemplate fieldRep = new FieldRepTemplate();
fieldRep.Name = f.Name;
fieldRep.Type = TypeHelper.buildTypeName(f.FieldType);
klass.Fields.Add(fieldRep);
}
// Grab Casts
foreach (MethodInfo m in t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static )) {
if (m.IsSpecialName && (m.Name == "op_Explicit" || m.Name == "op_Implicit")) {
CastRepTemplate cast = new CastRepTemplate();
cast.To = TypeHelper.buildTypeName(m.ReturnType);
cast.From = TypeHelper.buildTypeName(m.GetParameters()[0].ParameterType);
klass.Casts.Add(cast);
}
}
}
private IList<TypeRepTemplate> mkTemplates(string typeName) {
List<TypeRepTemplate> rets = new List<TypeRepTemplate>();
Type t = assembly.GetType(typeName);
foreach (Type nestedTy in t.GetNestedTypes()) {
foreach(TypeRepTemplate nestedRep in mkTemplates(nestedTy.FullName)) {
rets.Add(nestedRep);
}
}
TypeRepTemplate retRep = null;
if (t.IsClass) {
ClassRepTemplate classRep = new ClassRepTemplate();
buildClass(classRep, t);
retRep = classRep;
}
else if (t.IsInterface) {
InterfaceRepTemplate intRep = new InterfaceRepTemplate();
buildInterface(intRep, t);
retRep = intRep;
}
else if (t.IsEnum) {
EnumRepTemplate enumRep = new EnumRepTemplate();
enumRep.TypeName = TypeHelper.buildTypeName(t);
foreach (FieldInfo f in t.GetFields(BindingFlags.Public | BindingFlags.Static)) {
enumRep.Members.Add(new EnumMemberRepTemplate(f.Name, f.GetRawConstantValue().ToString()));
}
retRep = enumRep;
}
rets.Add(retRep);
return rets;
}
private void writeXmlStream(TypeRepTemplate inT, TextWriter str) {
XmlSerializer xmls = new XmlSerializer(inT.GetType(), Constants.TranslationTemplateNamespace);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.Indent = true;
settings.IndentChars = "\t";
settings.NewLineChars = Environment.NewLine;
settings.ConformanceLevel = ConformanceLevel.Document;
using (XmlWriter writer = XmlTextWriter.Create(str, settings))
{
xmls.Serialize(writer, inT);
}
}
private List<string> getAllTypeNames() {
List<string> typeNames = new List<string>();
foreach (Type t in assembly.GetExportedTypes()) {
typeNames.Add(t.FullName);
}
return typeNames;
}
private static void printUsageAndExit() {
Console.WriteLine ("Help goes here!");
Environment.Exit(0);
}
public static void Main(string[] args) {
TemplateFromDLL templateDriver = new TemplateFromDLL();
List<string> extractTypes = null;
bool dumpXmls = false;
string xmlDir = Directory.GetCurrentDirectory();
OptionSet p = new OptionSet ()
.Add ("v", v => templateDriver.verbose++)
.Add ("help|h|?", v => printUsageAndExit())
.Add ("dll=", dllFileName => templateDriver.assembly = Assembly.LoadFile(dllFileName))
.Add ("dumpxmls", v => dumpXmls = true)
.Add ("xmldir=", dir => xmlDir = Path.Combine(xmlDir, dir));
// .Add ("extract={,}", typeName => templateDriver.extractTypes.Add(typeName));
extractTypes = p.Parse (args);
if (templateDriver.assembly == null) {
Console.WriteLine("You must specify the DLL to extract the types");
printUsageAndExit();
}
if (extractTypes == null || extractTypes.Count == 0) {
extractTypes = templateDriver.getAllTypeNames();
}
if (templateDriver.verbose > 0)
Console.WriteLine ("Types to extract:");
foreach (string t in extractTypes) {
if (templateDriver.verbose > 0)
Console.WriteLine ( "extracting {0}", t );
IList<TypeRepTemplate> tyReps = templateDriver.mkTemplates(t);
TextWriter writer = null;
foreach (TypeRepTemplate tyRep in tyReps) {
if (dumpXmls) {
string xmlFName = Path.Combine(xmlDir, tyRep.TypeName.Replace('.', Path.DirectorySeparatorChar) + ".xml");
string xmlFDir = Path.GetDirectoryName(xmlFName);
if (!Directory.Exists(xmlFDir))
{
Directory.CreateDirectory(xmlFDir);
}
writer = new StreamWriter(xmlFName);
}
else {
writer = Console.Out;
}
templateDriver.writeXmlStream(tyRep, writer);
if (dumpXmls)
writer.Close();
}
}
}
}
}