/// <summary> /// Generate the types for the specified assembly. /// </summary> /// <param name="importlib"></param> protected void generateTypes(Assembly importlib, DopplegangerConfiguration config) { Type[] importlibTypes = importlib.GetExportedTypes(); Type[] nestedTypes = filterNestedTypes(importlibTypes); string currentNamespace = null; string asmName = Path.GetFileNameWithoutExtension(config.AssemblyPath); foreach (Type type in importlibTypes) { if (!type.IsNested) { if (config.IgnoredTypes.Contains(type.Namespace)) { continue; } if (config.IgnoredTypes.Contains(type.ToString())) { continue; } if (type.Namespace != currentNamespace) { if (currentNamespace != null) { // Close the current namespace. outputLevel--; output("}"); } currentNamespace = type.Namespace; if (currentNamespace != null) { Directory.CreateDirectory(Path.Combine(asmName, currentNamespace.Replace('.', Path.DirectorySeparatorChar))); output("namespace " + currentNamespace + "\n{"); outputLevel++; } } using (StreamWriter writer = new StreamWriter(File.Create(Path.Combine(asmName, type.FullName.Replace('.', Path.DirectorySeparatorChar) + ".cs")))) declareType(type, nestedTypes, config.ForceVirtual, writer); } } if (currentNamespace != null) { // Close the current namespace. outputLevel--; output("}"); } }
/// <summary> /// Main entry point /// </summary> /// <param name="args"></param> public static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("You must specify an assembly to parse."); return; } DopplegangerConfiguration config = new DopplegangerConfiguration(); config.ParseFromArguments(args); Doppleganger mg = new Doppleganger(); mg.generate(config); }
/// <summary> /// Generate the types for the specified assembly. /// </summary> /// <param name="importlib"></param> protected void generateTypes(Assembly importlib, DopplegangerConfiguration config) { Type[] importlibTypes = importlib.GetExportedTypes(); Type[] nestedTypes = filterNestedTypes(importlibTypes); string currentNamespace = null; foreach (Type type in importlibTypes) { if (!type.IsNested) { if (config.IgnoredTypes.Contains(type.Namespace)) { continue; } if (config.IgnoredTypes.Contains(type.ToString())) { continue; } if (type.Namespace != currentNamespace) { if (currentNamespace != null) { // Close the current namespace. outputLevel--; output("}"); } currentNamespace = type.Namespace; if (currentNamespace != null) { output("namespace " + currentNamespace + "\n{"); outputLevel++; } } declareType(type, nestedTypes, config.ForceVirtual); } } if (currentNamespace != null) { // Close the current namespace. outputLevel--; output("}"); } }
/// <summary> /// Generate the doppleganger interface for the assembly. /// </summary> /// <param name="typelibName"></param> public void generate(DopplegangerConfiguration config) { padWithTabs = config.UseTabs; Assembly importlib = Assembly.ReflectionOnlyLoadFrom(config.AssemblyPath); // Capture any assembly resolve problems and dynamically load the dependent assembly. AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += reflectionOnlyAssemblyResolveHandler; output("/*"); output(" * Licensed to the Apache Software Foundation (ASF) under one or more"); output(" * contributor license agreements. See the NOTICE file distributed with"); output(" * this work for additional information regarding copyright ownership."); output(" * The ASF licenses this file to You under the Apache License, Version 2.0"); output(" * (the \"License\"); you may not use this file except in compliance with"); output(" * the License. You may obtain a copy of the License at"); output(" *"); output(" * http://www.apache.org/licenses/LICENSE-2.0"); output(" *"); output(" * Unless required by applicable law or agreed to in writing, software"); output(" * distributed under the License is distributed on an \"AS IS\" BASIS,"); output(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied."); output(" * See the License for the specific language governing permissions and"); output(" * limitations under the License."); output(" */"); output("/*"); output(" * This file was auto-generated by Doppleganger."); output(" * Feel free to modify this file as necessary, but any changes"); output(" * may be lost when it is regenerated."); output(" *"); output(" * See http://code.google.com/p/doppleganger/ for more information."); output(" */"); if (!config.DisableAssemblyInfo) { generateAssemblyInfo(importlib); } generateTypes(importlib, config); }
/// <summary> /// Generate the assembly metedata attributes for the specified assembly. /// Will not replicate strong named attributes, as this information is not available /// and would be a violation of security restrictions. Therefore, it is not entirely /// possible to compile against a doppleganger version of a strong-named assembly and then /// run the code unmodified with the actual assembly. In order to run with a strong /// named assembly, the application must be compiled with that strong named assembly /// as a reference. However, the doppleganger version of the assembly can still be used as /// a stand-in during the development cycle. Just remember to do a final compile against /// the real strong named assembly before final deployment. /// </summary> /// <param name="importlib"></param> protected void generateAssemblyInfo(Assembly importlib, DopplegangerConfiguration config) { IList <CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(importlib); //bool hasDescriptionAttribute = false; string asmName = Path.GetFileNameWithoutExtension(config.AssemblyPath); Directory.CreateDirectory(Path.Combine(asmName, "Properties")); //output(getApacheCopyrightAttribute()); AssemblyName assemblyName = importlib.GetName(); using (StreamWriter writer = new StreamWriter(File.Create(Path.Combine(asmName, "Properties", "AssemblyInfo.cs")))) { Action <string> output = (s) => { foreach (string line in this.output(s)) { writer.Write(line); } }; output("[assembly: System.Reflection.AssemblyVersionAttribute(\"" + assemblyName.Version + "\")]"); foreach (CustomAttributeData attribute in attributes) { if (!shouldGenerateAttribute(attribute.Constructor.DeclaringType)) { continue; } string attributeSig = ("[assembly: " + attribute.Constructor.DeclaringType.FullName); if (attribute.ConstructorArguments.Count > 0) { int argumentIndex = 0; attributeSig += "("; foreach (CustomAttributeTypedArgument argument in attribute.ConstructorArguments) { string fieldDelim = getFieldDelim(argument.ArgumentType); if (argumentIndex > 0) { attributeSig += ", "; } attributeSig += fieldDelim; if (argument.ArgumentType.IsEnum) { if (argument.Value != null) { try { object o = Enum.Parse(argument.ArgumentType, argument.Value.ToString()); attributeSig += argument.ArgumentType + "." + Enum.GetName(argument.ArgumentType, o); } catch (Exception ex) { //FIXME: log } } } else if (argument.ArgumentType == typeof(bool)) { attributeSig += argument.Value.ToString().ToLower(); } else { if (attribute.Constructor.DeclaringType == typeof(AssemblyDescriptionAttribute)) { //attributeSig += assemblyDescriptionAttributeMarkup; //hasDescriptionAttribute = true; } attributeSig += argument.Value; } attributeSig += fieldDelim; argumentIndex++; } if (attribute.NamedArguments.Count > 0) { attributeSig += ", "; } for (int i = 0; i < attribute.NamedArguments.Count; i++) { attributeSig += string.Format("{0} = \"{1}\"", attribute.NamedArguments[i].MemberInfo.Name, attribute.NamedArguments[i].TypedValue.Value);//TODO: check enum and quotes if (i < attribute.NamedArguments.Count - 1) { attributeSig += ", "; } } attributeSig += ")"; } attributeSig += "]"; output(attributeSig); } /*if (!hasDescriptionAttribute) * { * output("[assembly: System.Reflection.AssemblyDescriptionAttribute(\"" + assemblyDescriptionAttributeMarkup + "\")]"); + }*/ } }