/Test/Mono.Cecil.Tests/Formatter.cs
http://github.com/jbevain/cecil · C# · 193 lines · 158 code · 35 blank · 0 comment · 24 complexity · a32935c52c72a8d5b4f7d4991e2d5ab8 MD5 · raw file
- using System;
- using System.IO;
- using Mono.Cecil;
- using Mono.Cecil.Cil;
- namespace Mono.Cecil.Tests {
- public static class Formatter {
- public static string FormatInstruction (Instruction instruction)
- {
- var writer = new StringWriter ();
- WriteInstruction (writer, instruction);
- return writer.ToString ();
- }
- public static string FormatMethodBody (MethodDefinition method)
- {
- var writer = new StringWriter ();
- WriteMethodBody (writer, method);
- return writer.ToString ();
- }
- public static void WriteMethodBody (TextWriter writer, MethodDefinition method)
- {
- var body = method.Body;
- WriteVariables (writer, body);
- foreach (Instruction instruction in body.Instructions) {
- var sequence_point = body.Method.DebugInformation.GetSequencePoint (instruction);
- if (sequence_point != null) {
- writer.Write ('\t');
- WriteSequencePoint (writer, sequence_point);
- writer.WriteLine ();
- }
- writer.Write ('\t');
- WriteInstruction (writer, instruction);
- writer.WriteLine ();
- }
- WriteExceptionHandlers (writer, body);
- }
- static void WriteVariables (TextWriter writer, MethodBody body)
- {
- var variables = body.Variables;
- writer.Write ('\t');
- writer.Write (".locals {0}(", body.InitLocals ? "init " : string.Empty);
- for (int i = 0; i < variables.Count; i++) {
- if (i > 0)
- writer.Write (", ");
- var variable = variables [i];
- writer.Write ("{0} {1}", variable.VariableType, GetVariableName (variable, body));
- }
- writer.WriteLine (")");
- }
- static string GetVariableName (VariableDefinition variable, MethodBody body)
- {
- string name;
- if (body.Method.DebugInformation.TryGetName (variable, out name))
- return name;
- return variable.ToString ();
- }
- static void WriteInstruction (TextWriter writer, Instruction instruction)
- {
- writer.Write (FormatLabel (instruction.Offset));
- writer.Write (": ");
- writer.Write (instruction.OpCode.Name);
- if (null != instruction.Operand) {
- writer.Write (' ');
- WriteOperand (writer, instruction.Operand);
- }
- }
- static void WriteSequencePoint (TextWriter writer, SequencePoint sequence_point)
- {
- if (sequence_point.IsHidden) {
- writer.Write (".line hidden '{0}'", sequence_point.Document.Url);
- return;
- }
- writer.Write (".line {0},{1}:{2},{3} '{4}'",
- sequence_point.StartLine,
- sequence_point.EndLine,
- sequence_point.StartColumn,
- sequence_point.EndColumn,
- sequence_point.Document.Url);
- }
- static string FormatLabel (int offset)
- {
- string label = "000" + offset.ToString ("x");
- return "IL_" + label.Substring (label.Length - 4);
- }
- static string FormatLabel (Instruction instruction)
- {
- return FormatLabel (instruction.Offset);
- }
- static void WriteOperand (TextWriter writer, object operand)
- {
- if (null == operand) throw new ArgumentNullException ("operand");
- var target = operand as Instruction;
- if (null != target) {
- writer.Write (FormatLabel (target.Offset));
- return;
- }
- var targets = operand as Instruction [];
- if (null != targets) {
- WriteLabelList (writer, targets);
- return;
- }
- string s = operand as string;
- if (null != s) {
- writer.Write ("\"" + s + "\"");
- return;
- }
- var parameter = operand as ParameterDefinition;
- if (parameter != null) {
- writer.Write (ToInvariantCultureString (parameter.Sequence));
- return;
- }
- s = ToInvariantCultureString (operand);
- writer.Write (s);
- }
- static void WriteLabelList (TextWriter writer, Instruction [] instructions)
- {
- writer.Write ("(");
- for (int i = 0; i < instructions.Length; i++) {
- if (i != 0) writer.Write (", ");
- writer.Write (FormatLabel (instructions [i].Offset));
- }
- writer.Write (")");
- }
- static void WriteExceptionHandlers (TextWriter writer, MethodBody body)
- {
- if (!body.HasExceptionHandlers)
- return;
- foreach (var handler in body.ExceptionHandlers) {
- writer.Write ("\t");
- writer.WriteLine (".try {0} to {1} {2} handler {3} to {4}",
- FormatLabel (handler.TryStart),
- FormatLabel (handler.TryEnd),
- FormatHandlerType (handler),
- FormatLabel (handler.HandlerStart),
- FormatLabel (handler.HandlerEnd));
- }
- }
- static string FormatHandlerType (ExceptionHandler handler)
- {
- var handler_type = handler.HandlerType;
- var type = handler_type.ToString ().ToLowerInvariant ();
- switch (handler_type) {
- case ExceptionHandlerType.Catch:
- return string.Format ("{0} {1}", type, handler.CatchType.FullName);
- case ExceptionHandlerType.Filter:
- throw new NotImplementedException ();
- default:
- return type;
- }
- }
- public static string ToInvariantCultureString (object value)
- {
- var convertible = value as IConvertible;
- return (null != convertible)
- ? convertible.ToString (System.Globalization.CultureInfo.InvariantCulture)
- : value.ToString ();
- }
- }
- }