Exemplo n.º 1
0
        /// <summary>
        /// Identifies same variables in new and old. Compute differences between new and old local variable declarations and
        /// uses placeholder in case where it is needed. Placeholders are stored to placeholders container, used to correctly
        /// change IL code of new version of methods.
        /// </summary>
        /// <param name="original">Signature of original version of method.</param>
        /// <param name="newSig">Signature of new version of mehtod.</param>
        /// <param name="placeholders">Container, that holds placeholder translation when method succeded.</param>
        /// <param name="tkOldMethod">Metadata token to the original version of method.</param>
        /// <param name="tkNewMethod">Metadata token to the new version of method.</param>
        /// <param name="translator">Token translator used to translate signatures.</param>
        /// <returns>Signature with placeholders for new version of method in running assembly.</returns>
        public Signature makeSignature(Signature original, Signature newSig, out Dictionary <int, int> placeholders,
                                       uint tkOldMethod, uint tkNewMethod, ITokenTranslator translator)
        {
            placeholders = new Dictionary <int, int>();
            int varCount = original.Types.Count - 2;
            List <LocalVarDefinition> olds;

            if (!oldLocalVars.TryGetValue(tkOldMethod, out olds))
            {
                olds = getDefinitions(tkOldMethod, oldReader);
            }

            List <LocalVarDefinition> news = getDefinitions(tkNewMethod, newReader);

            olds.ForEach((LocalVarDefinition def) =>
            {
                def.ilStart = remapper.TranslateILOffset(def.ilStart);
                def.ilEnd   = remapper.TranslateILOffset(def.ilEnd);
            });
            news.ForEach((LocalVarDefinition def) =>
            {
                if (def.signature != null)
                {
                    def.signature = Signature.Migrate(def.signature, translator, 0);
                }
            });
            List <int> used = new List <int>();

            for (int i = 0; i < news.Count; i++)
            {
                Predicate <LocalVarDefinition> lambda = (LocalVarDefinition def) =>
                {
                    return(def.Same(news[i]));
                };
                if (!olds.Exists(lambda) || used.Contains(olds.FindIndex(lambda)))
                {
                    placeholders.Add(i, olds.Count);
                    original.AddSigPart(news[i].signature);
                    olds.Add(news[i]);
                }
                else
                {
                    int index = olds.FindIndex(lambda);
                    placeholders.Add(i, index);
                    used.Add(index);
                }
            }
            for (int i = 0; i < olds.Count; i++)
            {
                if (!placeholders.ContainsValue(i))
                {
                    olds[i].removed = true;
                }
            }
            original.Types[1].Code    = (uint)olds.Count;
            oldLocalVars[tkOldMethod] = olds;
            return(original);
        }