/// <summary> /// Returns edge definitions specific to graph-viz (ver. 2.38+) /// see [http://www.graphviz.org/] /// </summary> /// <returns></returns> public static string ToGraphVizEdge(this CgType cgType) { var graphViz = new StringBuilder(); var myName = NfString.SafeDotNetIdentifier(cgType.FullName); var edges = new List <string>(); foreach ( var property in cgType.Properties.Where( x => !Etc.ValueTypesList.Contains(NfReflect.GetLastTypeNameFromArrayAndGeneric(x.TypeName, "<"))) ) { var toName = NfString.SafeDotNetIdentifier(NfReflect.GetLastTypeNameFromArrayAndGeneric(property.TypeName, "<")); var edg = new StringBuilder(); edg.AppendFormat("{0} -> {1}", myName, toName); edg.Append(property.IsEnumerableType ? " [arrowhead=odiamond]" : " [arrowhead=vee]"); edg.Append(";"); if (!edges.Contains(edg.ToString())) { edges.Add(edg.ToString()); } } foreach (var edge in edges) { graphViz.AppendLine(edge); } return(graphViz.ToString()); }
/// <summary> /// Performs a heavy task of resolving every MetadataToken in all <see cref="cgType"/>'s Methods and Properties. /// </summary> /// <param name="cgType"></param> /// <param name="manifestModule"></param> public static void ResolveAllMetadataTokens(CgType cgType, Module manifestModule) { if (cgType == null || manifestModule == null) { return; } //improve performance for common tokens invoked in lots of members. var memberInfoCache = new Dictionary <int, MemberInfo>(); //we don't want this clutter var gacAssemblies = NfConfig.UseReflectionOnlyLoad ? AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies() .Where(x => x.GlobalAssemblyCache) .Select(x => x.FullName) .ToArray() : AppDomain.CurrentDomain.GetAssemblies() .Where(x => x.GlobalAssemblyCache) .Select(x => x.FullName) .ToArray(); //go through each method on the cgType foreach (var cgm in cgType.Methods) { ResolveCgMemberMetadataTokens(cgm, manifestModule, memberInfoCache, gacAssemblies); } //then go through each property foreach (var cgm in cgType.Properties) { ResolveCgMemberMetadataTokens(cgm, manifestModule, memberInfoCache, gacAssemblies); } }
/// <summary> /// Moves the given code-gen source code definition to another file /// </summary> /// <returns>The full paths to the created source code files </returns> public static string[] MoveType(CgType cgType, string outputDirectory = null, CgClassModifier typeModifier = CgClassModifier.AsIs) { if (cgType == null) { return(new string[0]); } outputDirectory = outputDirectory ?? NfSettings.AppData; //TODO - this is inconsistent where enclosure is one but src files are many var srcCodeFile = cgType.GetMySrcCodeFiles()?.FirstOrDefault() ?? Path.Combine(NfSettings.AppData, cgType.Name + Settings.LangStyle.FileExtension); var fileName = cgType.Name; var fileExtension = Path.GetExtension(srcCodeFile); var outFilePath = Path.Combine(outputDirectory, fileName + fileExtension); //don't overwrite whatever is already there if (File.Exists(outFilePath)) { outFilePath = Path.Combine(outputDirectory, fileName + NfString.GetNfRandomName() + fileExtension); } var newlines = new List <string>(); var hasNs = !string.IsNullOrWhiteSpace(cgType.Namespace); if (hasNs) { newlines.AddRange(Settings.LangStyle.ToNamespaceDecl(cgType).ConvertToLf().Split('\n')); } if (File.Exists(srcCodeFile)) { var start = cgType.GetMyStartEnclosure().Item1; var end = cgType.GetMyEndEnclosure().Item1; var srcLines = File.ReadAllLines(srcCodeFile); newlines.AddRange(srcLines.Skip(start - 1).Take(end + 1 - start)); } else { var genLines = typeModifier == CgClassModifier.AsInterface ? Settings.LangStyle.ToInterface(cgType) : Settings.LangStyle.ToClass(cgType, CgAccessModifier.Public, typeModifier); newlines.AddRange(genLines.ConvertToLf().Split('\n')); } if (hasNs) { newlines.Add(Settings.LangStyle.GetEnclosureCloseToken(null)); } //write the type def to file File.WriteAllLines(outFilePath, newlines, Encoding.UTF8); return(new[] { outFilePath }); }
public CgTypeCsSrcCode(string assemblyPath, string typeFullName) { if (string.IsNullOrWhiteSpace(assemblyPath)) { throw new ArgumentNullException(nameof(assemblyPath)); } AssemblyPath = assemblyPath; if (!File.Exists(AssemblyPath)) { throw new FileNotFoundException("Cannot find the compiled assembly.", assemblyPath); } //this is how we line up a source code file to a reflected runtime type var invokeDia2Dump = new InvokeDia2Dump.GetPdbData(assemblyPath); var pdbLines = invokeDia2Dump.SingleTypeNamed(typeFullName); if (pdbLines == null) { throw new ItsDeadJim("Dia2Dump.exe did not return anything for the type " + $"named '{typeFullName}' from '{invokeDia2Dump.PdbAssemblyFilePath}'"); } //but we don't want the type in our appDomain, so we shell it out as a code-gen type _cgType = Etc.GetIsolatedCgOfType(assemblyPath, typeFullName, true); _cgType.AssignPdbSymbols(pdbLines.moduleSymbols); var sourceCodeFiles = pdbLines.moduleSymbols.Select(ms => ms.file); foreach (var src in sourceCodeFiles) { if (!File.Exists(src)) { continue; } //ANTLR CSharp parser seems to have problems with Preprocessor cmd\directives\macros var srcLines = File.ReadAllLines(src); srcLines = Settings.LangStyle.RemovePreprocessorCmds(srcLines); File.WriteAllLines(src, srcLines); var antlrParseRslts = CsharpParseTree.InvokeParse(src); _cgType.AssignAntlrParseItems(GetAntlrParseItems(antlrParseRslts)); } }
public CgTypeCsSrcCode(string assemblyPath, string typeFullName) { if (string.IsNullOrWhiteSpace(assemblyPath)) throw new ArgumentNullException(nameof(assemblyPath)); AssemblyPath = assemblyPath; if (!File.Exists(AssemblyPath)) { throw new ItsDeadJim($"No such file '{AssemblyPath}'."); } var invokeDia2Dump = new InvokeDia2Dump.GetPdbData(assemblyPath); var pdbLines = invokeDia2Dump.SingleTypeNamed(typeFullName); if(pdbLines == null) throw new ItsDeadJim($"Dia2Dump.exe did not return anything for the type named '{typeFullName}'"); _cgType = Etc.GetIsolatedCgOfType(assemblyPath, typeFullName, true); _cgType.AssignPdbSymbols(pdbLines.moduleSymbols); }
public CgTypeCsSrcCode(string assemblyPath, string typeFullName, params string[] sourceCodeFiles) { if (string.IsNullOrWhiteSpace(assemblyPath)) { throw new ArgumentNullException(nameof(assemblyPath)); } AssemblyPath = assemblyPath; if (!File.Exists(AssemblyPath)) { throw new FileNotFoundException("Cannot find the compiled assembly.", assemblyPath); } _cgType = Etc.GetIsolatedCgOfType(assemblyPath, typeFullName, true); if (sourceCodeFiles == null || !sourceCodeFiles.Any()) { return; } foreach (var src in sourceCodeFiles) { var antlrParseRslts = CsharpParseTree.InvokeParse(src); _cgType.AssignAntlrParseItems(GetAntlrParseItems(antlrParseRslts)); } }
/// <summary> /// Returns node definition specific to graph-viz (ver. 2.38+) /// see [http://www.graphviz.org/] /// </summary> /// <returns></returns> public static string ToGraphVizNode(this CgType cgType) { var graphViz = new StringBuilder(); graphViz.Append(NfString.SafeDotNetIdentifier(cgType.FullName)); graphViz.AppendLine(" [shape=Mrecord, label=<<table bgcolor=\"white\" border=\"0\" >"); graphViz.AppendLine("<th>"); graphViz.AppendLine("<td bgcolor=\"grey\" align=\"center\">"); graphViz.Append("<font color=\"white\">"); graphViz.AppendFormat("{0} :: {1}", cgType.Name, string.IsNullOrWhiteSpace(cgType.Namespace) ? "global" : cgType.Namespace); graphViz.AppendLine("</font></td></th>"); foreach (var prop in cgType.Properties) { graphViz.AppendLine(prop.ToGraphVizString()); } foreach (var me in cgType.SortedMethods) { graphViz.AppendLine(me.ToGraphVizString()); } graphViz.AppendLine("</table>> ];"); return(graphViz.ToString()); }
public CgTypeCsSrcCode(Assembly asm, string typeFullName, params string[] sourceCodeFiles) { if (asm == null) { throw new ArgumentNullException(nameof(asm)); } AssemblyPath = asm.Location; if (!File.Exists(AssemblyPath)) { throw new FileNotFoundException("Cannot find the compiled assembly.", AssemblyPath); } //this is how we line up a source code file to a reflected runtime type var invokeDia2Dump = new InvokeDia2Dump.GetPdbData(AssemblyPath); var pdbLines = invokeDia2Dump.SingleTypeNamed(typeFullName); if (pdbLines == null) { throw new ItsDeadJim("Dia2Dump.exe did not return anything for the type " + $"named '{typeFullName}' from '{invokeDia2Dump.PdbAssemblyFilePath}'"); } _cgType = Etc.GetCgOfType(asm, typeFullName, true); _cgType.AssignPdbSymbols(pdbLines.moduleSymbols); var scf = sourceCodeFiles?.ToList() ?? new List <string>(); scf.AddRange(pdbLines.moduleSymbols.Select(ms => ms.file)); foreach (var src in sourceCodeFiles) { var antlrParseRslts = CsharpParseTree.InvokeParse(src); _cgType.AssignAntlrParseItems(GetAntlrParseItems(antlrParseRslts)); } }
/// <summary> /// Performs a heavy task of resolving every MetadataToken in all <see cref="cgType"/>'s Methods and Properties. /// </summary> /// <param name="cgType"></param> /// <param name="manifestModule"></param> public static void ResolveAllMetadataTokens(CgType cgType, Module manifestModule) { if (cgType == null || manifestModule == null) return; //improve performance for common tokens invoked in lots of members. var memberInfoCache = new Dictionary<int, MemberInfo>(); //we don't want this clutter var gacAssemblies = NfConfig.UseReflectionOnlyLoad ? AppDomain.CurrentDomain.ReflectionOnlyGetAssemblies() .Where(x => x.GlobalAssemblyCache) .Select(x => x.FullName) .ToArray() : AppDomain.CurrentDomain.GetAssemblies() .Where(x => x.GlobalAssemblyCache) .Select(x => x.FullName) .ToArray(); //go through each method on the cgType foreach (var cgm in cgType.Methods) { ResolveCgMemberMetadataTokens(cgm, manifestModule, memberInfoCache, gacAssemblies); } //then go through each property foreach (var cgm in cgType.Properties) { ResolveCgMemberMetadataTokens(cgm, manifestModule, memberInfoCache, gacAssemblies); } }
/// <summary> /// Converts the .NET type into the custom Code Gen type /// </summary> /// <param name="asmType"></param> /// <param name="valueTypeOnly"> /// Will only export Fields and Properties whose base type extends System.ValueType /// </param> /// <param name="resolveDependencies"> /// Switch to have the IL of the type parsed and all dependent calls Metadata tokens added. /// </param> /// <returns></returns> public static CgType GetCgOfType(this Type asmType, bool valueTypeOnly, bool resolveDependencies = false) { var cgType = new CgType(); if (asmType == null || NfTypeName.IsIgnoreType(asmType) || NfTypeName.IsClrGeneratedType(asmType)) return null; //use the logic in TypeName to get the namespace and class name so its not tied to having the assembly var cgTypeName = new NfTypeName(asmType.AssemblyQualifiedName); //make sure there is always some kind of namespace cgType.Namespace = string.IsNullOrWhiteSpace(cgTypeName.Namespace) ? asmType.Assembly.GetName().Name : cgTypeName.Namespace; cgType.IsContrivedNamespace = string.IsNullOrWhiteSpace(cgTypeName.Namespace); cgType.Name = cgTypeName.ClassName; cgType.AssemblyQualifiedName = asmType.AssemblyQualifiedName; cgType.IsEnum = NfTypeName.IsEnumType(asmType); var cgTypesInterfaces = asmType.GetInterfaces(); cgType.MetadataToken = asmType.MetadataToken; Func<CgType, string, bool> alreadyPresentHerein = (cg, nextName) => (cg.Properties.FirstOrDefault( cgP => string.Equals(cgP.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null || cg.Fields.FirstOrDefault( cgF => string.Equals(cgF.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null || cg.Events.FirstOrDefault( cgE => string.Equals(cgE.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null) ; //have events go first since they tend to be speard across fields and properties foreach ( var evtInfo in asmType.GetEvents(NfConfig.DefaultFlags)) { var evtHandlerType = evtInfo.NfEventHandlerType().ToString(); var cgMem = new CgMember { Name = evtInfo.Name, TypeName = evtHandlerType, MetadataToken = evtInfo.MetadataToken }; cgType.Events.Add(cgMem); } var asmMembers = asmType.GetMembers(NfConfig.DefaultFlags); foreach (var mi in asmMembers) { if (alreadyPresentHerein(cgType, mi.Name)) continue; try { if (mi.MemberType == MemberTypes.Property) { var pi = mi as PropertyInfo; var cgm = GetAsCgMember(pi, valueTypeOnly, cgType.EnumValueDictionary); if (cgm == null) continue; if (resolveDependencies) { var propMi = NfTypeName.GetMethodsForProperty(pi, asmType); foreach (var pim in propMi) { cgm.opCodeCallsAndCallvirtsMetadatTokens.AddRange(Asm.GetCallsMetadataTokens(pim)); } } cgType.Properties.Add(cgm); } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); if (!Settings.IgnoreReflectionMissingAsmError) throw; cgType.Properties.Add(new CgMember { Name = mi.Name, TypeName = DF_TYPE_NAME, HasGetter = true, HasSetter = true, SkipIt = true }); } try { if (mi.MemberType == MemberTypes.Event) { continue;//these have already been handled } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); continue; } try { if (mi.MemberType == MemberTypes.Field) { var fi = mi as FieldInfo; var cgm = GetAsCgMember(fi, valueTypeOnly, cgType.EnumValueDictionary); if (cgm == null) continue; cgType.Fields.Add(cgm); } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); if (!Settings.IgnoreReflectionMissingAsmError) throw; cgType.Fields.Add(new CgMember { Name = mi.Name, TypeName = DF_TYPE_NAME, SkipIt = true }); } try { if (!valueTypeOnly && mi.MemberType == MemberTypes.Method) { var mti = mi as MethodInfo; var cgm = GetAsCgMember(mti, resolveDependencies); if (cgm == null) continue; cgm.IsInterfaceImpl = IsInterfaceImpl(mti, cgTypesInterfaces); cgType.Methods.Add(cgm); } if (!valueTypeOnly && mi.MemberType == MemberTypes.Constructor) { var ci = mi as ConstructorInfo; var tn = (string.IsNullOrWhiteSpace(cgTypeName.Namespace) ? cgTypeName.ClassName : $"{cgTypeName.Namespace}.{cgTypeName.ClassName}"); var cgm = GetAsCgMember(ci, tn, resolveDependencies); if (cgm == null) continue; cgType.Methods.Add(cgm); } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); if (!Settings.IgnoreReflectionMissingAsmError) throw; cgType.Methods.Add(new CgMember { Name = mi.Name, TypeName = DF_TYPE_NAME, SkipIt = true }); } } if (resolveDependencies) { ResolveAllMetadataTokens(cgType, asmType.Assembly.ManifestModule); } return cgType; }
public void TestCgMemberCompareMany() { var myCgType = new CgType() { Methods = new List<CgMember>() }; myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "Page_Load", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "Sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "Page_PreRender", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "ddlEquipmentName_SelectedIndexChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "ddlEquipmentLocation_SelectedIndexChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "ddlLocationname_SelectedIndexChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "ddlTransferTo_SelectedIndexChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "ddlClinicId_SelectedIndexChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "ddlVendorName_SelectedIndexChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.Web.UI.WebControls.GridViewPageEventArgs"}, }, Name = "grdvAgencySearch_PageIndexChanging", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "grdvAgencySearch_PreRender", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.Web.UI.WebControls.GridViewCommandEventArgs"}, }, Name = "grdvAgencySearch_RowCommand", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.Web.UI.WebControls.GridViewSortEventArgs"}, }, Name = "grdvAgencySearch_Sorting", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnAgencySearch_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnAgencyReset_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnAgencyClose_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.Web.UI.WebControls.GridViewPageEventArgs"}, }, Name = "grdvSubConSearch_PageIndexChanging", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "grdvSubConSearch_PreRender", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.Web.UI.WebControls.GridViewCommandEventArgs"}, }, Name = "grdvSubConSearch_RowCommand", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.Web.UI.WebControls.GridViewSortEventArgs"}, }, Name = "grdvSubConSearch_Sorting", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnSubSearch_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnSubReset_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnSubClose_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnAdd_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "btnReset_Click", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "strClinicDetails", ArgType = "string"}, new CgArg {ArgName = "intSize", ArgType = "int"}, }, Name = "FormatTheTextIntoGridCell", TypeName = "string" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { }, Name = "LoadDropdownValues", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { }, Name = "getFilter", TypeName = "string" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sortExpr", ArgType = "string"}, }, Name = "MyAgencySortBind", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sortExpr", ArgType = "string"}, }, Name = "MySubConSortBind", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { }, Name = "PopulateAgencyList", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { }, Name = "PopulateSubConList", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { }, Name = "SetControlToolTip", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "rdoBilling_CheckedChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "rdoShipping_CheckedChanged", TypeName = "void" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "strSerialNumber", ArgType = "string"}, }, Name = "IsValidSerialNumbers", TypeName = "int" }); myCgType.Methods.Add(new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "sender", ArgType = "System.Object"}, new CgArg {ArgName = "e", ArgType = "System.EventArgs"}, }, Name = "txtSerialNo_TextChanged", TypeName = "void" }); var testResult = myCgType.SortedMethods; Assert.AreEqual(testResult.Count, myCgType.Methods.Count); foreach(var d in testResult) System.Diagnostics.Debug.WriteLine(NoFuture.Gen.Settings.LangStyle.ToDecl(d)); }
public void TestContainsThisMember() { var args1 = new List<CgArg> { new CgArg {ArgName = "NameOne", ArgType = "TypeOne"}, new CgArg {ArgName = "NameTwo", ArgType = "TypeTwo"}, new CgArg {ArgName = "NameThree", ArgType = "TypeThree"} }; var args2 = new List<CgArg> { new CgArg {ArgName = "NameThree", ArgType = "TypeThree"}, new CgArg {ArgName = "NameTwo", ArgType = "TypeTwo"}, new CgArg {ArgName = "NameOne", ArgType = "TypeOne"} }; var cgOne = new CgMember() { Args = args1, HasGetter = true, HasSetter = true, TypeName = "MyCgMember", Name = "MyCgType" }; var cgTwo = new CgMember() { Args = args2, HasGetter = true, HasSetter = true, TypeName = "MyCgMember", Name = "MyCgType" }; var testSubject = new CgType(); testSubject.Methods.Add(cgOne); Assert.IsTrue(testSubject.ContainsThisMember(cgTwo)); testSubject = new CgType(); testSubject.Fields.Add(cgOne); Assert.IsTrue(testSubject.ContainsThisMember(cgTwo)); testSubject = new CgType(); testSubject.Events.Add(cgOne); Assert.IsTrue(testSubject.ContainsThisMember(cgTwo)); testSubject = new CgType(); testSubject.Properties.Add(cgOne); Assert.IsTrue(testSubject.ContainsThisMember(cgTwo)); }
public void TestCgMemberCompare() { var testSubject = new CgMemberCompare(); Assert.AreEqual(0, testSubject.Compare(null, null)); var less = new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "ddl", ArgType = "System.Web.UI.WebControls.DropDownList"}, new CgArg {ArgName = "lookupMstrDescription", ArgType = "string"} }, Name = "less", TypeName = "void" }; var middle = new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "ddl", ArgType = "System.Web.UI.WebControls.DropDownList"}, new CgArg {ArgName = "lookupMstrDescription", ArgType = "string"}, new CgArg {ArgName = "Id", ArgType = "bool"} }, Name = "middle", TypeName = "void" }; var most = new CgMember { Args = new List<CgArg>() { new CgArg {ArgName = "ddl", ArgType = "System.Web.UI.WebControls.DropDownList"}, new CgArg {ArgName = "lookupMstrDescription", ArgType = "string"}, new CgArg {ArgName = "defaultValue", ArgType = "string"} }, Name = "most", TypeName = "void" }; var deadLast = new CgMember { Name = "deadLast", TypeName = "void" }; var myCgType = new CgType() { Methods = new List<CgMember>() { deadLast, middle, less, most } }; foreach (var obj in myCgType.SortedMethods) { var cg = obj as CgMember; System.Diagnostics.Debug.WriteLine(string.Format("----{0}", cg.Name)); foreach (var arg in cg.Args) { System.Diagnostics.Debug.WriteLine(arg.ToString()); } } }
/// <summary> /// Performs dual operation of, one, moving <see cref="MoveMethodsArgs.MoveMembers"/> /// out of <see cref="MoveMethodsArgs.SrcFile"/> and into the new /// <see cref="MoveMethodsArgs.OutFilePath"/> (adjusting their signatures as needed to /// accommodate dependencies), and, two, modifying the <see cref="MoveMethodsArgs.SrcFile"/> /// file to call the new. /// </summary> /// <param name="cgType"></param> /// <param name="args"></param> public static void MoveMembers(this CgType cgType, MoveMethodsArgs args) { var srcFile = args.SrcFile; var moveMembers = args.MoveMembers; var newVariableName = args.NewVariableName; var outFilePath = args.OutFilePath; var outFileNamespaceAndTypeName = args.OutFileNamespaceAndType; var includeUsingStmts = args.IncludeUsingStmts; var excludeUsingStmts = args.ExcludedUsingStmts; if (moveMembers == null || moveMembers.Count < 0) { return; } if (string.IsNullOrWhiteSpace(srcFile) || !File.Exists(srcFile)) { return; } var srcLines = File.ReadAllLines(srcFile); //need this to be the same for the whole batch of refactored lines if (string.IsNullOrWhiteSpace(newVariableName)) { newVariableName = Util.Core.NfString.GetNfRandomName(); } if (string.IsNullOrWhiteSpace(outFilePath)) { outFilePath = Path.Combine(Shared.Core.NfSettings.AppData, Util.Core.NfString.GetNfRandomName()); } //need to move the existing code to the new file var newNs = NfString.SafeDotNetTypeName(outFileNamespaceAndTypeName.Item1); var newTn = NfString.SafeDotNetIdentifier(outFileNamespaceAndTypeName.Item2); var idxRefactor = new Dictionary <Tuple <int, int>, string[]>(); var newCgType = new CgType { Namespace = newNs, Name = newTn }; foreach (var cgm in moveMembers) { //the signature must be changed to handle instance-level dependencies cgm.Args.AddRange(cgm.GetAllRefactorDependencies()); var refactorLines = cgm.MyRefactoredLines(newVariableName, outFileNamespaceAndTypeName, false); foreach (var key in refactorLines.Keys) { if (idxRefactor.Keys.Any(x => x.Equals(key))) { continue; } idxRefactor.Add(key, refactorLines[key]); } newCgType.Methods.Add(cgm); } //clear file content File.WriteAllText(outFilePath, string.Empty, Encoding.UTF8); var nsImports = Settings.LangStyle.ExtractNamespaceImportStatements(srcLines); if (nsImports != null) { nsImports = FilterNamespaceImportStmts(nsImports, includeUsingStmts, excludeUsingStmts); } File.AppendAllLines(outFilePath, new [] { Settings.LangStyle.ToNamespaceDecl(newCgType) }); File.AppendAllText(outFilePath, Settings.LangStyle.ToClass(newCgType, CgAccessModifier.Public, CgClassModifier.AsIs, nsImports), Encoding.UTF8); File.AppendAllLines(outFilePath, new[] { Settings.LangStyle.GetEnclosureCloseToken(null) }); //now must modify existing file var k = 0; //get fresh copy from disk. srcLines = File.ReadAllLines(srcFile); foreach (var idx in idxRefactor) { var s = idx.Key.Item1 + k; var l = idx.Key.Item2; //get everything up to start of member var left = srcLines.Take(s - 1).ToList(); //add in the new refactored code left.AddRange(idx.Value); //add in all the remainder less the removed member left.AddRange(srcLines.Skip(s + l).Take(srcLines.Length).ToList()); //keep a running total of the number of lines removed var len = srcLines.Length; srcLines = left.ToArray(); k = srcLines.Length - len;//this will typically be a negative int } //need to add the new variable decl int lnNumOut; Settings.LangStyle.TryFindFirstLineInClass(cgType.FullName, srcLines.ToArray(), out lnNumOut); var oldFilesInstanceToNew = Settings.LangStyle.ToDecl(newCgType, newVariableName, CgAccessModifier.Private); var g = srcLines.Take(lnNumOut).ToList(); g.Add(oldFilesInstanceToNew); g.AddRange(srcLines.Skip(lnNumOut).Take(srcLines.Length)); srcLines = g.ToArray(); //write the new content out to the file File.WriteAllLines(srcFile, srcLines, Encoding.UTF8); }
/// <summary> /// Converts the .NET type into the custom Code Gen type /// </summary> /// <param name="asmType"></param> /// <param name="valueTypeOnly"> /// Will only export Fields and Properties whose base type extends System.ValueType /// </param> /// <param name="resolveDependencies"> /// Switch to have the IL of the type parsed and all dependent calls Metadata tokens added. /// </param> /// <returns></returns> public static CgType GetCgOfType(this Type asmType, bool valueTypeOnly, bool resolveDependencies = false) { var cgType = new CgType(); if (asmType == null || NfReflect.IsIgnoreType(asmType) || NfReflect.IsClrGeneratedType(asmType)) { return(null); } //use the logic in TypeName to get the namespace and class name so its not tied to having the assembly var cgTypeName = new NfTypeName(asmType.AssemblyQualifiedName); //make sure there is always some kind of namespace cgType.Namespace = string.IsNullOrWhiteSpace(cgTypeName.Namespace) ? asmType.Assembly.GetName().Name : cgTypeName.Namespace; cgType.IsContrivedNamespace = string.IsNullOrWhiteSpace(cgTypeName.Namespace); cgType.Name = cgTypeName.ClassName; cgType.AssemblyQualifiedName = asmType.AssemblyQualifiedName; cgType.IsEnum = NfReflect.IsEnumType(asmType); var cgTypesInterfaces = asmType.GetInterfaces(); cgType.MetadataToken = asmType.MetadataToken; Func <CgType, string, bool> alreadyPresentHerein = (cg, nextName) => (cg.Properties.FirstOrDefault( cgP => string.Equals(cgP.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null || cg.Fields.FirstOrDefault( cgF => string.Equals(cgF.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null || cg.Events.FirstOrDefault( cgE => string.Equals(cgE.Name, nextName, StringComparison.OrdinalIgnoreCase)) != null) ; //have events go first since they tend to be speard across fields and properties foreach ( var evtInfo in asmType.GetEvents(Shared.Core.NfSettings.DefaultFlags)) { var evtHandlerType = evtInfo.NfEventHandlerType().ToString(); var cgMem = new CgMember { Name = evtInfo.Name, TypeName = evtHandlerType, MetadataToken = evtInfo.MetadataToken }; cgType.Events.Add(cgMem); } var asmMembers = asmType.GetMembers(Shared.Core.NfSettings.DefaultFlags); foreach (var mi in asmMembers) { if (alreadyPresentHerein(cgType, mi.Name)) { continue; } try { if (mi.MemberType == MemberTypes.Property) { var pi = mi as PropertyInfo; var cgm = GetAsCgMember(pi, valueTypeOnly, cgType.EnumValueDictionary); if (cgm == null) { continue; } if (resolveDependencies) { var propMi = NfReflect.GetMethodsForProperty(pi, asmType); foreach (var pim in propMi) { cgm.opCodeCallsAndCallvirtsMetadatTokens.AddRange(Asm.GetCallsMetadataTokens(pim)); } } cgType.Properties.Add(cgm); } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); if (!Settings.IgnoreReflectionMissingAsmError) { throw; } cgType.Properties.Add(new CgMember { Name = mi.Name, TypeName = DF_TYPE_NAME, HasGetter = true, HasSetter = true, SkipIt = true }); } try { if (mi.MemberType == MemberTypes.Event) { continue;//these have already been handled } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); continue; } try { if (mi.MemberType == MemberTypes.Field) { var fi = mi as FieldInfo; var cgm = GetAsCgMember(fi, valueTypeOnly, cgType.EnumValueDictionary); if (cgm == null) { continue; } cgType.Fields.Add(cgm); } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); if (!Settings.IgnoreReflectionMissingAsmError) { throw; } cgType.Fields.Add(new CgMember { Name = mi.Name, TypeName = DF_TYPE_NAME, SkipIt = true }); } try { if (!valueTypeOnly && mi.MemberType == MemberTypes.Method) { var mti = mi as MethodInfo; var cgm = GetAsCgMember(mti, resolveDependencies); if (cgm == null) { continue; } cgm.IsInterfaceImpl = IsInterfaceImpl(mti, cgTypesInterfaces); cgType.Methods.Add(cgm); } if (!valueTypeOnly && mi.MemberType == MemberTypes.Constructor) { var ci = mi as ConstructorInfo; var tn = (string.IsNullOrWhiteSpace(cgTypeName.Namespace) ? cgTypeName.ClassName : $"{cgTypeName.Namespace}.{cgTypeName.ClassName}"); var cgm = GetAsCgMember(ci, tn, resolveDependencies); if (cgm == null) { continue; } cgType.Methods.Add(cgm); } } catch (Exception ex) { Asm.AddLoaderExceptionToLog(null, ex); if (!Settings.IgnoreReflectionMissingAsmError) { throw; } cgType.Methods.Add(new CgMember { Name = mi.Name, TypeName = DF_TYPE_NAME, SkipIt = true }); } } if (resolveDependencies) { ResolveAllMetadataTokens(cgType, asmType.Assembly.ManifestModule); } return(cgType); }