Ejemplo n.º 1
0
        public void TestEquals_EmptyNames()
        {
            var tx = new MetadataTokenName
            {
                Name       = "",
                Id         = 4451,
                DeclTypeId = 3322,
                OwnAsmIdx  = 0,
                RslvAsmIdx = 0
            };

            var ty = new MetadataTokenName
            {
                Name       = "",
                Id         = 1544,
                DeclTypeId = 2233,
                OwnAsmIdx  = 1,
                RslvAsmIdx = 1
            };

            var testSubject = new MetadataTokenNameComparer();
            var testResult  = testSubject.Equals(tx, ty);

            Assert.IsTrue(testResult);
        }
Ejemplo n.º 2
0
 private static MetadataTokenName AccumulateItems(MetadataTokenName something)
 {
     if (something == null)
     {
         return(null);
     }
     _accum.Push(something);
     return(something);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// An optional invocation, the caller could just invoke the ReassignAllInterfaceTokens
 /// on the <see cref="subjectNames"/>; however, for some assemblies this takes a long time.
 /// This option does the same thing only on a remote process with a progress indicator.
 /// </summary>
 public TokenReassignResponse ReassignTokenNames(MetadataTokenName subjectNames, MetadataTokenName foreignNames,
                                                 MetadataTokenType foreignTokenTypes, string rootAssemblyName = "")
 {
     _reassignTokenNamesCmd.Request = new TokenReassignRequest
     {
         SubjectTokenNames = subjectNames,
         ForeignTokenNames = foreignNames,
         ForeignTokenTypes = foreignTokenTypes,
         AsmName           = rootAssemblyName
     };
     return(_reassignTokenNamesCmd.Receive(null));
 }
Ejemplo n.º 4
0
        public static void SaveToFile(string filePath, MetadataTokenName rootTokenName)
        {
            if (rootTokenName?.Items == null || !rootTokenName.Items.Any())
            {
                return;
            }
            var json = JsonConvert.SerializeObject(rootTokenName, Formatting.None,
                                                   new JsonSerializerSettings {
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore
            });

            File.WriteAllText(filePath, json);
        }
Ejemplo n.º 5
0
        public void TestReassignAnyItemsByName()
        {
            var testInput     = GetTestMetadataTokenNameTree();
            var testSearchFor = new MetadataTokenName {
                Name = "(I) [2,0]"
            };

            var testReplacement = new MetadataTokenName
            {
                Name  = "*new* (I) [2,0]",
                Items = new[]
                {
                    new MetadataTokenName
                    {
                        Name = "*added* [2,0,0]"
                    },
                    new MetadataTokenName
                    {
                        Name  = "*added* [2,0,1]",
                        Items = new []
                        {
                            new MetadataTokenName
                            {
                                Name = "*added* [2,0,1,0]"
                            }
                        }
                    }
                }
            };

            testInput.ReassignAnyItemsByName(testSearchFor, testReplacement);
            var testResultItem = new MetadataTokenName();
            Func <MetadataTokenName, bool> searchFor             = (v) => string.Equals(v?.Name, testReplacement.Name);
            Func <MetadataTokenName, MetadataTokenName> getMatch = (v) => testResultItem = v;

            testInput.IterateTree(searchFor, getMatch);

            Assert.IsNotNull(testResultItem);
            Assert.AreEqual("*new* (I) [2,0]", testResultItem.Name);
            Assert.IsNotNull(testResultItem.Items);
            Assert.AreEqual("*added* [2,0,0]", testResultItem.Items[0].Name);
            Assert.AreEqual("*added* [2,0,1]", testResultItem.Items[1].Name);
            Assert.IsNotNull(testResultItem.Items[1].Items);
            Assert.AreEqual("*added* [2,0,1,0]", testResultItem.Items[1].Items[0].Name);
        }
Ejemplo n.º 6
0
        public void TestEquals_SameVariable()
        {
            var tx = new MetadataTokenName
            {
                Name       = "",
                Id         = 4451,
                DeclTypeId = 3322,
                OwnAsmIdx  = 0,
                RslvAsmIdx = 0
            };

            var ty = tx;

            var testSubject = new MetadataTokenNameComparer();
            var testResult  = testSubject.Equals(tx, ty);

            Assert.IsTrue(testResult);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Locates the <see cref="CgMember"/> who matches <see cref="tokenName"/>.
        /// </summary>
        /// <param name="tokenName"></param>
        /// <returns></returns>
        public CgMember FindCgMemberByTokenName(MetadataTokenName tokenName)
        {
            if (tokenName == null)
            {
                return(null);
            }

            var byToken = FindCgMember(tokenName.Id);

            if (byToken != null)
            {
                return(byToken);
            }

            if (string.IsNullOrWhiteSpace(tokenName.Name))
            {
                return(null);
            }

            var methodName = MetadataTokenName.ParseMethodNameFromTokenName(tokenName.Name);
            var argNames   = MetadataTokenName.ParseArgsFromTokenName(tokenName.Name);

            return(FindCgMember(methodName, argNames));
        }
Ejemplo n.º 8
0
        public static MetadataTokenName GetTestMetadataTokenNameTree()
        {
            /*
             *                                 root
             *                                  o
             *                                  |
             *                    o-----------o-+----------o
             *                   (A)          |            |
             *                                |            |
             *          o-----------o-------o-+----o    o--+------o
             *          |          (C)      |     (H)  (I)        |
             *          |                   |                     |
             *          o          o------o-+----o          o-----+------o
             *          |          |     (F)     |          |           (M)
             *          |          |             |          |
             *          o       o--+---o         o       o--+-o----o
             *         (B)     (D)    (E)        (G)    (J)  (K)  (L)
             *
             */

            var testInput = new MetadataTokenName
            {
                Name  = "root",
                Items = new[]
                {
                    new MetadataTokenName {
                        Name = "(A) [0]"
                    },
                    new MetadataTokenName
                    {
                        Name  = "[1]",
                        Items = new []
                        {
                            new MetadataTokenName
                            {
                                Name  = "[1,0]",
                                Items = new []
                                {
                                    new MetadataTokenName
                                    {
                                        Name  = "[1,0,0]",
                                        Items = new []
                                        {
                                            new MetadataTokenName {
                                                Name = "(B) [1,0,0,0]"
                                            }
                                        }
                                    }
                                }
                            },
                            new MetadataTokenName
                            {
                                Name = "(C) [1,1]"
                            },
                            new MetadataTokenName
                            {
                                Name  = "[1,2]",
                                Items = new []
                                {
                                    new MetadataTokenName
                                    {
                                        Name  = "[1,2,0]",
                                        Items = new []
                                        {
                                            new MetadataTokenName {
                                                Name = "(D) [1,2,0,0]"
                                            },
                                            new MetadataTokenName {
                                                Name = "(E) [1,2,0,1]"
                                            }
                                        }
                                    },
                                    new MetadataTokenName
                                    {
                                        Name = "(F) [1,2,1]"
                                    },
                                    new MetadataTokenName
                                    {
                                        Name  = "[1,2,2]",
                                        Items = new []
                                        {
                                            new MetadataTokenName {
                                                Name = "(G) [1,2,2,0]"
                                            }
                                        }
                                    }
                                }
                            },
                            new MetadataTokenName
                            {
                                Name = "(H) [1,3]"
                            }
                        }
                    },
                    new MetadataTokenName
                    {
                        Name  = "[2]",
                        Items = new []
                        {
                            new MetadataTokenName
                            {
                                Name = "(I) [2,0]"
                            },
                            new MetadataTokenName
                            {
                                Name  = "[2,1]",
                                Items = new []
                                {
                                    new MetadataTokenName
                                    {
                                        Name  = "[2,1,0]",
                                        Items = new []
                                        {
                                            new MetadataTokenName {
                                                Name = "(J) [2,1,0,0]"
                                            },
                                            new MetadataTokenName {
                                                Name = "(K) [2,1,0,1]"
                                            },
                                            new MetadataTokenName {
                                                Name = "(L) [2,1,0,2]"
                                            },
                                        }
                                    },
                                    new MetadataTokenName
                                    {
                                        Name = "(M) [2,1,1]"
                                    }
                                }
                            }
                        }
                    }
                }
            };

            return(testInput);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Intended for resolving method calls of types defined in another assembly.
        /// </summary>
        /// <param name="owningAsm"></param>
        /// <param name="tokenName">The name as drafted from <see cref="AssemblyAnalysis.ConvertToMetadataTokenName"/></param>
        /// <param name="mi"></param>
        /// <param name="msgOut">Intended for debug trace from the Console.</param>
        /// <returns></returns>
        internal bool TryResolveRtMemberInfo(Assembly owningAsm, string tokenName, out MemberInfo mi, StringBuilder msgOut = null)
        {
            //default the out variable
            mi = null;

            //expect token name to match naming given herein
            if (String.IsNullOrWhiteSpace(tokenName))
            {
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'the token name is null'");
                }
                return(false);
            }
            if (!tokenName.Contains(Constants.TYPE_METHOD_NAME_SPLIT_ON))
            {
                if (msgOut != null)
                {
                    msgOut.AppendFormat(", Message:'[{0}] does not contain {1}'", tokenName,
                                        Constants.TYPE_METHOD_NAME_SPLIT_ON);
                }
            }

            if (owningAsm == null)
            {
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'the owning assembly is null'");
                }
                return(false);
            }

            var assemblyName = owningAsm.GetName().Name;
            var typeName     = MetadataTokenName.CtorTypeNameFromTokenName(tokenName, assemblyName);

            if (String.IsNullOrWhiteSpace(typeName))
            {
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'could not parse type name'");
                }
                return(false);
            }
            Type asmType = null;

            try
            {
                //framework throwing null-ref ex despite null checks
                asmType = owningAsm.NfGetType(typeName, false, _myProgram.LogFile);
            }
            catch
            {
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'Assembly.GetType threw exception'");
                }
                return(false);
            }
            if (asmType == null)
            {
                if (msgOut != null)
                {
                    msgOut.AppendFormat(", Message:'assembly {0} could not resolve {1}'", assemblyName,
                                        typeName);
                }
                return(false);
            }

            var methodName = MetadataTokenName.ParseMethodNameFromTokenName(tokenName);

            if (String.IsNullOrWhiteSpace(methodName))
            {
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'could not parse method name'");
                }
                return(false);
            }

            MethodInfo methodInfo = null;

            //try easiest first
            try
            {
                methodInfo = asmType.NfGetMethod(methodName, NfSettings.DefaultFlags);
            }
            catch (AmbiguousMatchException) { }//is overloaded

            //try it the formal way
            if (methodInfo == null)
            {
                var args     = MetadataTokenName.ParseArgsFromTokenName(tokenName).ToArray();
                var argTypes = args.Length <= 0
                    ? Type.EmptyTypes
                    : args.Select(Type.GetType).Where(x => x != null).ToArray();

                //there must be a one-for-one match of string names to first-class types
                if (args.Length == argTypes.Length)
                {
                    methodInfo = asmType.NfGetMethod(methodName, NfSettings.DefaultFlags, null, argTypes, null,
                                                     false, _myProgram.LogFile);
                }
            }

            //try it the very slow but certain way
            if (methodInfo == null)
            {
                var methodInfos = asmType.NfGetMethods(NfSettings.DefaultFlags, false, _myProgram.LogFile);
                if (methodInfos.Length <= 0)
                {
                    if (msgOut != null)
                    {
                        msgOut.AppendFormat(", Assembly:'{0}'\n", assemblyName);
                        msgOut.AppendFormat(", Type:'{0}'\n", typeName);
                        msgOut.Append(", Message:'does not have any methods'");
                    }
                    return(false);
                }
                foreach (var info in methodInfos)
                {
                    var asTokenName = AssemblyAnalysis.ConvertToMetadataTokenName(info, _myProgram.AsmIndicies, IsIgnore, _myProgram.LogFile);
                    if (asTokenName == null || string.IsNullOrWhiteSpace(asTokenName.Name))
                    {
                        continue;
                    }
                    if (string.Equals(asTokenName.Name, tokenName))
                    {
                        methodInfo = info;
                        break;
                    }
                }
            }

            if (methodInfo == null)
            {
                if (msgOut != null)
                {
                    msgOut.AppendFormat(", Assembly:'{0}'\n", assemblyName);
                    msgOut.AppendFormat(", Type:'{0}'\n", typeName);
                    msgOut.AppendFormat(", Method:'{0}'\n", methodName);
                    msgOut.Append(", Message:'was not found'");
                }
                return(false);
            }

            mi = methodInfo;
            return(true);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Attempts to resolve <see cref="tokenId"/> to a <see cref="MetadataTokenName"/>
        /// </summary>
        /// <param name="resolvesWith"></param>
        /// <param name="tokenId"></param>
        /// <param name="tokenName"></param>
        /// <param name="msgOut">Intended for debug trace from the Console.</param>
        /// <returns></returns>
        internal bool ResolveSingleTokenName(Assembly resolvesWith, MetadataTokenId tokenId,
                                             out MetadataTokenName tokenName, StringBuilder msgOut = null)
        {
            tokenName = null;
            if (tokenId.Id == 0)
            {
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'the token id is zero'");
                }
                return(false);
            }
            if (_myProgram.TokenId2NameCache.ContainsKey(tokenId))
            {
                tokenName = _myProgram.TokenId2NameCache[tokenId];
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'token previously resolved'");
                }

                return(true);
            }
            if (resolvesWith == null)
            {
                if (msgOut != null)
                {
                    msgOut.Append(string.Format(", Message:'resolve assembly idx {0} has no match'", tokenId.RslvAsmIdx));
                }

                return(false);
            }

            MemberInfo mi;
            var        rtMiRslt = false;

            rtMiRslt = TryResolveRtMemberInfo(resolvesWith.ManifestModule, tokenId, out mi, msgOut);
            if (!rtMiRslt)
            {
                return(false);
            }
            if (mi == null)
            {
                return(false);
            }

            tokenName = AssemblyAnalysis.ConvertToMetadataTokenName(mi, _myProgram.AsmIndicies, IsIgnore, _myProgram.LogFile);

            if (tokenName == null)
            {
                if (msgOut != null)
                {
                    msgOut.Append(", Message:'could not construct a token name'");
                }

                return(false);
            }
            tokenName.Id         = tokenId.Id;
            tokenName.RslvAsmIdx = tokenId.RslvAsmIdx;
            tokenName.DeclTypeId = mi.DeclaringType?.MetadataToken ?? 0;
            return(true);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Helper method which resolves the assembly using the <see cref="tokenId"/> RslvAsmIdx.
        /// </summary>
        /// <param name="tokenId"></param>
        /// <param name="tokenName"></param>
        /// <param name="msgOut">Intended for debug trace from the Console.</param>
        /// <returns></returns>
        internal bool ResolveSingleTokenName(MetadataTokenId tokenId, out MetadataTokenName tokenName, StringBuilder msgOut = null)
        {
            var manifestAsm = _myProgram.AsmIndicies.GetAssemblyByIndex(tokenId.RslvAsmIdx);

            return(ResolveSingleTokenName(manifestAsm, tokenId, out tokenName, msgOut));
        }
Ejemplo n.º 12
0
        public override byte[] Execute(byte[] arg)
        {
            MyProgram.PrintToConsole();
            MyProgram.PrintToConsole($"{nameof(GetTokenNames)} invoked");
            MyProgram.ProgressMessageState = null;
            try
            {
                var myIaaProgram = ((IaaProgram)MyProgram);
                if (myIaaProgram.AsmInited != true)
                {
                    MyProgram.PrintToConsole("no assemblies are loaded - call GetAsmIndices");
                    return(JsonEncodedResponse(
                               new TokenNameResponse
                    {
                        Msg = "no assemblies are loaded - call GetAsmIndices",
                        St = MetadataTokenStatus.Error
                    }));
                }

                var json   = Encoding.UTF8.GetString(arg);
                var rqst   = JsonConvert.DeserializeObject <TokenNameRequest>(json);
                var tokens = rqst.Tokens ?? myIaaProgram.TokenIdResponse?.Tokens;

                if (tokens == null || tokens.Length <= 0)
                {
                    return(JsonEncodedResponse(new TokenNameResponse
                    {
                        Msg = "parse failed",
                        St = MetadataTokenStatus.Error
                    }));
                }

                var names = myIaaProgram.UtilityMethods.ResolveAllTokenNames(tokens);
                Console.Write('\n');
                var tokenNameRspn = new TokenNameResponse {
                    Names = names.ToArray()
                };
                if (rqst.MapFullCallStack && myIaaProgram.TokenTypeResponse != null &&
                    myIaaProgram.TokenIdResponse != null)
                {
                    var nameRoot      = tokenNameRspn.GetAsRoot();
                    var tokenRoot     = myIaaProgram.TokenIdResponse.GetAsRoot();
                    var typeRoot      = myIaaProgram.TokenTypeResponse.GetAsRoot();
                    var asmRspn       = myIaaProgram.AsmIndicies;
                    var fullCallStack =
                        MetadataTokenName.BuildMetadataTokenName(nameRoot, tokenRoot, asmRspn, typeRoot, MyProgram.PrintToConsole);
                    if (fullCallStack?.Items != null)
                    {
                        tokenNameRspn.Names = fullCallStack.Items;
                    }
                }

                myIaaProgram.TokenNameResponse = tokenNameRspn;
                return(JsonEncodedResponse(tokenNameRspn));
            }
            catch (Exception ex)
            {
                MyProgram.PrintToConsole(ex);
                return(JsonEncodedResponse(new TokenNameResponse
                {
                    Msg = string.Format(ex.Message),
                    St = MetadataTokenStatus.Error
                }));
            }
        }
Ejemplo n.º 13
0
        /// <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&apos;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);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Transforms a <see cref="MemberInfo"/> into a <see cref="MetadataTokenName"/>
        /// getting as much info as possiable 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>
        /// <returns></returns>
        public static MetadataTokenName ConvertToMetadataTokenName(MemberInfo mi, AsmIndicies indicies, Func<string, bool> isIgnore)
        {
            if (mi == null)
                return null;

            var localIsIgnore = isIgnore ?? (s => false);
            var localIndicies = indicies ?? new AsmIndicies { Asms = new MetadataTokenAsm[0] };

            var tokenName = new MetadataTokenName { Name = mi.Name, Label = mi.GetType().Name };

            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.Replace($"{asmName}", string.Empty)
                    : type.FullName;
                if (!string.Equals(expandedName, tokenName.Name, StringComparison.OrdinalIgnoreCase))
                    tokenName.Name = expandedName;

                tokenName.OwnAsmIdx = t.IndexId;
                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)
                ? mi.DeclaringType.FullName.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;

            var mtiParams = mti.GetParameters();
            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;
                if (!param.ParameterType.IsGenericType)
                {
                    paramNames.Add(workingName);
                    continue;
                }

                var paramsGen = param.ParameterType.GetGenericArguments();
                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;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Resolves the outbound call stack for the given <see cref="token"/>
        /// </summary>
        /// <param name="token"></param>
        /// <param name="depth"></param>
        /// <param name="stackTrc">For detecting recursive call patterns</param>
        /// <param name="msgOut">For getting details on recursion.</param>
        internal void ResolveCallOfCall(MetadataTokenId token, ref int depth, Stack <MetadataTokenId> stackTrc, StringBuilder msgOut)
        {
            if (msgOut != null)
            {
                if (depth > 0)
                {
                    msgOut.Append(new string(' ', depth));
                }

                msgOut.AppendFormat("Depth:{0}", depth);
                msgOut.AppendFormat(", Token:{0}.0x{1}", token.RslvAsmIdx, token.Id.ToString("X4"));
            }
            //detect if we are in a recursive call
            if (stackTrc.Any(x => x.Equals(token)))
            {
                if (msgOut != null)
                {
                    msgOut.AppendLine(", Message:'present in stack trace'");
                }
                return;
            }

            stackTrc.Push(new MetadataTokenId {
                Id = token.Id, RslvAsmIdx = token.RslvAsmIdx
            });

            //increment the current depth
            depth += 1;

            //abort if max depth has been reached
            if (depth > ((IaaProgram)MyProgram).MaxRecursionDepth)
            {
                depth -= 1;
                MyProgram.PrintToConsole(
                    String.Format("Max Recursion Depth @ {0}.{1}\n", token.RslvAsmIdx, token.Id));
                if (msgOut != null)
                {
                    msgOut.AppendLine(", Message:'max recursion depth'");
                }
                return;
            }

            //when there are already Items then leave them as is
            if (token.Items != null && token.Items.Length > 0)
            {
                depth -= 1;
                if (msgOut != null)
                {
                    msgOut.AppendLine(", Message:'Items already present'");
                }
                return;
            }

            //don't waste clock cycles on Ignore types
            if (((IaaProgram)MyProgram).DisolutionCache.Contains(token))
            {
                depth -= 1;
                if (msgOut != null)
                {
                    msgOut.AppendLine(", Message:'token in DisolutionCache'");
                }
                return;
            }

            //resolve token to name
            MetadataTokenName tokenName = null;

            if (((IaaProgram)MyProgram).TokenId2NameCache.ContainsKey(token))
            {
                tokenName = ((IaaProgram)MyProgram).TokenId2NameCache[token];
            }
            else
            {
                // the token must be resolvable with the its manifest module
                var resolveRslt = ((IaaProgram)MyProgram).UtilityMethods.ResolveSingleTokenName(token, out tokenName, msgOut);
                if (!resolveRslt || tokenName == null)
                {
                    ((IaaProgram)MyProgram).DisolutionCache.Add(token);
                    depth -= 1;
                    if (msgOut != null)
                    {
                        msgOut.AppendLine(", Message:'ResolveSingleTokenName failed'");
                    }
                    return;
                }
                ((IaaProgram)MyProgram).TokenId2NameCache.Add(token, tokenName);
            }

            //only proceed to find calls of calls, types are resolved elsewhere
            if (!tokenName.IsMethodName())
            {
                depth -= 1;
                if (msgOut != null)
                {
                    msgOut.AppendLine(", Message:'token is not a method'");
                }
                return;
            }

            //match is on Asm Name, not type nor member name
            var owningAsmName = ((IaaProgram)MyProgram).AsmIndicies.Asms.FirstOrDefault(x => x.IndexId == tokenName.OwnAsmIdx);

            if (owningAsmName == null)
            {
                ((IaaProgram)MyProgram).DisolutionCache.Add(token);
                depth -= 1;
                if (msgOut != null)
                {
                    msgOut.AppendLine(string.Format(", Message:'owning assembly idx {0} has no match'", tokenName.OwnAsmIdx));
                }
                return;
            }

            //check for match of asm name to user defined regex
            if (!Regex.IsMatch(owningAsmName.AssemblyName, ((IaaProgram)MyProgram).AssemblyNameRegexPattern))
            {
                ((IaaProgram)MyProgram).DisolutionCache.Add(token);
                if (msgOut != null)
                {
                    msgOut.AppendLine(string.Format(", Message:'assembly name [{1}] does not match regex [{0}]'",
                                                    ((IaaProgram)MyProgram).AssemblyNameRegexPattern, owningAsmName.AssemblyName));
                }

                depth -= 1;
                return;
            }

            //resolve token to runtime member info
            MemberInfo mi;
            var        rtMiRslt =
                ((IaaProgram)MyProgram).UtilityMethods.TryResolveRtMemberInfo(((IaaProgram)MyProgram).AsmIndicies.GetAssemblyByIndex(owningAsmName.IndexId),
                                                                              tokenName.Name, out mi, msgOut);

            if (!rtMiRslt)
            {
                ((IaaProgram)MyProgram).DisolutionCache.Add(token);
                depth -= 1;
                return;
            }

            //get the token as it is called in its own assembly
            var r = AssemblyAnalysis.GetMetadataToken(mi, true, tokenName.OwnAsmIdx);

            if (stackTrc.Any(x => x.Equals(r)))
            {
                depth        -= 1;
                token.IsByRef = 1;
                if (msgOut != null)
                {
                    msgOut.AppendLine(string.Format(", Message:'name resolved token id {0},{1} found in stack trace'",
                                                    r.RslvAsmIdx, r.Id.ToString("X4")));
                }
                return;
            }

            //this token differs from the method arg 'token'
            stackTrc.Push(new MetadataTokenId {
                Id = r.Id, RslvAsmIdx = r.RslvAsmIdx
            });

            //unwind when its a terminal token
            if (r.Items == null || r.Items.Length <= 0)
            {
                depth -= 1;
                if (msgOut != null)
                {
                    msgOut.AppendLine(string.Format(", Message:'name resolved token id {0},{1} is a terminal node'",
                                                    r.RslvAsmIdx, r.Id.ToString("X4")));
                }

                return;
            }

            //these token ids are only resolvable to the asm who owns MemberInfo(mi)
            token.Items = r.Items;

            //recurse each of these calls-of-calls[...]-of-calls
            foreach (var iToken in token.Items)
            {
                ResolveCallOfCall(iToken, ref depth, stackTrc, msgOut);
            }

            depth -= 1;
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Locates the <see cref="CgMember"/> in <see cref="Methods"/> who matches <see cref="tokenName"/>.
        /// </summary>
        /// <param name="tokenName"></param>
        /// <returns></returns>
        public CgMember FindCgMethodByTokenName(MetadataTokenName tokenName)
        {
            if (tokenName == null)
                return null;
            if (string.IsNullOrWhiteSpace(tokenName.Name))
                return null;
            if (!tokenName.IsMethodName())
                return null;
            var methodName = AssemblyAnalysis.ParseMethodNameFromTokenName(tokenName.Name);
            if (string.IsNullOrWhiteSpace(methodName))
                return null;
            string isPropName;
            if (NfTypeName.IsClrMethodForProperty(tokenName.Name, out isPropName))
            {
                methodName = isPropName;
                var propMatches = Properties.Where(p => string.Equals(p.Name, methodName)).ToArray();
                if (propMatches.Length >= 1)
                    return propMatches.First();
            }

            var matches = Methods.Where(x => string.Equals(x.Name, methodName)).ToArray();
            if (matches.Length <= 0)
                return null;
            if (matches.Length == 1)
                return matches.First();

            //attempt to match on arg count first
            var argNames = AssemblyAnalysis.ParseArgsFromTokenName(tokenName.Name);
            var argCount = argNames == null ? 0 : argNames.Length;

            matches = Methods.Where(x => x.Args.Count == argCount).ToArray();
            if (matches.Length <= 0)
                return null;
            if (matches.Length == 1)
                return matches.First();
            if (argNames == null)
                return null;

            //attempt to match by args names
            var argNamesLikeThese = argNames.Select(x => Settings.LangStyle.TransformClrTypeSyntax(x));

            foreach (var match in matches)
            {
                if (match.Args.All(nfArg => argNamesLikeThese.Any(token => string.Equals(nfArg.ArgType, token))))
                    return match;
            }
            return null;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Attempts to resolve <see cref="tokenId"/> to a <see cref="MetadataTokenName"/>
        /// </summary>
        /// <param name="resolvesWith"></param>
        /// <param name="tokenId"></param>
        /// <param name="tokenName"></param>
        /// <param name="msgOut">Inteneded for debug trace from the Console.</param>
        /// <returns></returns>
        internal bool ResolveSingleTokenName(Assembly resolvesWith, MetadataTokenId tokenId,
            out MetadataTokenName tokenName, StringBuilder msgOut = null)
        {
            tokenName = null;
            if (tokenId.Id == 0)
            {
                if (msgOut != null)
                    msgOut.Append(", Message:'the token id is zero'");
                return false;
            }
            if (_myProgram.TokenId2NameCache.ContainsKey(tokenId))
            {
                tokenName = _myProgram.TokenId2NameCache[tokenId];
                if (msgOut != null)
                    msgOut.Append(", Message:'token previously resolved'");

                return true;
            }
            if (resolvesWith == null)
            {
                if (msgOut != null)
                    msgOut.Append(string.Format(", Message:'resolve assembly idx {0} has no match'", tokenId.RslvAsmIdx));

                return false;
            }

            MemberInfo mi;
            var rtMiRslt = false;
            rtMiRslt = TryResolveRtMemberInfo(resolvesWith.ManifestModule, tokenId, out mi, msgOut);
            if (!rtMiRslt)
            {
                return false;
            }
            if (mi == null)
            {
                return false;
            }

            tokenName = AssemblyAnalysis.ConvertToMetadataTokenName(mi, _myProgram.AsmIndicies, IsIgnore);

            if (tokenName == null)
            {
                if (msgOut != null)
                    msgOut.Append(", Message:'could not construct a token name'");

                return false;
            }
            tokenName.Id = tokenId.Id;
            tokenName.RslvAsmIdx = tokenId.RslvAsmIdx;
            return true;
        }
Ejemplo n.º 18
0
 /// <summary>
 /// Helper method which resolves the assembly using the <see cref="tokenId"/> RslvAsmIdx.
 /// </summary>
 /// <param name="tokenId"></param>
 /// <param name="tokenName"></param>
 /// <param name="msgOut">Inteneded for debug trace from the Console.</param>
 /// <returns></returns>
 internal bool ResolveSingleTokenName(MetadataTokenId tokenId, out MetadataTokenName tokenName, StringBuilder msgOut = null)
 {
     var manifestAsm = _myProgram.AsmIndicies.GetAssemblyByIndex(tokenId.RslvAsmIdx);
     return ResolveSingleTokenName(manifestAsm, tokenId, out tokenName, msgOut);
 }