Example #1
0
        public void ApplyPatches(IEnumerable <Patch> enabledPatches, ISymbolTranslator symbolTranslator)
        {
            InitOriginalType();
            CollectReplacements(symbolTranslator);
            // We already have the list of types we should check for replacement methods, it's the contents of
            // typeReplacements. This dictionary will be modified during fixups, though, so to keep things
            // consistent, iterate on a copy instead of the field itself.
            Dictionary <string, TypeReference> typeReplacementsCopy = new Dictionary <string, TypeReference>(typeReplacements);

            foreach (KeyValuePair <string, TypeReference> nameAndTargetPair in typeReplacementsCopy)
            {
                TypeDefinition decoyType  = source.GetType(nameAndTargetPair.Key);
                TypeDefinition targetType = nameAndTargetPair.Value as TypeDefinition;
                if (targetType != null)
                {
                    // We can only have replacement methods when the target of the parent type
                    // is inside SpacheChem.exe, and therefore is a method definition, not a reference.
                    ReplaceMethodsOnType(decoyType, targetType, enabledPatches);
                    if (decoyType.IsEnum)
                    {
                        HandleEnumFieldInjections(decoyType, enabledPatches);
                    }
                }
            }
        }
Example #2
0
 private void CollectReplacements(ISymbolTranslator symbolTranslator)
 {
     CollectReplacementsForTypes(source.Types, FindTypeDefinition, symbolTranslator);
 }
Example #3
0
        private void CollectReplacementsForTypes(IEnumerable <TypeDefinition> typeDefinitions, TypeFinder typeFinder, ISymbolTranslator symbolTranslator)
        {
            foreach (KeyValuePair <TypeDefinition, CustomAttribute> typePair in FindAnnotated(typeDefinitions, "DecoyAttribute"))
            {
                TypeDefinition  type                    = typePair.Key;
                CustomAttribute decoyAttribute          = typePair.Value;
                string          @namespace              = GetAttributeFieldValue(decoyAttribute, "namespace", "");
                string          scrambledName           = (string)decoyAttribute.ConstructorArguments[0].Value;
                string          translatedScrambledName = symbolTranslator.TranslateType(scrambledName);
                TypeDefinition  targetType              = typeFinder(@namespace, translatedScrambledName);
                typeReplacements.Add(type.FullName, target.ImportReference(targetType));

                if (type.GenericParameters.Count > 0)
                {
                    Dictionary <string, GenericParameter> genericReplacementsForThisType = new Dictionary <string, GenericParameter>();
                    for (int i = 0; i < type.GenericParameters.Count; i++)
                    {
                        genericReplacementsForThisType.Add(type.GenericParameters[i].FullName, targetType.GenericParameters[i]);
                    }
                    genericParameterReplacements.Add(type.FullName, genericReplacementsForThisType);
                }

                CollectMethodReplacementsInType(type, targetType, symbolTranslator.GetMethodTranslator(scrambledName));
                CollectFieldReplacementsInType(type, targetType, symbolTranslator.GetFieldTranslator(scrambledName));

                // Recurse for nested types.
                CollectReplacementsForTypes(type.NestedTypes, (dummy, typeName) => targetType.NestedTypes.First(t => t.Name == typeName), symbolTranslator.GetTranslatorForNestedTypes(scrambledName));
            }
        }