Bump corefx
[mono.git] / mcs / tools / cil-stringreplacer / cil-stringreplacer.cs
index f86922be2bf58e3560dcd3e318ec0d80a0d2f2a1..9892827b2d79088e979acea2849bd0f7256a0b3f 100644 (file)
@@ -40,6 +40,7 @@ public class Program
                public bool ShowHelp { get; set; }
                public bool Verbose { get; set; }
                public List<string> ResourcesStrings { get; }
+               public string ILFile { get; set; }
 
                public CmdOptions ()
                {
@@ -54,10 +55,12 @@ public class Program
                var p = new OptionSet () {
                        { "r|resourcestrings=", "File with string resource in key=value format",
                                v => options.ResourcesStrings.Add (v) },
-                       { "h|help",  "Display available options", 
+                       { "h|help",  "Display available options",
                                v => options.ShowHelp = v != null },
-                       { "v|verbose",  "Use verbose output", 
-                               v => options.Verbose = v != null },                     
+                       { "v|verbose",  "Use verbose output",
+                               v => options.Verbose = v != null },
+                       { "ilreplace=", "File with IL code to be used instead",
+                               v => options.ILFile = v },
                };
 
                List<string> extra;
@@ -100,31 +103,87 @@ public class Program
 
        static void RewriteAssembly (string assemblyLocation, Dictionary<string, string> resourcesStrings, CmdOptions options)
        {
-               var assembly = AssemblyDefinition.ReadAssembly (assemblyLocation);
-               foreach (var module in assembly.Modules) {
-                       foreach (var type in module.GetTypes ()) {
-                               foreach (var method in type.Methods) {
-                                       if (!method.HasBody)
-                                               continue;
-                                       
-                                       foreach (var instr in method.Body.Instructions) {
-                                               if (instr.OpCode != OpCodes.Ldstr)
+               var methods = new Dictionary<string, MethodBody> (StringComparer.Ordinal);
+               if (options.ILFile != null) {
+                       var rp = new ReaderParameters {
+                               InMemory = true
+                       };
+
+                       using (var module = ModuleDefinition.ReadModule (options.ILFile,rp)) {
+                               foreach (var type in module.GetTypes ()) {
+                                       foreach (var method in type.Methods) {
+                                               if (!method.HasBody)
                                                        continue;
 
-                                               string value;
-                                               if (resourcesStrings.TryGetValue ((string)instr.Operand, out value)) {
-                                                       if (options.Verbose) {
-                                                               Console.WriteLine ($"Replacing '{instr.Operand}' with '{value}'");
+                                               methods.Add (method.FullName, method.Body);
+                                       }
+                               }
+                       }
+               }
+
+               var readerParameters = new ReaderParameters {
+                       ReadSymbols = true,
+                       ReadWrite = true,
+                       SymbolReaderProvider = new DefaultSymbolReaderProvider (false)
+               };
+
+               using (var assembly = AssemblyDefinition.ReadAssembly (assemblyLocation, readerParameters)) {
+                       foreach (var module in assembly.Modules) {
+                               foreach (var type in module.GetTypes ()) {
+                                       foreach (var method in type.Methods) {
+                                               if (!method.HasBody)
+                                                       continue;
+
+                                               MethodBody newBody;
+                                               if (methods.TryGetValue (method.FullName, out newBody)) {
+                                                       var mbody = method.Body;
+                                                       mbody.Instructions.Clear ();
+                                                       foreach (var instr in newBody.Instructions) {
+                                                               switch (instr.OpCode.OperandType) {
+                                                               case OperandType.InlineType:
+                                                                       var tr = (TypeReference)instr.Operand;
+                                                                       foreach (var t in method.GenericParameters) {
+                                                                               if (tr.FullName == t.FullName) {
+                                                                                       instr.Operand = t;
+                                                                                       break;
+                                                                               }
+                                                                       }
+
+                                                                       break;
+                                                               }
+
+                                                               mbody.Instructions.Add (instr);
                                                        }
 
-                                                       instr.Operand = value;
+                                                       method.Body.Variables.Clear ();
+                                                       foreach (var variable in newBody.Variables) {
+                                                               mbody.Variables.Add (variable);
+                                                       }
+                                               }
+
+                                               foreach (var instr in method.Body.Instructions) {
+                                                       if (instr.OpCode != OpCodes.Ldstr)
+                                                               continue;
+
+                                                       string value;
+                                                       if (resourcesStrings.TryGetValue ((string)instr.Operand, out value)) {
+                                                               if (options.Verbose) {
+                                                                       Console.WriteLine ($"Replacing '{instr.Operand}' with '{value}'");
+                                                               }
+
+                                                               instr.Operand = value;
+                                                       }
                                                }
                                        }
                                }
                        }
-               }
 
-               assembly.Write (assemblyLocation);
+                       var writerParameters = new WriterParameters () {
+                               WriteSymbols = assembly.MainModule.HasSymbols
+                       };
+
+                       assembly.Write (writerParameters);
+               }
        }
 
        static bool LoadGetResourceStrings (Dictionary<string, string> resourcesStrings, CmdOptions options)