/// <summary> /// Gets the fully qualified assembly names to an index /// </summary> /// <param name="assemblyPath"></param> /// <returns></returns> public AsmIndexResponse GetAsmIndices(string assemblyPath) { if (string.IsNullOrWhiteSpace(assemblyPath) || !File.Exists(assemblyPath)) { throw new ItsDeadJim("This isn't a valid assembly path"); } _asmIndices = _getAsmIndiciesCmd.Receive(assemblyPath); return(_asmIndices); }
public void TestFindCgMemberByTokenName() { NfConfig.UseReflectionOnlyLoad = false; FxPointers.AddResolveAsmEventHandlerToDomain(); var testAsm = GetAdventureWorks2012(); const string testTypeName = "AdventureWorks.VeryBadCode.BasicGenerics"; var testType = testAsm.GetType(testTypeName); Assert.IsNotNull(testType); var testMethod = testType.GetMember("TakesGenericArg").FirstOrDefault(); Assert.IsNotNull(testMethod); var testAsmIndicies = new AsmIndexResponse() { Asms = new[] { new MetadataTokenAsm() { AssemblyName = "AdventureWorks2012, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", IndexId = 0 } } }; var testTokenName = AssemblyAnalysis.ConvertToMetadataTokenName(testMethod, testAsmIndicies, null); Assert.IsNotNull(testTokenName); var testCgType = NoFuture.Gen.Etc.GetCgOfType(testAsm, testTypeName, false); Assert.IsNotNull(testCgType); var testResult = testCgType.FindCgMemberByTokenName(testTokenName); Assert.IsNotNull(testResult); }
public override byte[] Execute(byte[] arg) { MyProgram.PrintToConsole(); MyProgram.PrintToConsole($"{nameof(GetTokenTypes)} invoked"); MyProgram.ProgressMessageState = null; try { //expect that the caller has init'ed this with some target assembly(ies) if (((IaaProgram)MyProgram).AsmInited != true) { MyProgram.PrintToConsole("no assemblies are loaded - call GetAsmIndices"); return(JsonEncodedResponse( new TokenTypeResponse { Msg = "no assemblies are loaded - call GetAsmIndices", St = MetadataTokenStatus.Error })); } var json = Encoding.UTF8.GetString(arg); var rqst = JsonConvert.DeserializeObject <TokenTypeRequest>(json); if (!string.IsNullOrWhiteSpace(rqst.ResolveAllNamedLike)) { ((IaaProgram)MyProgram).AssemblyNameRegexPattern = rqst.ResolveAllNamedLike; } if (!string.IsNullOrWhiteSpace(((IaaProgram)MyProgram).RootAssemblyPath)) { _rootDir = System.IO.Path.GetDirectoryName(((IaaProgram)MyProgram).RootAssemblyPath); } //get all the assemblies of this app domain _asmIndices = ((IaaProgram)MyProgram).AsmIndicies; MyProgram.PrintToConsole($"There are {_asmIndices.Asms.Length} assemblies in scope."); var allTypes = GetAllTypes(); if (allTypes == null || !allTypes.Any()) { var msg = "Could not resolve any types from any of the assemblies."; MyProgram.PrintToConsole(msg); return(JsonEncodedResponse( new TokenTypeResponse { Msg = msg, St = MetadataTokenStatus.Error })); } MyProgram.PrintToConsole(); MyProgram.PrintToConsole($"There are {allTypes.Length} types in all assemblies."); var tokenTypes = new List <MetadataTokenType>(); var totalTypes = allTypes.Length; for (var i = 0; i < totalTypes; i++) { var cType = allTypes[i]; ((IaaProgram)MyProgram).ReportProgress(new ProgressMessage { Activity = $"{cType}", ProcName = Process.GetCurrentProcess().ProcessName, ProgressCounter = Etc.CalcProgressCounter(i, totalTypes), Status = "Resolving all type names" }); var tt = GetMetadataTokenType(cType); if (tt != null) { tokenTypes.Add(tt); } } var tokenTypeRspn = new TokenTypeResponse { Types = tokenTypes.ToArray() }; //keep a copy of this in memory like AsmIndices ((IaaProgram)MyProgram).TokenTypeResponse = tokenTypeRspn; return(JsonEncodedResponse(tokenTypeRspn)); } catch (Exception ex) { Console.Write('\n'); MyProgram.PrintToConsole(ex); return(JsonEncodedResponse( new TokenTypeResponse { Msg = ex.Message, St = MetadataTokenStatus.Error })); } }
/// <summary> /// Transforms a <see cref="MemberInfo"/> into a <see cref="MetadataTokenName"/> /// getting as much info as possible depending on which /// child-type the <see cref="mi"/> resolves to. /// </summary> /// <param name="mi"></param> /// <param name="indicies"> /// optional parameter, used to abbreviate the name removing the redundant part shared /// by both assembly and namespace. /// </param> /// <param name="isIgnore">optional f(x) pointer for calling assembly to specify some additional rules by token name</param> /// <param name="logFile"> /// optional, the path to a log file where any assembly, type, member, method, etc. loader exceptions will be written. /// </param> /// <param name="truncateAsmPartOfName"> /// Optional switch to reduce the member name to only what is original. The prefixed portion can be restored based on the Owning Assembly's name. /// </param> /// <returns></returns> public static MetadataTokenName ConvertToMetadataTokenName(MemberInfo mi, AsmIndexResponse indicies, Func <string, bool> isIgnore, string logFile = null, bool truncateAsmPartOfName = true) { if (mi == null) { return(null); } var localIsIgnore = isIgnore ?? (s => false); var localIndicies = indicies ?? new AsmIndexResponse { Asms = new MetadataTokenAsm[0] }; var tokenName = new MetadataTokenName { Name = mi.Name, Label = mi.GetType().Name, DeclTypeId = mi.DeclaringType?.MetadataToken ?? 0, Id = mi.MetadataToken }; string asmQualName; string asmName; string expandedName; var type = mi as Type; if (type != null) { asmQualName = type.Assembly.GetName().FullName; //do not send back GAC asm's unless asked if (localIsIgnore(asmQualName)) { return(null); } var t = localIndicies.Asms.FirstOrDefault( x => String.Equals(x.AssemblyName, type.Assembly.GetName().FullName, StringComparison.OrdinalIgnoreCase)); if (t == null) { return(null); } asmName = type.Assembly.GetName().Name; expandedName = !string.IsNullOrEmpty(asmName) ? (type.FullName ?? UNKNOWN_NAME_SUB).Replace($"{asmName}", string.Empty) : type.FullName; if (!string.Equals(expandedName, tokenName.Name, StringComparison.OrdinalIgnoreCase)) { tokenName.Name = expandedName; } tokenName.OwnAsmIdx = t.IndexId; tokenName.IsAmbiguous = type.IsInterface || type.IsAbstract; return(tokenName); } if (mi.DeclaringType == null) { return(tokenName); } asmQualName = mi.DeclaringType.Assembly.GetName().FullName; //do not send back GAC asm's unless asked if (localIsIgnore(asmQualName) || localIsIgnore(mi.DeclaringType.FullName)) { return(null); } var f = localIndicies.Asms.FirstOrDefault( x => string.Equals(x.AssemblyName, mi.DeclaringType.Assembly.GetName().FullName, StringComparison.OrdinalIgnoreCase)); if (f == null) { return(null); } asmName = mi.DeclaringType.Assembly.GetName().Name; expandedName = !string.IsNullOrEmpty(asmName) && truncateAsmPartOfName ? (mi.DeclaringType.FullName ?? UNKNOWN_NAME_SUB).Replace($"{asmName}", string.Empty) : mi.DeclaringType.FullName; if (!string.Equals(expandedName, tokenName.Name, StringComparison.OrdinalIgnoreCase)) { tokenName.Name = $"{expandedName}{Constants.TYPE_METHOD_NAME_SPLIT_ON}{tokenName.Name}"; } tokenName.OwnAsmIdx = f.IndexId; var mti = mi as MethodInfo; if (mti == null) { return(tokenName); } tokenName.IsAmbiguous = mti.IsAbstract; var mtiParams = mti.NfGetParameters(false, logFile); if (mtiParams.Length <= 0) { tokenName.Name = $"{tokenName.Name}()"; return(tokenName); } var paramNames = new List <string>(); foreach (var param in mtiParams) { var workingName = param.ParameterType.FullName ?? UNKNOWN_NAME_SUB; if (!param.ParameterType.IsGenericType) { paramNames.Add(workingName); continue; } var paramsGen = param.ParameterType.NfGetGenericArguments(false, logFile); foreach (var genParam in paramsGen) { var asmGenParamName = genParam.AssemblyQualifiedName; if (string.IsNullOrWhiteSpace(asmGenParamName)) { continue; } workingName = workingName.Replace("[" + asmGenParamName + "]", genParam.FullName); } paramNames.Add(workingName); } tokenName.Name = $"{tokenName.Name}({string.Join(",", paramNames)})"; return(tokenName); }