Browse Source

Assembly inspector dumping to JSON for marshal

Josh Engebretson 10 years ago
parent
commit
3ace9111c9

+ 227 - 0
Build/AtomicNETTest/AtomicEditor/AssemblyInspector.cs

@@ -0,0 +1,227 @@
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Metadata;
+using System.Reflection.PortableExecutable;
+using System.Reflection.Metadata.Ecma335;
+using System.Text;
+
+using AtomicEngine;
+
+using File = System.IO.File;
+
+namespace AtomicEditor
+{
+
+	class AssemblyInspector
+	{
+
+    Dictionary<string, InspectorEnum> InspectorEnums = new Dictionary<string, InspectorEnum>();
+    Dictionary<string, InspectorComponent> InspectorComponents = new Dictionary<string, InspectorComponent>();
+
+		PEReader peFile;
+		MetadataReader metaReader;
+
+		public AssemblyInspector ()
+		{
+
+		}
+
+    public string DumpToJSON ()
+    {
+        var dict = new Dictionary<string, object>();
+
+        var enumList = new List<object>();
+        var componentList = new List<object>();
+
+        foreach (var entry in InspectorEnums)
+        {
+          enumList.Add(entry.Value.GetJSONDict());
+        }
+
+        foreach (var entry in InspectorComponents)
+        {
+          componentList.Add(entry.Value.GetJSONDict());
+        }
+
+        dict["enums"] = enumList;
+        dict["components"] = componentList;
+
+        return MiniJSON.Json.Serialize(dict);
+
+    }
+
+		public void Inspect (String pathToAssembly)
+		{
+
+			using (var stream = File.OpenRead (pathToAssembly))
+			using (peFile = new PEReader (stream)) {
+
+				metaReader = peFile.GetMetadataReader ();
+
+				ParseEnums ();
+        ParseComponents();
+			}
+
+		}
+
+    void ParseComponents ()
+		{
+
+			foreach (var handle in metaReader.TypeDefinitions)
+      {
+				var typeDef = metaReader.GetTypeDefinition (handle);
+
+				var baseTypeHandle = typeDef.BaseType;
+
+				if (baseTypeHandle.Kind == HandleKind.TypeReference)
+        {
+
+					var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle);
+
+          if (metaReader.GetString(typeRef.Name) != "CSComponent")
+            continue;
+
+          var inspector = new CSComponentInspector(typeDef, peFile, metaReader);
+
+          var icomponent = inspector.Inspect();
+
+          if (icomponent != null)
+            InspectorComponents[icomponent.Name] = icomponent;
+				}
+			}
+		}
+
+
+		void ParseEnums ()
+		{
+			foreach (var handle in metaReader.TypeDefinitions)
+      {
+				var typeDef = metaReader.GetTypeDefinition (handle);
+
+				var baseTypeHandle = typeDef.BaseType;
+
+				if (baseTypeHandle.Kind == HandleKind.TypeReference)
+        {
+					var typeRef = metaReader.GetTypeReference ((TypeReferenceHandle)baseTypeHandle);
+
+					if (metaReader.GetString (typeRef.Name) == "Enum")
+          {
+						ParseEnum (typeDef);
+					}
+				}
+			}
+		}
+
+		void ParseEnum (TypeDefinition enumTypeDef)
+		{
+
+			// TODO: verify that int32 is the enums storage type for constant read below
+
+      InspectorEnum ienum = new InspectorEnum();
+
+      ienum.Name = metaReader.GetString(enumTypeDef.Name);
+
+      InspectorEnums[ienum.Name] = ienum;
+
+			var fields = enumTypeDef.GetFields ();
+
+			foreach (var fieldHandle in fields) {
+
+				var inspectorField = new InspectorField ();
+
+				var fieldDef = metaReader.GetFieldDefinition (fieldHandle);
+
+				if ((fieldDef.Attributes & FieldAttributes.HasDefault) != 0) {
+
+					var constantHandle = fieldDef.GetDefaultValue ();
+					var constant = metaReader.GetConstant (constantHandle);
+
+					BlobReader constantReader = metaReader.GetBlobReader (constant.Value);
+
+          ienum.Values[metaReader.GetString (fieldDef.Name)] = constantReader.ReadInt32 ();
+
+				}
+			}
+
+			return;
+
+		}
+	}
+
+  internal class InspectorEnum
+  {
+    public String Name;
+    public Dictionary<string, int> Values = new Dictionary<string, int>();
+
+    public Dictionary<string, object> GetJSONDict()
+    {
+      var dict = new Dictionary<string,object>();
+      dict["name"] = Name;
+      dict["values"] = Values;
+      return dict;
+    }
+  }
+
+  internal class InspectorComponent
+  {
+    public String Name;
+		public Dictionary<string, InspectorField> Fields = new Dictionary<string, InspectorField> ();
+
+		public Dictionary<string, object> GetJSONDict()
+		{
+      var dict = new Dictionary<string,object>();
+
+      dict["name"] = Name;
+      var fieldList = new List<object>();
+
+      foreach (var entry in Fields)
+      {
+        fieldList.Add(entry.Value.GetJSONDict());
+      }
+
+      dict["fields"] = fieldList;
+
+      return dict;
+		}
+  }
+
+	internal class InspectorField
+	{
+
+    public Dictionary<string, object> GetJSONDict()
+    {
+
+      var dict = new Dictionary<string,object>();
+
+      dict["isEnum"] = IsEnum;
+      dict["typeName"] = TypeName;
+      dict["name"] = Name;
+      dict["defaultValue"] = DefaultValue;
+
+      dict["customAttrPosArgs"] = CustomAttrPositionalArgs;
+      dict["customAttrNamedArgs"] = CustomAttrNamedArgs;
+
+      return dict;
+
+    }
+
+		public bool IsEnum = false;
+
+		public string TypeName;
+
+		// the Name of the InspectorField
+		public string Name;
+		// The DefaultValue if supplied
+		public string DefaultValue;
+
+		// custom attributes, positional and named
+		public List<string> CustomAttrPositionalArgs = new List<string> ();
+		public Dictionary<string, string> CustomAttrNamedArgs = new Dictionary<string, string> ();
+	}
+
+}

+ 4 - 108
Build/AtomicNETTest/AtomicEditor/AtomicEditor.cs

@@ -16,122 +16,18 @@ using File = System.IO.File;
 
 namespace AtomicEditor
 {
-	class AssemblyInspector
+	class AtomicEditor
 	{
 
-		public static bool ParseEnum(TypeDefinition enumTypeDef, PEReader peFile, MetadataReader metaReader)
-		{
-
-			// TODO: verify that int32 is the enums storage type for constant read below
-
-			var fields = enumTypeDef.GetFields ();
-
-			foreach (var fieldHandle in fields) {
-
-				var inspectorField = new InspectorField ();
-
-				var fieldDef = metaReader.GetFieldDefinition (fieldHandle);
-
-				if ( (fieldDef.Attributes & FieldAttributes.HasDefault) != 0)
-				{
-					 	var constantHandle = fieldDef.GetDefaultValue();
-						var constant = metaReader.GetConstant(constantHandle);
-						BlobReader constantReader = metaReader.GetBlobReader (constant.Value);
-						Console.WriteLine("{0} {1}", metaReader.GetString(fieldDef.Name), constantReader.ReadInt32());
-				}
-			}
-
-			return true;
-
-		}
-
 		public static void InspectAssembly (String pathToAssembly)
 		{
 
 			try {
-				using (var stream = File.OpenRead (pathToAssembly))
-				using (var peFile = new PEReader (stream)) {
-
-					var reader = peFile.GetMetadataReader ();
-
-					foreach (var handle in reader.TypeDefinitions)
-          {
-              var typeDef = reader.GetTypeDefinition(handle);
-
-							var baseTypeHandle = typeDef.BaseType;
-
-							if (baseTypeHandle.Kind == HandleKind.TypeReference)
-							{
-									var typeRef = reader.GetTypeReference((TypeReferenceHandle)baseTypeHandle);
-
-									if (reader.GetString(typeRef.Name) == "Enum")
-									{
-
-										ParseEnum(typeDef, peFile, reader);
-
-									}
-
-									// TODO: validate assembly of CSComponent typeref
-									if (reader.GetString(typeRef.Name) != "CSComponent")
-										continue;
-
-									var inspector = new CSComponentInspector(typeDef, peFile, reader);
-
-									inspector.Inspect();
-
-							}
-
-
-					}
-
-              //uint size, packingSize;
-              //bool hasLayout = entry.GetTypeLayout(out size, out packingSize);
-
-							/*
-							Console.WriteLine(reader.GetString(entry.Name));
-
-							var fields = entry.GetFields();
-							foreach (var fieldHandle in fields)
-							{
-								 // FieldDefinitionHandle
-								 var fieldDef = reader.GetFieldDefinition(fieldHandle);
-								 Console.WriteLine("Field! {0}", reader.GetString(fieldDef.Name));
-							}
-
-							var methods = entry.GetMethods();
-
-							foreach (var methodHandle in methods)
-							{
-								 // FieldDefinitionHandle
-								 var methodDef = reader.GetMethodDefinition(methodHandle);
-
-								 if (reader.GetString(methodDef.Name) == ".ctor")
-								 {
-									 Console.WriteLine("Dumping ctor");
-
-									 var body = peFile.GetMethodBody(methodDef.RelativeVirtualAddress);
-
-									 /*
-									 var value = CSComponentInspector.Instance.DumpMethod(
-									 		reader,
-									 		entry,
-									 		body.MaxStack,
-									 		body.GetILContent(),
-									 		ImmutableArray.Create<CSComponentInspector.LocalInfo>(),     // TODO
-									 		ImmutableArray.Create<CSComponentInspector.HandlerSpan>());
-
-											Console.WriteLine("IL: \n{0}", value);
-										*/
-
-									/*
-								 }
-
 
-							}
+				var inspector = new AssemblyInspector();
+				inspector.Inspect(pathToAssembly);
+				Console.WriteLine(inspector.DumpToJSON());
 
-          }
-					*/
-				}
 			} catch (Exception ex) {
 				Console.WriteLine (ex.Message);
 			}

+ 343 - 343
Build/AtomicNETTest/AtomicEditor/CSComponentInspector.cs

@@ -14,6 +14,8 @@ using System.Reflection.Metadata;
 using System.Reflection.Metadata.Ecma335;
 using System.Reflection.PortableExecutable;
 
+// References
+
 //https://github.com/Microsoft/dotnetsamples/tree/master/System.Reflection.Metadata
 //https://github.com/dotnet/corefx/tree/master/src/System.Reflection.Metadata/tests
 //http://www.cnetion.com/getting-field-values-using-mono-cecil-qq-AUvBjRFgivICeoL1jxJy.php
@@ -31,54 +33,24 @@ using System.Reflection.PortableExecutable;
 
 namespace AtomicEditor
 {
-
-	public class InspectorField
-	{
-		public string TypeName;
-
-		// the Name of the InspectorField
-		public string Name;
-		// The DefaultValue if supplied
-		public string DefaultValue;
-
-		// custom attributes, positional and named
-		public List<string> CustomAttrPositionalArgs = new List<string> ();
-		public Dictionary<string, string> CustomAttrNamedArgs = new Dictionary<string, string> ();
-	}
-
+	
 	public class CSComponentInspector
 	{
 
-		public Dictionary<string, InspectorField> InspectorFields = new Dictionary<string, InspectorField> ();
+		InspectorComponent _inspectorComponent;
 
 		public CSComponentInspector (TypeDefinition typeDef, PEReader peFile, MetadataReader metaReader)
 		{
 			this.typeDef = typeDef;
 			this.peFile = peFile;
 			this.metaReader = metaReader;
-		}
-
-		public void Dump ()
-		{
-			foreach (var entry in InspectorFields) {
-				var field = entry.Value;
-
-				Console.WriteLine ("Inspector Field: {0}", field.Name);
 
-				Console.WriteLine ("   Type Name: {0}", field.TypeName);
-				Console.WriteLine ("   Default Value: {0}", field.DefaultValue);
-
-				Console.WriteLine ("   Positional Custom Attr:");
-				foreach (var p in field.CustomAttrPositionalArgs)
-					if (p.Length != 0)
-						Console.WriteLine ("      {0}", p);
-				Console.WriteLine ("   Named Custom Attr:");
-				foreach (var nentry in field.CustomAttrNamedArgs)
-					Console.WriteLine ("      {0}:{1}", nentry.Key, nentry.Value);
-			}
+			this._inspectorComponent = new InspectorComponent();
+			this._inspectorComponent.Name = metaReader.GetString(typeDef.Name);
 		}
 
-		public bool Inspect ()
+		// Inspect a CSComponent derived class
+		internal InspectorComponent Inspect ()
 		{
 
 			var fields = typeDef.GetFields ();
@@ -115,6 +87,7 @@ namespace AtomicEditor
 
 								// can store local enum typedefs
 								// enum initializers are stored as constant value in the IL
+
 								var typeDef = metaReader.GetTypeDefinition ((TypeDefinitionHandle)token);
 
 								var baseTypeToken = typeDef.BaseType;
@@ -127,7 +100,8 @@ namespace AtomicEditor
 								if (metaReader.GetString (baseTypeRef.Name) != "Enum")
 									continue;
 
-								Console.WriteLine ("Enum TypeDef {0}", metaReader.GetString (typeDef.Name));
+								inspectorField.IsEnum = true;
+								typeName = metaReader.GetString (typeDef.Name);
 
 							} else if (tokenType == HandleKind.TypeReference) {
 
@@ -145,7 +119,7 @@ namespace AtomicEditor
 
 						inspectorField.TypeName = typeName;
 						inspectorField.Name = metaReader.GetString (fieldDef.Name);
-						InspectorFields [inspectorField.Name] = inspectorField;
+						_inspectorComponent.Fields[inspectorField.Name] = inspectorField;
 
 						break;
 					}
@@ -157,6 +131,7 @@ namespace AtomicEditor
 			var methods = typeDef.GetMethods ();
 
 			foreach (var methodHandle in methods) {
+
 				var methodDef = metaReader.GetMethodDefinition (methodHandle);
 
 				if (metaReader.GetString (methodDef.Name) == ".ctor") {
@@ -169,9 +144,9 @@ namespace AtomicEditor
 
 			}
 
-			Dump ();
+			//Dump ();
 
-			return true;
+			return _inspectorComponent;
 
 		}
 
@@ -248,7 +223,7 @@ namespace AtomicEditor
 
 				// support string custom attr for now to simplify things
 				if (paramTypeCode != SignatureTypeCode.String)
-					return false;
+				return false;
 
 				string value;
 
@@ -264,6 +239,7 @@ namespace AtomicEditor
 			short namedParamCount = argsReader.ReadInt16 ();
 
 			for (short i = 0; i < namedParamCount; i++) {
+
 				// Ecma-335 23.3 - A NamedArg is simply a FixedArg preceded by information to identify which field or
 				// property it represents. [Note: Recall that the CLI allows fields and properties to have the same name; so
 				// we require a means to disambiguate such situations. end note] FIELD is the single byte 0x53. PROPERTY is
@@ -281,22 +257,24 @@ namespace AtomicEditor
 
 				// support string custom attr for now to simplify things
 				if (typeCode != SerializationTypeCode.String)
-					return false;
+				return false;
 
 				string name;
+
 				if (!CrackStringInAttributeValue (out name, ref argsReader))
-					return false;
+				return false;
 
 				string value;
-				if (!CrackStringInAttributeValue (out value, ref argsReader))
-					return false;
 
+				if (!CrackStringInAttributeValue (out value, ref argsReader))
+				return false;
 
 				inspectorField.CustomAttrNamedArgs [name] = value;
 
 			}
 
 			return true;
+
 		}
 
 		internal static bool CrackStringInAttributeValue (out string value, ref BlobReader sig)
@@ -324,11 +302,11 @@ namespace AtomicEditor
 		}
 
 		public void InspectILBlock (
-			ImmutableArray<byte> ilBytes,
-			int length,
-			IReadOnlyList<HandlerSpan> spans = null,
-			int blockOffset = 0,
-			IReadOnlyDictionary<int, string> markers = null)
+		ImmutableArray<byte> ilBytes,
+		int length,
+		IReadOnlyList<HandlerSpan> spans = null,
+		int blockOffset = 0,
+		IReadOnlyDictionary<int, string> markers = null)
 		{
 			if (ilBytes == null) {
 				return;
@@ -339,14 +317,14 @@ namespace AtomicEditor
 		}
 
 		private int InspectILBlock (
-			ImmutableArray<byte> ilBytes,
-			int length,
-			IReadOnlyList<HandlerSpan> spans,
-			int blockOffset,
-			int curIndex,
-			int spanIndex,
-			IReadOnlyDictionary<int, string> markers,
-			out int nextSpanIndex)
+		ImmutableArray<byte> ilBytes,
+		int length,
+		IReadOnlyList<HandlerSpan> spans,
+		int blockOffset,
+		int curIndex,
+		int spanIndex,
+		IReadOnlyDictionary<int, string> markers,
+		out int nextSpanIndex)
 		{
 			int lastSpanIndex = spanIndex - 1;
 
@@ -392,7 +370,7 @@ namespace AtomicEditor
 
 					switch (opCode.OperandType) {
 
-					case OperandType.InlineField:
+						case OperandType.InlineField:
 
 						// read token
 						uint fieldToken = ReadUInt32 (ilBytes, ref curIndex);
@@ -411,7 +389,7 @@ namespace AtomicEditor
 
 							InspectorField inspectorField;
 
-							if (InspectorFields.TryGetValue (fieldName, out inspectorField)) {
+							if (_inspectorComponent.Fields.TryGetValue (fieldName, out inspectorField)) {
 								inspectorField.DefaultValue = String.Join (" ", loadedValues.ToArray ());
 							}
 
@@ -420,169 +398,169 @@ namespace AtomicEditor
 						loadedValues.Clear ();
 
 						break;
-					case OperandType.InlineMethod:
+						case OperandType.InlineMethod:
 
 						// new Vector3, etc
 						if (opCode.ToString () == "newobj") {
 
-						} else
+							} else
 							loadedValues.Clear ();
 
-						break;
-					case OperandType.InlineTok:
-					case OperandType.InlineType:
-						ReadUInt32 (ilBytes, ref curIndex);
-						loadedValues.Clear ();
-						break;
+							break;
+							case OperandType.InlineTok:
+							case OperandType.InlineType:
+							ReadUInt32 (ilBytes, ref curIndex);
+							loadedValues.Clear ();
+							break;
 
-					case OperandType.InlineSig: // signature (calli), not emitted by C#/VB
-						ReadUInt32 (ilBytes, ref curIndex);
-						loadedValues.Clear ();
-						break;
+							case OperandType.InlineSig: // signature (calli), not emitted by C#/VB
+							ReadUInt32 (ilBytes, ref curIndex);
+							loadedValues.Clear ();
+							break;
 
-					case OperandType.InlineString:
-                          //sb.Append(" 391 ");
-                          //sb.Append(VisualizeUserString());
+							case OperandType.InlineString:
+							//sb.Append(" 391 ");
+							//sb.Append(VisualizeUserString());
 
-						uint stringToken = ReadUInt32 (ilBytes, ref curIndex);
+							uint stringToken = ReadUInt32 (ilBytes, ref curIndex);
 
-                          // get the kind
-                          //uint tokenKind = stringToken & TokenTypeIds.TokenTypeMask;
-                          // and the rowId
-                          //uint rowId = stringToken & TokenTypeIds.RIDMask;
+							// get the kind
+							//uint tokenKind = stringToken & TokenTypeIds.TokenTypeMask;
+							// and the rowId
+							//uint rowId = stringToken & TokenTypeIds.RIDMask;
 
 
-						UserStringHandle handle = MetadataTokens.UserStringHandle ((int)stringToken);
-						loadedValues.Add (metaReader.GetUserString (handle));
+							UserStringHandle handle = MetadataTokens.UserStringHandle ((int)stringToken);
+							loadedValues.Add (metaReader.GetUserString (handle));
 
-						break;
+							break;
 
-					case OperandType.InlineNone:
+							case OperandType.InlineNone:
 
-						if (opCode == OpCodes.Ldc_I4_0)
+							if (opCode == OpCodes.Ldc_I4_0)
 							loadedValues.Add ("0");
-						else if (opCode == OpCodes.Ldc_I4_1)
+							else if (opCode == OpCodes.Ldc_I4_1)
 							loadedValues.Add ("1");
-						else if (opCode == OpCodes.Ldc_I4_2)
+							else if (opCode == OpCodes.Ldc_I4_2)
 							loadedValues.Add ("2");
-						else if (opCode == OpCodes.Ldc_I4_3)
+							else if (opCode == OpCodes.Ldc_I4_3)
 							loadedValues.Add ("3");
-						else if (opCode == OpCodes.Ldc_I4_4)
+							else if (opCode == OpCodes.Ldc_I4_4)
 							loadedValues.Add ("4");
-						else if (opCode == OpCodes.Ldc_I4_5)
+							else if (opCode == OpCodes.Ldc_I4_5)
 							loadedValues.Add ("5");
-						else if (opCode == OpCodes.Ldc_I4_6)
+							else if (opCode == OpCodes.Ldc_I4_6)
 							loadedValues.Add ("6");
-						else if (opCode == OpCodes.Ldc_I4_7)
+							else if (opCode == OpCodes.Ldc_I4_7)
 							loadedValues.Add ("7");
-						else if (opCode == OpCodes.Ldc_I4_8)
+							else if (opCode == OpCodes.Ldc_I4_8)
 							loadedValues.Add ("8");
-						else if (opCode == OpCodes.Ldc_I4_M1)
+							else if (opCode == OpCodes.Ldc_I4_M1)
 							loadedValues.Add ("-1");
 
-						break;
+							break;
 
-					case OperandType.ShortInlineI:
-						loadedValues.Add (ReadSByte (ilBytes, ref curIndex).ToString ());
-						break;
+							case OperandType.ShortInlineI:
+							loadedValues.Add (ReadSByte (ilBytes, ref curIndex).ToString ());
+							break;
 
-					case OperandType.ShortInlineVar:
-						loadedValues.Add (ReadByte (ilBytes, ref curIndex).ToString ());
-						break;
+							case OperandType.ShortInlineVar:
+							loadedValues.Add (ReadByte (ilBytes, ref curIndex).ToString ());
+							break;
 
-					case OperandType.InlineVar:
-						loadedValues.Add (ReadUInt16 (ilBytes, ref curIndex).ToString ());
-						break;
+							case OperandType.InlineVar:
+							loadedValues.Add (ReadUInt16 (ilBytes, ref curIndex).ToString ());
+							break;
 
-					case OperandType.InlineI:
-						loadedValues.Add (ReadUInt32 (ilBytes, ref curIndex).ToString ());
-						break;
+							case OperandType.InlineI:
+							loadedValues.Add (ReadUInt32 (ilBytes, ref curIndex).ToString ());
+							break;
 
-					case OperandType.InlineI8:
-						loadedValues.Add (ReadUInt64 (ilBytes, ref curIndex).ToString ());
-						break;
+							case OperandType.InlineI8:
+							loadedValues.Add (ReadUInt64 (ilBytes, ref curIndex).ToString ());
+							break;
 
-					case OperandType.ShortInlineR:
-						{
-							loadedValues.Add (ReadSingle (ilBytes, ref curIndex).ToString ());
-						}
-						break;
+							case OperandType.ShortInlineR:
+							{
+								loadedValues.Add (ReadSingle (ilBytes, ref curIndex).ToString ());
+							}
+							break;
 
-					case OperandType.InlineR:
-						{
-							loadedValues.Add (ReadDouble (ilBytes, ref curIndex).ToString ());
-						}
-						break;
+							case OperandType.InlineR:
+							{
+								loadedValues.Add (ReadDouble (ilBytes, ref curIndex).ToString ());
+							}
+							break;
 
-					case OperandType.ShortInlineBrTarget:
-						loadedValues.Clear ();
-						var sbyteValue = ReadSByte (ilBytes, ref curIndex) + curIndex + blockOffset;
-						break;
+							case OperandType.ShortInlineBrTarget:
+							loadedValues.Clear ();
+							var sbyteValue = ReadSByte (ilBytes, ref curIndex) + curIndex + blockOffset;
+							break;
 
-					case OperandType.InlineBrTarget:
-						loadedValues.Clear ();
-						var int32value = ReadInt32 (ilBytes, ref curIndex) + curIndex + blockOffset;
-						break;
+							case OperandType.InlineBrTarget:
+							loadedValues.Clear ();
+							var int32value = ReadInt32 (ilBytes, ref curIndex) + curIndex + blockOffset;
+							break;
 
-					case OperandType.InlineSwitch:
-						loadedValues.Clear ();
-						int labelCount = ReadInt32 (ilBytes, ref curIndex);
-						int instrEnd = curIndex + labelCount * 4;
-						for (int i = 0; i < labelCount; i++) {
-							var int32LabelValue = ReadInt32 (ilBytes, ref curIndex) + instrEnd + blockOffset;
-							//sb.AppendLine((i == labelCount - 1) ? ")" : ",");
+							case OperandType.InlineSwitch:
+							loadedValues.Clear ();
+							int labelCount = ReadInt32 (ilBytes, ref curIndex);
+							int instrEnd = curIndex + labelCount * 4;
+							for (int i = 0; i < labelCount; i++) {
+								var int32LabelValue = ReadInt32 (ilBytes, ref curIndex) + instrEnd + blockOffset;
+								//sb.AppendLine((i == labelCount - 1) ? ")" : ",");
+							}
+							break;
+
+							default:
+							throw new InvalidOperationException ();
+							//throw ExceptionUtilities.UnexpectedValue(opCode.OperandType);
 						}
-						break;
 
-					default:
-						throw new InvalidOperationException ();
-					//throw ExceptionUtilities.UnexpectedValue(opCode.OperandType);
+						//sb.AppendLine();
 					}
 
-					//sb.AppendLine();
+					if (EndsSpan (spans, lastSpanIndex, curIndex + blockOffset)) {
+						break;
+					}
 				}
 
-				if (EndsSpan (spans, lastSpanIndex, curIndex + blockOffset)) {
-					break;
-				}
+				nextSpanIndex = spanIndex;
+				return curIndex;
 			}
 
-			nextSpanIndex = spanIndex;
-			return curIndex;
-		}
-
-		TypeDefinition typeDef;
-		PEReader peFile;
-		MetadataReader metaReader;
+			TypeDefinition typeDef;
+			PEReader peFile;
+			MetadataReader metaReader;
 
-		private static readonly OpCode[] s_oneByteOpCodes;
-		private static readonly OpCode[] s_twoByteOpCodes;
+			private static readonly OpCode[] s_oneByteOpCodes;
+			private static readonly OpCode[] s_twoByteOpCodes;
 
-		static CSComponentInspector ()
-		{
-			s_oneByteOpCodes = new OpCode[0x100];
-			s_twoByteOpCodes = new OpCode[0x100];
+			static CSComponentInspector ()
+			{
+				s_oneByteOpCodes = new OpCode[0x100];
+				s_twoByteOpCodes = new OpCode[0x100];
 
-			var typeOfOpCode = typeof(OpCode);
+				var typeOfOpCode = typeof(OpCode);
 
-			foreach (FieldInfo fi in typeof(OpCodes).GetTypeInfo().DeclaredFields) {
-				if (fi.FieldType != typeOfOpCode) {
-					continue;
-				}
+				foreach (FieldInfo fi in typeof(OpCodes).GetTypeInfo().DeclaredFields) {
+					if (fi.FieldType != typeOfOpCode) {
+						continue;
+					}
 
-				OpCode opCode = (OpCode)fi.GetValue (null);
-				var value = unchecked((ushort)opCode.Value);
-				if (value < 0x100) {
-					s_oneByteOpCodes [value] = opCode;
-				} else if ((value & 0xff00) == 0xfe00) {
-					s_twoByteOpCodes [value & 0xff] = opCode;
+					OpCode opCode = (OpCode)fi.GetValue (null);
+					var value = unchecked((ushort)opCode.Value);
+					if (value < 0x100) {
+						s_oneByteOpCodes [value] = opCode;
+					} else if ((value & 0xff00) == 0xfe00) {
+						s_twoByteOpCodes [value & 0xff] = opCode;
+					}
 				}
 			}
-		}
 
-		private static ulong ReadUInt64 (ImmutableArray<byte> buffer, ref int pos)
-		{
-			ulong result =
+			private static ulong ReadUInt64 (ImmutableArray<byte> buffer, ref int pos)
+			{
+				ulong result =
 				buffer [pos] |
 				(ulong)buffer [pos + 1] << 8 |
 				(ulong)buffer [pos + 2] << 16 |
@@ -592,216 +570,238 @@ namespace AtomicEditor
 				(ulong)buffer [pos + 6] << 48 |
 				(ulong)buffer [pos + 7] << 56;
 
-			pos += sizeof(ulong);
-			return result;
-		}
-
-		private static uint ReadUInt32 (ImmutableArray<byte> buffer, ref int pos)
-		{
-			uint result = buffer [pos] | (uint)buffer [pos + 1] << 8 | (uint)buffer [pos + 2] << 16 | (uint)buffer [pos + 3] << 24;
-			pos += sizeof(uint);
-			return result;
-		}
-
-		private static int ReadInt32 (ImmutableArray<byte> buffer, ref int pos)
-		{
-			return unchecked((int)ReadUInt32 (buffer, ref pos));
-		}
+				pos += sizeof(ulong);
+				return result;
+			}
 
-		private static ushort ReadUInt16 (ImmutableArray<byte> buffer, ref int pos)
-		{
-			ushort result = (ushort)(buffer [pos] | buffer [pos + 1] << 8);
-			pos += sizeof(ushort);
-			return result;
-		}
+			private static uint ReadUInt32 (ImmutableArray<byte> buffer, ref int pos)
+			{
+				uint result = buffer [pos] | (uint)buffer [pos + 1] << 8 | (uint)buffer [pos + 2] << 16 | (uint)buffer [pos + 3] << 24;
+				pos += sizeof(uint);
+				return result;
+			}
 
-		private static byte ReadByte (ImmutableArray<byte> buffer, ref int pos)
-		{
-			byte result = buffer [pos];
-			pos += sizeof(byte);
-			return result;
-		}
+			private static int ReadInt32 (ImmutableArray<byte> buffer, ref int pos)
+			{
+				return unchecked((int)ReadUInt32 (buffer, ref pos));
+			}
 
-		private static sbyte ReadSByte (ImmutableArray<byte> buffer, ref int pos)
-		{
-			sbyte result = unchecked((sbyte)buffer [pos]);
-			pos += 1;
-			return result;
-		}
+			private static ushort ReadUInt16 (ImmutableArray<byte> buffer, ref int pos)
+			{
+				ushort result = (ushort)(buffer [pos] | buffer [pos + 1] << 8);
+				pos += sizeof(ushort);
+				return result;
+			}
 
-		private unsafe static float ReadSingle (ImmutableArray<byte> buffer, ref int pos)
-		{
-			uint value = ReadUInt32 (buffer, ref pos);
-			return *(float*)&value;
-		}
+			private static byte ReadByte (ImmutableArray<byte> buffer, ref int pos)
+			{
+				byte result = buffer [pos];
+				pos += sizeof(byte);
+				return result;
+			}
 
-		private unsafe static double ReadDouble (ImmutableArray<byte> buffer, ref int pos)
-		{
-			ulong value = ReadUInt64 (buffer, ref pos);
-			return *(double*)&value;
-		}
+			private static sbyte ReadSByte (ImmutableArray<byte> buffer, ref int pos)
+			{
+				sbyte result = unchecked((sbyte)buffer [pos]);
+				pos += 1;
+				return result;
+			}
 
-		public enum HandlerKind
-		{
-			Try,
-			Catch,
-			Filter,
-			Finally,
-			Fault
-		}
+			private unsafe static float ReadSingle (ImmutableArray<byte> buffer, ref int pos)
+			{
+				uint value = ReadUInt32 (buffer, ref pos);
+				return *(float*)&value;
+			}
 
-		public struct HandlerSpan : IComparable<HandlerSpan>
-		{
-			public readonly HandlerKind Kind;
-			public readonly object ExceptionType;
-			public readonly int StartOffset;
-			public readonly int FilterHandlerStart;
-			public readonly int EndOffset;
+			private unsafe static double ReadDouble (ImmutableArray<byte> buffer, ref int pos)
+			{
+				ulong value = ReadUInt64 (buffer, ref pos);
+				return *(double*)&value;
+			}
 
-			public HandlerSpan (HandlerKind kind, object exceptionType, int startOffset, int endOffset, int filterHandlerStart = 0)
+			public enum HandlerKind
 			{
-				this.Kind = kind;
-				this.ExceptionType = exceptionType;
-				this.StartOffset = startOffset;
-				this.EndOffset = endOffset;
-				this.FilterHandlerStart = filterHandlerStart;
+				Try,
+				Catch,
+				Filter,
+				Finally,
+				Fault
 			}
 
-			public int CompareTo (HandlerSpan other)
+			public struct HandlerSpan : IComparable<HandlerSpan>
 			{
-				int result = this.StartOffset - other.StartOffset;
-				if (result == 0) {
-					// Both blocks have same start. Order larger (outer) before smaller (inner).
-					result = other.EndOffset - this.EndOffset;
+				public readonly HandlerKind Kind;
+				public readonly object ExceptionType;
+				public readonly int StartOffset;
+				public readonly int FilterHandlerStart;
+				public readonly int EndOffset;
+
+				public HandlerSpan (HandlerKind kind, object exceptionType, int startOffset, int endOffset, int filterHandlerStart = 0)
+				{
+					this.Kind = kind;
+					this.ExceptionType = exceptionType;
+					this.StartOffset = startOffset;
+					this.EndOffset = endOffset;
+					this.FilterHandlerStart = filterHandlerStart;
 				}
 
-				return result;
+				public int CompareTo (HandlerSpan other)
+				{
+					int result = this.StartOffset - other.StartOffset;
+					if (result == 0) {
+						// Both blocks have same start. Order larger (outer) before smaller (inner).
+						result = other.EndOffset - this.EndOffset;
+					}
+
+					return result;
+				}
+
+				public string ToString (CSComponentInspector visualizer)
+				{
+					switch (this.Kind) {
+						default:
+						return ".try";
+						case HandlerKind.Catch:
+						return "catch **exceptiontype**";// + visualizer.VisualizeLocalType(this.ExceptionType);
+						case HandlerKind.Filter:
+						return "filter";
+						case HandlerKind.Finally:
+						return "finally";
+						case HandlerKind.Fault:
+						return "fault";
+					}
+				}
+
+				public override string ToString ()
+				{
+					throw new NotSupportedException ("Use ToString(CSComponentInspector)");
+				}
 			}
 
-			public string ToString (CSComponentInspector visualizer)
+			private static bool StartsSpan (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
 			{
-				switch (this.Kind) {
-				default:
-					return ".try";
-				case HandlerKind.Catch:
-					return "catch **exceptiontype**";// + visualizer.VisualizeLocalType(this.ExceptionType);
-				case HandlerKind.Filter:
-					return "filter";
-				case HandlerKind.Finally:
-					return "finally";
-				case HandlerKind.Fault:
-					return "fault";
-				}
+				return spans != null && spanIndex < spans.Count && spans [spanIndex].StartOffset == (uint)curIndex;
 			}
 
-			public override string ToString ()
+			private static bool EndsSpan (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
 			{
-				throw new NotSupportedException ("Use ToString(CSComponentInspector)");
+				return spans != null && spanIndex >= 0 && spans [spanIndex].EndOffset == (uint)curIndex;
 			}
-		}
 
-		private static bool StartsSpan (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-		{
-			return spans != null && spanIndex < spans.Count && spans [spanIndex].StartOffset == (uint)curIndex;
-		}
+			private static bool StartsFilterHandler (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
+			{
+				return spans != null &&
+				spanIndex < spans.Count &&
+				spans [spanIndex].Kind == HandlerKind.Filter &&
+				spans [spanIndex].FilterHandlerStart == (uint)curIndex;
+			}
 
-		private static bool EndsSpan (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-		{
-			return spans != null && spanIndex >= 0 && spans [spanIndex].EndOffset == (uint)curIndex;
-		}
+			public static IReadOnlyList<HandlerSpan> GetHandlerSpans (ImmutableArray<ExceptionRegion> entries)
+			{
+				if (entries.Length == 0) {
+					return new HandlerSpan[0];
+				}
 
-		private static bool StartsFilterHandler (IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-		{
-			return spans != null &&
-			spanIndex < spans.Count &&
-			spans [spanIndex].Kind == HandlerKind.Filter &&
-			spans [spanIndex].FilterHandlerStart == (uint)curIndex;
-		}
+				var result = new List<HandlerSpan> ();
+				foreach (ExceptionRegion entry in entries) {
+					int tryStartOffset = entry.TryOffset;
+					int tryEndOffset = entry.TryOffset + entry.TryLength;
+					var span = new HandlerSpan (HandlerKind.Try, null, tryStartOffset, tryEndOffset);
 
-		public static IReadOnlyList<HandlerSpan> GetHandlerSpans (ImmutableArray<ExceptionRegion> entries)
-		{
-			if (entries.Length == 0) {
-				return new HandlerSpan[0];
-			}
+					if (result.Count == 0 || span.CompareTo (result [result.Count - 1]) != 0) {
+						result.Add (span);
+					}
+				}
+
+				foreach (ExceptionRegion entry in entries) {
+					int handlerStartOffset = entry.HandlerOffset;
+					int handlerEndOffset = entry.HandlerOffset + entry.HandlerLength;
+
+					HandlerSpan span;
+					switch (entry.Kind) {
+						case ExceptionRegionKind.Catch:
+						span = new HandlerSpan (HandlerKind.Catch, MetadataTokens.GetToken (entry.CatchType), handlerStartOffset, handlerEndOffset);
+						break;
+
+						case ExceptionRegionKind.Fault:
+						span = new HandlerSpan (HandlerKind.Fault, null, handlerStartOffset, handlerEndOffset);
+						break;
 
-			var result = new List<HandlerSpan> ();
-			foreach (ExceptionRegion entry in entries) {
-				int tryStartOffset = entry.TryOffset;
-				int tryEndOffset = entry.TryOffset + entry.TryLength;
-				var span = new HandlerSpan (HandlerKind.Try, null, tryStartOffset, tryEndOffset);
+						case ExceptionRegionKind.Filter:
+						span = new HandlerSpan (HandlerKind.Filter, null, handlerStartOffset, handlerEndOffset, entry.FilterOffset);
+						break;
+
+						case ExceptionRegionKind.Finally:
+						span = new HandlerSpan (HandlerKind.Finally, null, handlerStartOffset, handlerEndOffset);
+						break;
+
+						default:
+						throw new InvalidOperationException ();
+					}
 
-				if (result.Count == 0 || span.CompareTo (result [result.Count - 1]) != 0) {
 					result.Add (span);
 				}
-			}
-
-			foreach (ExceptionRegion entry in entries) {
-				int handlerStartOffset = entry.HandlerOffset;
-				int handlerEndOffset = entry.HandlerOffset + entry.HandlerLength;
 
-				HandlerSpan span;
-				switch (entry.Kind) {
-				case ExceptionRegionKind.Catch:
-					span = new HandlerSpan (HandlerKind.Catch, MetadataTokens.GetToken (entry.CatchType), handlerStartOffset, handlerEndOffset);
-					break;
+				return result;
+			}
 
-				case ExceptionRegionKind.Fault:
-					span = new HandlerSpan (HandlerKind.Fault, null, handlerStartOffset, handlerEndOffset);
-					break;
+			public void Dump ()
+			{
+				/*
+				foreach (var entry in InspectorFields) {
+					var field = entry.Value;
 
-				case ExceptionRegionKind.Filter:
-					span = new HandlerSpan (HandlerKind.Filter, null, handlerStartOffset, handlerEndOffset, entry.FilterOffset);
-					break;
+					Console.WriteLine ("Inspector Field: {0}", field.Name);
 
-				case ExceptionRegionKind.Finally:
-					span = new HandlerSpan (HandlerKind.Finally, null, handlerStartOffset, handlerEndOffset);
-					break;
+					Console.WriteLine ("   Type Name: {0}", field.TypeName);
+					Console.WriteLine ("   Default Value: {0}", field.DefaultValue);
 
-				default:
-					throw new InvalidOperationException ();
+					Console.WriteLine ("   Positional Custom Attr:");
+					foreach (var p in field.CustomAttrPositionalArgs)
+					if (p.Length != 0)
+					Console.WriteLine ("      {0}", p);
+					Console.WriteLine ("   Named Custom Attr:");
+					foreach (var nentry in field.CustomAttrNamedArgs)
+					Console.WriteLine ("      {0}:{1}", nentry.Key, nentry.Value);
 				}
-
-				result.Add (span);
+				*/
 			}
 
-			return result;
 		}
 
-	}
-
-	internal static class TokenTypeIds
-	{
-		internal const uint Module = 0x00000000;
-		internal const uint TypeRef = 0x01000000;
-		internal const uint TypeDef = 0x02000000;
-		internal const uint FieldDef = 0x04000000;
-		internal const uint MethodDef = 0x06000000;
-		internal const uint ParamDef = 0x08000000;
-		internal const uint InterfaceImpl = 0x09000000;
-		internal const uint MemberRef = 0x0a000000;
-		internal const uint CustomAttribute = 0x0c000000;
-		internal const uint Permission = 0x0e000000;
-		internal const uint Signature = 0x11000000;
-		internal const uint Event = 0x14000000;
-		internal const uint Property = 0x17000000;
-		internal const uint ModuleRef = 0x1a000000;
-		internal const uint TypeSpec = 0x1b000000;
-		internal const uint Assembly = 0x20000000;
-		internal const uint AssemblyRef = 0x23000000;
-		internal const uint File = 0x26000000;
-		internal const uint ExportedType = 0x27000000;
-		internal const uint ManifestResource = 0x28000000;
-		internal const uint GenericParam = 0x2a000000;
-		internal const uint MethodSpec = 0x2b000000;
-		internal const uint GenericParamConstraint = 0x2c000000;
-		internal const uint String = 0x70000000;
-		internal const uint Name = 0x71000000;
-		internal const uint BaseType = 0x72000000;
-		// Leave this on the high end value. This does not correspond to metadata table???
-
-		internal const uint RIDMask = 0x00FFFFFF;
-		internal const uint TokenTypeMask = 0xFF000000;
-	}
+		internal static class TokenTypeIds
+		{
+			internal const uint Module = 0x00000000;
+			internal const uint TypeRef = 0x01000000;
+			internal const uint TypeDef = 0x02000000;
+			internal const uint FieldDef = 0x04000000;
+			internal const uint MethodDef = 0x06000000;
+			internal const uint ParamDef = 0x08000000;
+			internal const uint InterfaceImpl = 0x09000000;
+			internal const uint MemberRef = 0x0a000000;
+			internal const uint CustomAttribute = 0x0c000000;
+			internal const uint Permission = 0x0e000000;
+			internal const uint Signature = 0x11000000;
+			internal const uint Event = 0x14000000;
+			internal const uint Property = 0x17000000;
+			internal const uint ModuleRef = 0x1a000000;
+			internal const uint TypeSpec = 0x1b000000;
+			internal const uint Assembly = 0x20000000;
+			internal const uint AssemblyRef = 0x23000000;
+			internal const uint File = 0x26000000;
+			internal const uint ExportedType = 0x27000000;
+			internal const uint ManifestResource = 0x28000000;
+			internal const uint GenericParam = 0x2a000000;
+			internal const uint MethodSpec = 0x2b000000;
+			internal const uint GenericParamConstraint = 0x2c000000;
+			internal const uint String = 0x70000000;
+			internal const uint Name = 0x71000000;
+			internal const uint BaseType = 0x72000000;
+			// Leave this on the high end value. This does not correspond to metadata table???
+
+			internal const uint RIDMask = 0x00FFFFFF;
+			internal const uint TokenTypeMask = 0xFF000000;
+		}
 
 
-}
+	}

+ 0 - 644
Build/AtomicNETTest/AtomicEditor/CSComponentInspectorOld.cs

@@ -1,644 +0,0 @@
-// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
-
-#if nope
-
-using System.Collections.Immutable;
-//using Roslyn.Utilities;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Text;
-using System.Reflection.Emit;
-using System.Reflection;
-using System.Reflection.Metadata;
-using System.Reflection.Metadata.Ecma335;
-
-namespace AtomicEditor
-{
-  public class CSComponentInspector
-  {
-      private static readonly OpCode[] s_oneByteOpCodes;
-      private static readonly OpCode[] s_twoByteOpCodes;
-
-      public static readonly CSComponentInspector Instance = new CSComponentInspector();
-
-      static CSComponentInspector()
-      {
-          s_oneByteOpCodes = new OpCode[0x100];
-          s_twoByteOpCodes = new OpCode[0x100];
-
-          var typeOfOpCode = typeof(OpCode);
-
-          foreach (FieldInfo fi in typeof(OpCodes).GetTypeInfo().DeclaredFields)
-          {
-              if (fi.FieldType != typeOfOpCode)
-              {
-                  continue;
-              }
-
-              OpCode opCode = (OpCode)fi.GetValue(null);
-              var value = unchecked((ushort)opCode.Value);
-              if (value < 0x100)
-              {
-                  s_oneByteOpCodes[value] = opCode;
-              }
-              else if ((value & 0xff00) == 0xfe00)
-              {
-                  s_twoByteOpCodes[value & 0xff] = opCode;
-              }
-          }
-      }
-
-      public enum HandlerKind
-      {
-          Try,
-          Catch,
-          Filter,
-          Finally,
-          Fault
-      }
-
-      public struct HandlerSpan : IComparable<HandlerSpan>
-      {
-          public readonly HandlerKind Kind;
-          public readonly object ExceptionType;
-          public readonly int StartOffset;
-          public readonly int FilterHandlerStart;
-          public readonly int EndOffset;
-
-          public HandlerSpan(HandlerKind kind, object exceptionType, int startOffset, int endOffset, int filterHandlerStart = 0)
-          {
-              this.Kind = kind;
-              this.ExceptionType = exceptionType;
-              this.StartOffset = startOffset;
-              this.EndOffset = endOffset;
-              this.FilterHandlerStart = filterHandlerStart;
-          }
-
-          public int CompareTo(HandlerSpan other)
-          {
-              int result = this.StartOffset - other.StartOffset;
-              if (result == 0)
-              {
-                  // Both blocks have same start. Order larger (outer) before smaller (inner).
-                  result = other.EndOffset - this.EndOffset;
-              }
-
-              return result;
-          }
-
-          public string ToString(CSComponentInspector visualizer)
-          {
-              switch (this.Kind)
-              {
-                  default:
-                      return ".try";
-                  case HandlerKind.Catch:
-                      return "catch " + visualizer.VisualizeLocalType(this.ExceptionType);
-                  case HandlerKind.Filter:
-                      return "filter";
-                  case HandlerKind.Finally:
-                      return "finally";
-                  case HandlerKind.Fault:
-                      return "fault";
-              }
-          }
-
-          public override string ToString()
-          {
-              throw new NotSupportedException("Use ToString(CSComponentInspector)");
-          }
-      }
-
-      public struct LocalInfo
-      {
-          public readonly string Name;
-          public readonly bool IsPinned;
-          public readonly bool IsByRef;
-          public readonly object Type; // ITypeReference or ITypeSymbol
-
-          public LocalInfo(string name, object type, bool isPinned, bool isByRef)
-          {
-              Name = name;
-              Type = type;
-              IsPinned = isPinned;
-              IsByRef = isByRef;
-          }
-      }
-
-      public const string IndentString = "  ";
-
-      public string VisualizeUserString(uint token)
-      {
-        return "";
-
-      }
-
-      public string VisualizeSymbol(uint token)
-      {
-        return "";
-      }
-
-      public string VisualizeLocalType(object type)
-      {
-        return "";
-      }
-
-      private static ulong ReadUInt64(ImmutableArray<byte> buffer, ref int pos)
-      {
-          ulong result =
-              buffer[pos] |
-              (ulong)buffer[pos + 1] << 8 |
-              (ulong)buffer[pos + 2] << 16 |
-              (ulong)buffer[pos + 3] << 24 |
-              (ulong)buffer[pos + 4] << 32 |
-              (ulong)buffer[pos + 5] << 40 |
-              (ulong)buffer[pos + 6] << 48 |
-              (ulong)buffer[pos + 7] << 56;
-
-          pos += sizeof(ulong);
-          return result;
-      }
-
-      private static uint ReadUInt32(ImmutableArray<byte> buffer, ref int pos)
-      {
-          uint result = buffer[pos] | (uint)buffer[pos + 1] << 8 | (uint)buffer[pos + 2] << 16 | (uint)buffer[pos + 3] << 24;
-          pos += sizeof(uint);
-          return result;
-      }
-
-      private static int ReadInt32(ImmutableArray<byte> buffer, ref int pos)
-      {
-          return unchecked((int)ReadUInt32(buffer, ref pos));
-      }
-
-      private static ushort ReadUInt16(ImmutableArray<byte> buffer, ref int pos)
-      {
-          ushort result = (ushort)(buffer[pos]| buffer[pos + 1] << 8);
-          pos += sizeof(ushort);
-          return result;
-      }
-
-      private static byte ReadByte(ImmutableArray<byte> buffer, ref int pos)
-      {
-          byte result = buffer[pos];
-          pos += sizeof(byte);
-          return result;
-      }
-
-      private static sbyte ReadSByte(ImmutableArray<byte> buffer, ref int pos)
-      {
-          sbyte result = unchecked((sbyte)buffer[pos]);
-          pos += 1;
-          return result;
-      }
-
-      private unsafe static float ReadSingle(ImmutableArray<byte> buffer, ref int pos)
-      {
-          uint value = ReadUInt32(buffer, ref pos);
-          return *(float*)&value;
-      }
-
-      private unsafe static double ReadDouble(ImmutableArray<byte> buffer, ref int pos)
-      {
-          ulong value = ReadUInt64(buffer, ref pos);
-          return *(double*)&value;
-      }
-
-      public void VisualizeHeader(StringBuilder sb, int codeSize, int maxStack, ImmutableArray<LocalInfo> locals)
-      {
-          if (codeSize >= 0 && maxStack >= 0)
-          {
-              if (codeSize == 0)
-              {
-                  sb.AppendLine("  // Unrealized IL");
-              }
-              else
-              {
-                  sb.AppendLine(string.Format("  // Code size {0,8} (0x{0:x})", codeSize));
-              }
-
-              sb.AppendLine(string.Format("  .maxstack  {0}", maxStack));
-          }
-
-          int i = 0;
-          foreach (var local in locals)
-          {
-              sb.Append(i == 0 ? "  .locals init (" : new string(' ', "  .locals init (".Length));
-              if (local.IsPinned)
-              {
-                  sb.Append("pinned ");
-              }
-
-              sb.Append(VisualizeLocalType(local.Type));
-              if (local.IsByRef)
-              {
-                  sb.Append("&");
-              }
-
-              sb.Append(" ");
-              sb.Append("V_" + i);
-
-              sb.Append(i == locals.Length - 1 ? ")" : ",");
-
-              var name = local.Name;
-              if (name != null)
-              {
-                  sb.Append(" //");
-                  sb.Append(name);
-              }
-
-              sb.AppendLine();
-
-              i++;
-          }
-      }
-
-      public string DumpMethod(
-          MetadataReader reader,
-          TypeDefinition typeDef,
-          int maxStack,
-          ImmutableArray<byte> ilBytes,
-          ImmutableArray<LocalInfo> locals,
-          IReadOnlyList<HandlerSpan> exceptionHandlers,
-          IReadOnlyDictionary<int, string> markers = null)
-      {
-          var builder = new StringBuilder();
-          this.DumpMethod(reader, typeDef, builder, maxStack, ilBytes, locals, exceptionHandlers, markers);
-          return builder.ToString();
-      }
-
-      public void DumpMethod(
-          MetadataReader reader,
-          TypeDefinition typeDef,
-          StringBuilder sb,
-          int maxStack,
-          ImmutableArray<byte> ilBytes,
-          ImmutableArray<LocalInfo> locals,
-          IReadOnlyList<HandlerSpan> exceptionHandlers,
-          IReadOnlyDictionary<int, string> markers = null)
-      {
-          sb.AppendLine("{");
-
-          VisualizeHeader(sb, ilBytes.Length, maxStack, locals);
-          DumpILBlock(reader, typeDef, ilBytes, ilBytes.Length, sb, exceptionHandlers, 0, markers);
-
-          sb.AppendLine("}");
-      }
-
-      /// <summary>
-      /// Dumps all instructions in the stream into provided string builder.
-      /// The blockOffset specifies the relative position of the block within method body (if known).
-      /// </summary>
-      public void DumpILBlock(
-          MetadataReader reader,
-          TypeDefinition typeDef,
-          ImmutableArray<byte> ilBytes,
-          int length,
-          StringBuilder sb,
-          IReadOnlyList<HandlerSpan> spans = null,
-          int blockOffset = 0,
-          IReadOnlyDictionary<int, string> markers = null)
-      {
-          if (ilBytes == null)
-          {
-              return;
-          }
-
-          int spanIndex = 0;
-          int curIndex = DumpILBlock(reader, typeDef, ilBytes, length, sb, spans, blockOffset, 0, spanIndex, IndentString, markers, out spanIndex);
-      }
-
-      private int DumpILBlock(
-          MetadataReader reader,
-          TypeDefinition typeDef,
-          ImmutableArray<byte> ilBytes,
-          int length,
-          StringBuilder sb,
-          IReadOnlyList<HandlerSpan> spans,
-          int blockOffset,
-          int curIndex,
-          int spanIndex,
-          string indent,
-          IReadOnlyDictionary<int, string> markers,
-          out int nextSpanIndex)
-      {
-          int lastSpanIndex = spanIndex - 1;
-
-          while (curIndex < length)
-          {
-              if (lastSpanIndex > 0 && StartsFilterHandler(spans, lastSpanIndex, curIndex + blockOffset))
-              {
-                  sb.Append(indent.Substring(0, indent.Length - IndentString.Length));
-                  sb.Append("}  // end filter");
-                  sb.AppendLine();
-
-                  sb.Append(indent.Substring(0, indent.Length - IndentString.Length));
-                  sb.Append("{  // handler");
-                  sb.AppendLine();
-              }
-
-              if (StartsSpan(spans, spanIndex, curIndex + blockOffset))
-              {
-                  sb.Append(indent);
-                  sb.Append(spans[spanIndex].ToString(this));
-                  sb.AppendLine();
-                  sb.Append(indent);
-                  sb.Append("{");
-                  sb.AppendLine();
-
-                  curIndex = DumpILBlock(reader, typeDef, ilBytes, length, sb, spans, blockOffset, curIndex, spanIndex + 1, indent + IndentString, markers, out spanIndex);
-
-                  sb.Append(indent);
-                  sb.Append("}");
-                  sb.AppendLine();
-              }
-              else
-              {
-                  int ilOffset = curIndex + blockOffset;
-                  string marker;
-                  if (markers != null && markers.TryGetValue(ilOffset, out marker))
-                  {
-                      sb.Append(indent.Substring(0, indent.Length - marker.Length));
-                      sb.Append(marker);
-                  }
-                  else
-                  {
-                      sb.Append(indent);
-                  }
-
-                  sb.AppendFormat("IL_{0:x4}:", ilOffset);
-
-                  OpCode opCode;
-                  int expectedSize;
-
-                  byte op1 = ilBytes[curIndex++];
-                  if (op1 == 0xfe && curIndex < length)
-                  {
-                      byte op2 = ilBytes[curIndex++];
-                      opCode = s_twoByteOpCodes[op2];
-                      expectedSize = 2;
-                  }
-                  else
-                  {
-                      opCode = s_oneByteOpCodes[op1];
-                      expectedSize = 1;
-                  }
-
-                  if (opCode.Size != expectedSize)
-                  {
-                      sb.AppendLine(string.Format("  <unknown 0x{0}{1:X2}>", expectedSize == 2 ? "fe" : "", op1));
-                      continue;
-                  }
-
-                  sb.Append("  ");
-                  sb.AppendFormat(opCode.OperandType == OperandType.InlineNone ? "{0}" : "{0,-10}", opCode);
-
-                  switch (opCode.OperandType)
-                  {
-                      case OperandType.InlineField:
-
-                          // read token
-                          uint fieldToken = ReadUInt32(ilBytes, ref curIndex);
-                          // get the kind
-                          uint tokenKind = fieldToken & TokenTypeIds.TokenTypeMask;
-                          // and the rowId
-                          uint rowId = fieldToken & TokenTypeIds.RIDMask;
-
-                          var fieldHandle = MetadataTokens.FieldDefinitionHandle( (int) rowId);
-
-                          var fieldDef = reader.GetFieldDefinition(fieldHandle);
-
-         								  sb.AppendFormat("{0}", reader.GetString(fieldDef.Name));
-
-
-                          break;
-                      case OperandType.InlineMethod:
-                      case OperandType.InlineTok:
-                      case OperandType.InlineType:
-                          sb.Append(VisualizeSymbol(ReadUInt32(ilBytes, ref curIndex)));
-                          break;
-
-                      case OperandType.InlineSig: // signature (calli), not emitted by C#/VB
-                          sb.AppendFormat(" 387 0x{0:x}", ReadUInt32(ilBytes, ref curIndex));
-                          break;
-
-                      case OperandType.InlineString:
-                          //sb.Append(" 391 ");
-                          //sb.Append(VisualizeUserString());
-
-                          uint stringToken = ReadUInt32(ilBytes, ref curIndex);
-
-                          // get the kind
-                          //uint tokenKind = stringToken & TokenTypeIds.TokenTypeMask;
-                          // and the rowId
-                          //uint rowId = stringToken & TokenTypeIds.RIDMask;
-
-
-                          UserStringHandle handle = MetadataTokens.UserStringHandle((int)stringToken);
-
-                          sb.AppendFormat("\"{0}\"", reader.GetUserString(handle));
-
-
-                          break;
-
-                      case OperandType.InlineNone:
-                          // ldc.i4.1 // load 1 for instance
-                          //sb.AppendFormat(" InlineNone");
-                          break;
-
-                      case OperandType.ShortInlineI:
-                          sb.AppendFormat(" 399 {0}", ReadSByte(ilBytes, ref curIndex));
-                          break;
-
-                      case OperandType.ShortInlineVar:
-                          sb.AppendFormat(" 403 V_{0}", ReadByte(ilBytes, ref curIndex));
-                          break;
-
-                      case OperandType.InlineVar:
-                          sb.AppendFormat(" 407 V_{0}", ReadUInt16(ilBytes, ref curIndex));
-                          break;
-
-                      case OperandType.InlineI:
-                          sb.AppendFormat(" 411 0x{0:x}", ReadUInt32(ilBytes, ref curIndex));
-                          break;
-
-                      case OperandType.InlineI8:
-                          sb.AppendFormat(" 415 0x{0:x8}", ReadUInt64(ilBytes, ref curIndex));
-                          break;
-
-                      case OperandType.ShortInlineR:
-                          {
-                              var value = ReadSingle(ilBytes, ref curIndex);
-                              if (value == 0 && 1 / value < 0)
-                              {
-                                  sb.Append(" 423 -0.0");
-                              }
-                              else
-                              {
-                                  sb.AppendFormat("477 {0}", value.ToString(CultureInfo.InvariantCulture));
-                              }
-                          }
-                          break;
-
-                      case OperandType.InlineR:
-                          {
-                              var value = ReadDouble(ilBytes, ref curIndex);
-                              if (value == 0 && 1 / value < 0)
-                              {
-                                  sb.Append("437 -0.0");
-                              }
-                              else
-                              {
-                                  sb.AppendFormat("441 {0}", value.ToString(CultureInfo.InvariantCulture));
-                              }
-                          }
-                          break;
-
-                      case OperandType.ShortInlineBrTarget:
-                          sb.AppendFormat(" 447 IL_{0:x4}", ReadSByte(ilBytes, ref curIndex) + curIndex + blockOffset);
-                          break;
-
-                      case OperandType.InlineBrTarget:
-                          sb.AppendFormat(" 451 IL_{0:x4}", ReadInt32(ilBytes, ref curIndex) + curIndex + blockOffset);
-                          break;
-
-                      case OperandType.InlineSwitch:
-                          int labelCount = ReadInt32(ilBytes, ref curIndex);
-                          int instrEnd = curIndex + labelCount * 4;
-                          sb.AppendLine("(");
-                          for (int i = 0; i < labelCount; i++)
-                          {
-                              sb.AppendFormat("        IL_{0:x4}", ReadInt32(ilBytes, ref curIndex) + instrEnd + blockOffset);
-                              sb.AppendLine((i == labelCount - 1) ? ")" : ",");
-                          }
-                          break;
-
-                      default:
-                          throw new InvalidOperationException();
-                          //throw ExceptionUtilities.UnexpectedValue(opCode.OperandType);
-                  }
-
-                  sb.AppendLine();
-              }
-
-              if (EndsSpan(spans, lastSpanIndex, curIndex + blockOffset))
-              {
-                  break;
-              }
-          }
-
-          nextSpanIndex = spanIndex;
-          return curIndex;
-      }
-
-      private static bool StartsSpan(IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-      {
-          return spans != null && spanIndex < spans.Count && spans[spanIndex].StartOffset == (uint)curIndex;
-      }
-
-      private static bool EndsSpan(IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-      {
-          return spans != null && spanIndex >= 0 && spans[spanIndex].EndOffset == (uint)curIndex;
-      }
-
-      private static bool StartsFilterHandler(IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-      {
-          return spans != null &&
-              spanIndex < spans.Count &&
-              spans[spanIndex].Kind == HandlerKind.Filter &&
-              spans[spanIndex].FilterHandlerStart == (uint)curIndex;
-      }
-
-      public static IReadOnlyList<HandlerSpan> GetHandlerSpans(ImmutableArray<ExceptionRegion> entries)
-      {
-          if (entries.Length == 0)
-          {
-              return new HandlerSpan[0];
-          }
-
-          var result = new List<HandlerSpan>();
-          foreach (ExceptionRegion entry in entries)
-          {
-              int tryStartOffset = entry.TryOffset;
-              int tryEndOffset = entry.TryOffset + entry.TryLength;
-              var span = new HandlerSpan(HandlerKind.Try, null, tryStartOffset, tryEndOffset);
-
-              if (result.Count == 0 || span.CompareTo(result[result.Count - 1]) != 0)
-              {
-                  result.Add(span);
-              }
-          }
-
-          foreach (ExceptionRegion entry in entries)
-          {
-              int handlerStartOffset = entry.HandlerOffset;
-              int handlerEndOffset = entry.HandlerOffset + entry.HandlerLength;
-
-              HandlerSpan span;
-              switch (entry.Kind)
-              {
-                  case ExceptionRegionKind.Catch:
-                      span = new HandlerSpan(HandlerKind.Catch, MetadataTokens.GetToken(entry.CatchType), handlerStartOffset, handlerEndOffset);
-                      break;
-
-                  case ExceptionRegionKind.Fault:
-                      span = new HandlerSpan(HandlerKind.Fault, null, handlerStartOffset, handlerEndOffset);
-                      break;
-
-                  case ExceptionRegionKind.Filter:
-                      span = new HandlerSpan(HandlerKind.Filter, null, handlerStartOffset, handlerEndOffset, entry.FilterOffset);
-                      break;
-
-                  case ExceptionRegionKind.Finally:
-                      span = new HandlerSpan(HandlerKind.Finally, null, handlerStartOffset, handlerEndOffset);
-                      break;
-
-                  default:
-                      throw new InvalidOperationException();
-              }
-
-              result.Add(span);
-          }
-
-          return result;
-      }
-  }
-
-  internal static class TokenTypeIds {
-      internal const uint Module = 0x00000000;
-      internal const uint TypeRef = 0x01000000;
-      internal const uint TypeDef = 0x02000000;
-      internal const uint FieldDef = 0x04000000;
-      internal const uint MethodDef = 0x06000000;
-      internal const uint ParamDef = 0x08000000;
-      internal const uint InterfaceImpl = 0x09000000;
-      internal const uint MemberRef = 0x0a000000;
-      internal const uint CustomAttribute = 0x0c000000;
-      internal const uint Permission = 0x0e000000;
-      internal const uint Signature = 0x11000000;
-      internal const uint Event = 0x14000000;
-      internal const uint Property = 0x17000000;
-      internal const uint ModuleRef = 0x1a000000;
-      internal const uint TypeSpec = 0x1b000000;
-      internal const uint Assembly = 0x20000000;
-      internal const uint AssemblyRef = 0x23000000;
-      internal const uint File = 0x26000000;
-      internal const uint ExportedType = 0x27000000;
-      internal const uint ManifestResource = 0x28000000;
-      internal const uint GenericParam = 0x2a000000;
-      internal const uint MethodSpec = 0x2b000000;
-      internal const uint GenericParamConstraint = 0x2c000000;
-      internal const uint String = 0x70000000;
-      internal const uint Name = 0x71000000;
-      internal const uint BaseType = 0x72000000;       // Leave this on the high end value. This does not correspond to metadata table???
-
-      internal const uint RIDMask = 0x00FFFFFF;
-      internal const uint TokenTypeMask = 0xFF000000;
-    }
-
-
-}
-
-#endif

+ 0 - 555
Build/AtomicNETTest/AtomicEditor/ILVisualizer.cs

@@ -1,555 +0,0 @@
-// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
-
-using System.Collections.Immutable;
-//using Roslyn.Utilities;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.Text;
-using System.Reflection.Emit;
-using System.Reflection;
-using System.Reflection.Metadata;
-using System.Reflection.Metadata.Ecma335;
-
-namespace AtomicEditor
-{
-    public abstract class ILVisualizer
-    {
-        private static readonly OpCode[] s_oneByteOpCodes;
-        private static readonly OpCode[] s_twoByteOpCodes;
-
-        static ILVisualizer()
-        {
-            s_oneByteOpCodes = new OpCode[0x100];
-            s_twoByteOpCodes = new OpCode[0x100];
-
-            var typeOfOpCode = typeof(OpCode);
-
-            foreach (FieldInfo fi in typeof(OpCodes).GetTypeInfo().DeclaredFields)
-            {
-                if (fi.FieldType != typeOfOpCode)
-                {
-                    continue;
-                }
-
-                OpCode opCode = (OpCode)fi.GetValue(null);
-                var value = unchecked((ushort)opCode.Value);
-                if (value < 0x100)
-                {
-                    s_oneByteOpCodes[value] = opCode;
-                }
-                else if ((value & 0xff00) == 0xfe00)
-                {
-                    s_twoByteOpCodes[value & 0xff] = opCode;
-                }
-            }
-        }
-
-        public enum HandlerKind
-        {
-            Try,
-            Catch,
-            Filter,
-            Finally,
-            Fault
-        }
-
-        public struct HandlerSpan : IComparable<HandlerSpan>
-        {
-            public readonly HandlerKind Kind;
-            public readonly object ExceptionType;
-            public readonly int StartOffset;
-            public readonly int FilterHandlerStart;
-            public readonly int EndOffset;
-
-            public HandlerSpan(HandlerKind kind, object exceptionType, int startOffset, int endOffset, int filterHandlerStart = 0)
-            {
-                this.Kind = kind;
-                this.ExceptionType = exceptionType;
-                this.StartOffset = startOffset;
-                this.EndOffset = endOffset;
-                this.FilterHandlerStart = filterHandlerStart;
-            }
-
-            public int CompareTo(HandlerSpan other)
-            {
-                int result = this.StartOffset - other.StartOffset;
-                if (result == 0)
-                {
-                    // Both blocks have same start. Order larger (outer) before smaller (inner).
-                    result = other.EndOffset - this.EndOffset;
-                }
-
-                return result;
-            }
-
-            public string ToString(ILVisualizer visualizer)
-            {
-                switch (this.Kind)
-                {
-                    default:
-                        return ".try";
-                    case HandlerKind.Catch:
-                        return "catch " + visualizer.VisualizeLocalType(this.ExceptionType);
-                    case HandlerKind.Filter:
-                        return "filter";
-                    case HandlerKind.Finally:
-                        return "finally";
-                    case HandlerKind.Fault:
-                        return "fault";
-                }
-            }
-
-            public override string ToString()
-            {
-                throw new NotSupportedException("Use ToString(ILVisualizer)");
-            }
-        }
-
-        public struct LocalInfo
-        {
-            public readonly string Name;
-            public readonly bool IsPinned;
-            public readonly bool IsByRef;
-            public readonly object Type; // ITypeReference or ITypeSymbol
-
-            public LocalInfo(string name, object type, bool isPinned, bool isByRef)
-            {
-                Name = name;
-                Type = type;
-                IsPinned = isPinned;
-                IsByRef = isByRef;
-            }
-        }
-
-        public const string IndentString = "  ";
-
-        public abstract string VisualizeUserString(uint token);
-        public abstract string VisualizeSymbol(uint token);
-        public abstract string VisualizeLocalType(object type);
-
-        private static ulong ReadUInt64(ImmutableArray<byte> buffer, ref int pos)
-        {
-            ulong result =
-                buffer[pos] |
-                (ulong)buffer[pos + 1] << 8 |
-                (ulong)buffer[pos + 2] << 16 |
-                (ulong)buffer[pos + 3] << 24 |
-                (ulong)buffer[pos + 4] << 32 |
-                (ulong)buffer[pos + 5] << 40 |
-                (ulong)buffer[pos + 6] << 48 |
-                (ulong)buffer[pos + 7] << 56;
-
-            pos += sizeof(ulong);
-            return result;
-        }
-
-        private static uint ReadUInt32(ImmutableArray<byte> buffer, ref int pos)
-        {
-            uint result = buffer[pos] | (uint)buffer[pos + 1] << 8 | (uint)buffer[pos + 2] << 16 | (uint)buffer[pos + 3] << 24;
-            pos += sizeof(uint);
-            return result;
-        }
-
-        private static int ReadInt32(ImmutableArray<byte> buffer, ref int pos)
-        {
-            return unchecked((int)ReadUInt32(buffer, ref pos));
-        }
-
-        private static ushort ReadUInt16(ImmutableArray<byte> buffer, ref int pos)
-        {
-            ushort result = (ushort)(buffer[pos]| buffer[pos + 1] << 8);
-            pos += sizeof(ushort);
-            return result;
-        }
-
-        private static byte ReadByte(ImmutableArray<byte> buffer, ref int pos)
-        {
-            byte result = buffer[pos];
-            pos += sizeof(byte);
-            return result;
-        }
-
-        private static sbyte ReadSByte(ImmutableArray<byte> buffer, ref int pos)
-        {
-            sbyte result = unchecked((sbyte)buffer[pos]);
-            pos += 1;
-            return result;
-        }
-
-        private unsafe static float ReadSingle(ImmutableArray<byte> buffer, ref int pos)
-        {
-            uint value = ReadUInt32(buffer, ref pos);
-            return *(float*)&value;
-        }
-
-        private unsafe static double ReadDouble(ImmutableArray<byte> buffer, ref int pos)
-        {
-            ulong value = ReadUInt64(buffer, ref pos);
-            return *(double*)&value;
-        }
-
-        public void VisualizeHeader(StringBuilder sb, int codeSize, int maxStack, ImmutableArray<LocalInfo> locals)
-        {
-            if (codeSize >= 0 && maxStack >= 0)
-            {
-                if (codeSize == 0)
-                {
-                    sb.AppendLine("  // Unrealized IL");
-                }
-                else
-                {
-                    sb.AppendLine(string.Format("  // Code size {0,8} (0x{0:x})", codeSize));
-                }
-
-                sb.AppendLine(string.Format("  .maxstack  {0}", maxStack));
-            }
-
-            int i = 0;
-            foreach (var local in locals)
-            {
-                sb.Append(i == 0 ? "  .locals init (" : new string(' ', "  .locals init (".Length));
-                if (local.IsPinned)
-                {
-                    sb.Append("pinned ");
-                }
-
-                sb.Append(VisualizeLocalType(local.Type));
-                if (local.IsByRef)
-                {
-                    sb.Append("&");
-                }
-
-                sb.Append(" ");
-                sb.Append("V_" + i);
-
-                sb.Append(i == locals.Length - 1 ? ")" : ",");
-
-                var name = local.Name;
-                if (name != null)
-                {
-                    sb.Append(" //");
-                    sb.Append(name);
-                }
-
-                sb.AppendLine();
-
-                i++;
-            }
-        }
-
-        public string DumpMethod(
-            int maxStack,
-            ImmutableArray<byte> ilBytes,
-            ImmutableArray<LocalInfo> locals,
-            IReadOnlyList<HandlerSpan> exceptionHandlers,
-            IReadOnlyDictionary<int, string> markers = null)
-        {
-            var builder = new StringBuilder();
-            this.DumpMethod(builder, maxStack, ilBytes, locals, exceptionHandlers, markers);
-            return builder.ToString();
-        }
-
-        public void DumpMethod(
-            StringBuilder sb,
-            int maxStack,
-            ImmutableArray<byte> ilBytes,
-            ImmutableArray<LocalInfo> locals,
-            IReadOnlyList<HandlerSpan> exceptionHandlers,
-            IReadOnlyDictionary<int, string> markers = null)
-        {
-            sb.AppendLine("{");
-
-            VisualizeHeader(sb, ilBytes.Length, maxStack, locals);
-            DumpILBlock(ilBytes, ilBytes.Length, sb, exceptionHandlers, 0, markers);
-
-            sb.AppendLine("}");
-        }
-
-        /// <summary>
-        /// Dumps all instructions in the stream into provided string builder.
-        /// The blockOffset specifies the relative position of the block within method body (if known).
-        /// </summary>
-        public void DumpILBlock(
-            ImmutableArray<byte> ilBytes,
-            int length,
-            StringBuilder sb,
-            IReadOnlyList<HandlerSpan> spans = null,
-            int blockOffset = 0,
-            IReadOnlyDictionary<int, string> markers = null)
-        {
-            if (ilBytes == null)
-            {
-                return;
-            }
-
-            int spanIndex = 0;
-            int curIndex = DumpILBlock(ilBytes, length, sb, spans, blockOffset, 0, spanIndex, IndentString, markers, out spanIndex);
-            //Debug.Assert(curIndex == length);
-            //Debug.Assert(spans == null || spanIndex == spans.Count);
-        }
-
-        private int DumpILBlock(
-            ImmutableArray<byte> ilBytes,
-            int length,
-            StringBuilder sb,
-            IReadOnlyList<HandlerSpan> spans,
-            int blockOffset,
-            int curIndex,
-            int spanIndex,
-            string indent,
-            IReadOnlyDictionary<int, string> markers,
-            out int nextSpanIndex)
-        {
-            int lastSpanIndex = spanIndex - 1;
-
-            while (curIndex < length)
-            {
-                if (lastSpanIndex > 0 && StartsFilterHandler(spans, lastSpanIndex, curIndex + blockOffset))
-                {
-                    sb.Append(indent.Substring(0, indent.Length - IndentString.Length));
-                    sb.Append("}  // end filter");
-                    sb.AppendLine();
-
-                    sb.Append(indent.Substring(0, indent.Length - IndentString.Length));
-                    sb.Append("{  // handler");
-                    sb.AppendLine();
-                }
-
-                if (StartsSpan(spans, spanIndex, curIndex + blockOffset))
-                {
-                    sb.Append(indent);
-                    sb.Append(spans[spanIndex].ToString(this));
-                    sb.AppendLine();
-                    sb.Append(indent);
-                    sb.Append("{");
-                    sb.AppendLine();
-
-                    curIndex = DumpILBlock(ilBytes, length, sb, spans, blockOffset, curIndex, spanIndex + 1, indent + IndentString, markers, out spanIndex);
-
-                    sb.Append(indent);
-                    sb.Append("}");
-                    sb.AppendLine();
-                }
-                else
-                {
-                    int ilOffset = curIndex + blockOffset;
-                    string marker;
-                    if (markers != null && markers.TryGetValue(ilOffset, out marker))
-                    {
-                        sb.Append(indent.Substring(0, indent.Length - marker.Length));
-                        sb.Append(marker);
-                    }
-                    else
-                    {
-                        sb.Append(indent);
-                    }
-
-                    sb.AppendFormat("IL_{0:x4}:", ilOffset);
-
-                    OpCode opCode;
-                    int expectedSize;
-
-                    byte op1 = ilBytes[curIndex++];
-                    if (op1 == 0xfe && curIndex < length)
-                    {
-                        byte op2 = ilBytes[curIndex++];
-                        opCode = s_twoByteOpCodes[op2];
-                        expectedSize = 2;
-                    }
-                    else
-                    {
-                        opCode = s_oneByteOpCodes[op1];
-                        expectedSize = 1;
-                    }
-
-                    if (opCode.Size != expectedSize)
-                    {
-                        sb.AppendLine(string.Format("  <unknown 0x{0}{1:X2}>", expectedSize == 2 ? "fe" : "", op1));
-                        continue;
-                    }
-
-                    sb.Append("  ");
-                    sb.AppendFormat(opCode.OperandType == OperandType.InlineNone ? "{0}" : "{0,-10}", opCode);
-
-                    switch (opCode.OperandType)
-                    {
-                        case OperandType.InlineField:
-                        case OperandType.InlineMethod:
-                        case OperandType.InlineTok:
-                        case OperandType.InlineType:
-                            sb.Append(' ');
-                            sb.Append(VisualizeSymbol(ReadUInt32(ilBytes, ref curIndex)));
-                            break;
-
-                        case OperandType.InlineSig: // signature (calli), not emitted by C#/VB
-                            sb.AppendFormat(" 0x{0:x}", ReadUInt32(ilBytes, ref curIndex));
-                            break;
-
-                        case OperandType.InlineString:
-                            sb.Append(' ');
-                            sb.Append(VisualizeUserString(ReadUInt32(ilBytes, ref curIndex)));
-                            break;
-
-                        case OperandType.InlineNone:
-                            break;
-
-                        case OperandType.ShortInlineI:
-                            sb.AppendFormat(" {0}", ReadSByte(ilBytes, ref curIndex));
-                            break;
-
-                        case OperandType.ShortInlineVar:
-                            sb.AppendFormat(" V_{0}", ReadByte(ilBytes, ref curIndex));
-                            break;
-
-                        case OperandType.InlineVar:
-                            sb.AppendFormat(" V_{0}", ReadUInt16(ilBytes, ref curIndex));
-                            break;
-
-                        case OperandType.InlineI:
-                            sb.AppendFormat(" 0x{0:x}", ReadUInt32(ilBytes, ref curIndex));
-                            break;
-
-                        case OperandType.InlineI8:
-                            sb.AppendFormat(" 0x{0:x8}", ReadUInt64(ilBytes, ref curIndex));
-                            break;
-
-                        case OperandType.ShortInlineR:
-                            {
-                                var value = ReadSingle(ilBytes, ref curIndex);
-                                if (value == 0 && 1 / value < 0)
-                                {
-                                    sb.Append(" -0.0");
-                                }
-                                else
-                                {
-                                    sb.AppendFormat(" {0}", value.ToString(CultureInfo.InvariantCulture));
-                                }
-                            }
-                            break;
-
-                        case OperandType.InlineR:
-                            {
-                                var value = ReadDouble(ilBytes, ref curIndex);
-                                if (value == 0 && 1 / value < 0)
-                                {
-                                    sb.Append(" -0.0");
-                                }
-                                else
-                                {
-                                    sb.AppendFormat(" {0}", value.ToString(CultureInfo.InvariantCulture));
-                                }
-                            }
-                            break;
-
-                        case OperandType.ShortInlineBrTarget:
-                            sb.AppendFormat(" IL_{0:x4}", ReadSByte(ilBytes, ref curIndex) + curIndex + blockOffset);
-                            break;
-
-                        case OperandType.InlineBrTarget:
-                            sb.AppendFormat(" IL_{0:x4}", ReadInt32(ilBytes, ref curIndex) + curIndex + blockOffset);
-                            break;
-
-                        case OperandType.InlineSwitch:
-                            int labelCount = ReadInt32(ilBytes, ref curIndex);
-                            int instrEnd = curIndex + labelCount * 4;
-                            sb.AppendLine("(");
-                            for (int i = 0; i < labelCount; i++)
-                            {
-                                sb.AppendFormat("        IL_{0:x4}", ReadInt32(ilBytes, ref curIndex) + instrEnd + blockOffset);
-                                sb.AppendLine((i == labelCount - 1) ? ")" : ",");
-                            }
-                            break;
-
-                        default:
-                            throw new InvalidOperationException();
-                            //throw ExceptionUtilities.UnexpectedValue(opCode.OperandType);
-                    }
-
-                    sb.AppendLine();
-                }
-
-                if (EndsSpan(spans, lastSpanIndex, curIndex + blockOffset))
-                {
-                    break;
-                }
-            }
-
-            nextSpanIndex = spanIndex;
-            return curIndex;
-        }
-
-        private static bool StartsSpan(IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-        {
-            return spans != null && spanIndex < spans.Count && spans[spanIndex].StartOffset == (uint)curIndex;
-        }
-
-        private static bool EndsSpan(IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-        {
-            return spans != null && spanIndex >= 0 && spans[spanIndex].EndOffset == (uint)curIndex;
-        }
-
-        private static bool StartsFilterHandler(IReadOnlyList<HandlerSpan> spans, int spanIndex, int curIndex)
-        {
-            return spans != null &&
-                spanIndex < spans.Count &&
-                spans[spanIndex].Kind == HandlerKind.Filter &&
-                spans[spanIndex].FilterHandlerStart == (uint)curIndex;
-        }
-
-        public static IReadOnlyList<HandlerSpan> GetHandlerSpans(ImmutableArray<ExceptionRegion> entries)
-        {
-            if (entries.Length == 0)
-            {
-                return new HandlerSpan[0];
-            }
-
-            var result = new List<HandlerSpan>();
-            foreach (ExceptionRegion entry in entries)
-            {
-                int tryStartOffset = entry.TryOffset;
-                int tryEndOffset = entry.TryOffset + entry.TryLength;
-                var span = new HandlerSpan(HandlerKind.Try, null, tryStartOffset, tryEndOffset);
-
-                if (result.Count == 0 || span.CompareTo(result[result.Count - 1]) != 0)
-                {
-                    result.Add(span);
-                }
-            }
-
-            foreach (ExceptionRegion entry in entries)
-            {
-                int handlerStartOffset = entry.HandlerOffset;
-                int handlerEndOffset = entry.HandlerOffset + entry.HandlerLength;
-
-                HandlerSpan span;
-                switch (entry.Kind)
-                {
-                    case ExceptionRegionKind.Catch:
-                        span = new HandlerSpan(HandlerKind.Catch, MetadataTokens.GetToken(entry.CatchType), handlerStartOffset, handlerEndOffset);
-                        break;
-
-                    case ExceptionRegionKind.Fault:
-                        span = new HandlerSpan(HandlerKind.Fault, null, handlerStartOffset, handlerEndOffset);
-                        break;
-
-                    case ExceptionRegionKind.Filter:
-                        span = new HandlerSpan(HandlerKind.Filter, null, handlerStartOffset, handlerEndOffset, entry.FilterOffset);
-                        break;
-
-                    case ExceptionRegionKind.Finally:
-                        span = new HandlerSpan(HandlerKind.Finally, null, handlerStartOffset, handlerEndOffset);
-                        break;
-
-                    default:
-                        throw new InvalidOperationException();
-                }
-
-                result.Add(span);
-            }
-
-            return result;
-        }
-    }
-}

+ 0 - 24
Build/AtomicNETTest/AtomicEditor/ILVisualizerAsTokens.cs

@@ -1,24 +0,0 @@
-// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
-
-namespace AtomicEditor
-{
-    public sealed class ILVisualizerAsTokens : ILVisualizer
-    {
-        public static readonly ILVisualizerAsTokens Instance = new ILVisualizerAsTokens();
-
-        public override string VisualizeUserString(uint token)
-        {
-            return string.Format("0x{0:X8}", token);
-        }
-
-        public override string VisualizeSymbol(uint token)
-        {
-            return string.Format("0x{0:X8}", token);
-        }
-
-        public override string VisualizeLocalType(object type)
-        {
-            return string.Format("0x{0:X8}", type); // Should be a token.
-        }
-    }
-}

+ 0 - 1803
Build/AtomicNETTest/AtomicEditor/MetadataVisualizer.cs

@@ -1,1803 +0,0 @@
-// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
-
-#if nope
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Reflection.Metadata;
-//using System.Reflection.Metadata.Decoding;
-using System.Reflection.Metadata.Ecma335;
-using System.Text;
-
-namespace Roslyn.Test.MetadataUtilities
-{
-    [Flags]
-    public enum MetadataVisualizerOptions
-    {
-        None = 0,
-        ShortenBlobs = 1,
-    }
-
-    public sealed class MetadataVisualizer
-    {
-        private enum BlobKind
-        {
-            None,
-            Key,
-            FileHash,
-
-            MethodSignature,
-            FieldSignature,
-            MemberRefSignature,
-            StandAloneSignature,
-
-            TypeSpec,
-            MethodSpec,
-
-            ConstantValue,
-            Marshalling,
-            PermissionSet,
-            CustomAttribute,
-
-            DocumentName,
-            DocumentHash,
-            SequencePoints,
-            Imports,
-            ImportAlias,
-            ImportNamespace,
-            LocalConstantSignature,
-            CustomDebugInformation,
-
-            Count
-        }
-
-        private readonly TextWriter _writer;
-        private readonly IReadOnlyList<MetadataReader> _readers;
-        private readonly MetadataAggregator _aggregator;
-        private readonly MetadataVisualizerOptions _options;
-
-        // enc map for each delta reader
-        private readonly ImmutableArray<ImmutableArray<EntityHandle>> _encMaps;
-
-        private MetadataReader _reader;
-        private readonly List<string[]> _pendingRows = new List<string[]>();
-        private readonly Dictionary<BlobHandle, BlobKind> _blobKinds = new Dictionary<BlobHandle, BlobKind>();
-
-        private MetadataVisualizer(TextWriter writer, IReadOnlyList<MetadataReader> readers, MetadataVisualizerOptions options = MetadataVisualizerOptions.None)
-        {
-            _writer = writer;
-            _readers = readers;
-            _options = options;
-
-            if (readers.Count > 1)
-            {
-                var deltaReaders = new List<MetadataReader>(readers.Skip(1));
-                _aggregator = new MetadataAggregator(readers[0], deltaReaders);
-
-                _encMaps = ImmutableArray.CreateRange(deltaReaders.Select(reader => ImmutableArray.CreateRange(reader.GetEditAndContinueMapEntries())));
-            }
-        }
-
-        public MetadataVisualizer(MetadataReader reader, TextWriter writer, MetadataVisualizerOptions options = MetadataVisualizerOptions.None)
-            : this(writer, new[] { reader }, options)
-        {
-            _reader = reader;
-        }
-
-        public MetadataVisualizer(IReadOnlyList<MetadataReader> readers, TextWriter writer, MetadataVisualizerOptions options = MetadataVisualizerOptions.None)
-            : this(writer, readers, options)
-        {
-        }
-
-        public void VisualizeAllGenerations()
-        {
-            for (int i = 0; i < _readers.Count; i++)
-            {
-                _writer.WriteLine(">>>");
-                _writer.WriteLine($">>> Generation {i}:");
-                _writer.WriteLine(">>>");
-                _writer.WriteLine();
-
-                Visualize(i);
-            }
-        }
-
-        public void Visualize(int generation = -1)
-        {
-            _reader = (generation >= 0) ? _readers[generation] : _readers[_readers.Count - 1];
-
-            WriteModule();
-            WriteTypeRef();
-            WriteTypeDef();
-            WriteField();
-            WriteMethod();
-            WriteParam();
-            WriteMemberRef();
-            WriteConstant();
-            WriteCustomAttribute();
-            WriteDeclSecurity();
-            WriteStandAloneSig();
-            WriteEvent();
-            WriteProperty();
-            WriteMethodImpl();
-            WriteModuleRef();
-            WriteTypeSpec();
-            WriteEnCLog();
-            WriteEnCMap();
-            WriteAssembly();
-            WriteAssemblyRef();
-            WriteFile();
-            WriteExportedType();
-            WriteManifestResource();
-            WriteGenericParam();
-            WriteMethodSpec();
-            WriteGenericParamConstraint();
-
-            // debug tables:
-            WriteDocument();
-            WriteMethodBody();
-            WriteLocalScope();
-            WriteLocalVariable();
-            WriteLocalConstant();
-            WriteLocalImport();
-            WriteCustomDebugInformation();
-
-            // heaps:
-            WriteUserStrings();
-            WriteStrings();
-            WriteBlobs();
-            WriteGuids();
-        }
-
-        private bool IsDelta
-        {
-            get
-            {
-                return _reader.GetTableRowCount(TableIndex.EncLog) > 0;
-            }
-        }
-
-        private void WriteTableName(TableIndex index)
-        {
-            WriteRows(MakeTableName(index));
-        }
-
-        private string MakeTableName(TableIndex index)
-        {
-            return $"{index} (index: 0x{(byte)index:X2}, size: {_reader.GetTableRowCount(index) * _reader.GetTableRowSize(index)}): ";
-        }
-
-        private void AddHeader(params string[] header)
-        {
-            Debug.Assert(_pendingRows.Count == 0);
-            _pendingRows.Add(header);
-        }
-
-        private void AddRow(params string[] fields)
-        {
-            Debug.Assert(_pendingRows.Count > 0 && _pendingRows.Last().Length == fields.Length);
-            _pendingRows.Add(fields);
-        }
-
-        private void WriteRows(string title)
-        {
-            Debug.Assert(_pendingRows.Count > 0);
-
-            if (_pendingRows.Count == 1)
-            {
-                _pendingRows.Clear();
-                return;
-            }
-
-            _writer.Write(title);
-            _writer.WriteLine();
-
-            string columnSeparator = "  ";
-            int rowNumberWidth = _pendingRows.Count.ToString("x").Length;
-
-            int[] columnWidths = new int[_pendingRows.First().Length];
-            foreach (var row in _pendingRows)
-            {
-                for (int c = 0; c < row.Length; c++)
-                {
-                    columnWidths[c] = Math.Max(columnWidths[c], row[c].Length + columnSeparator.Length);
-                }
-            }
-
-            int tableWidth = columnWidths.Sum() + columnWidths.Length;
-            string horizontalSeparator = new string('=', tableWidth);
-
-            for (int r = 0; r < _pendingRows.Count; r++)
-            {
-                var row = _pendingRows[r];
-
-                // header
-                if (r == 0)
-                {
-                    _writer.WriteLine(horizontalSeparator);
-                    _writer.Write(new string(' ', rowNumberWidth + 2));
-                }
-                else
-                {
-                    string rowNumber = r.ToString("x");
-                    _writer.Write(new string(' ', rowNumberWidth - rowNumber.Length));
-                    _writer.Write(rowNumber);
-                    _writer.Write(": ");
-                }
-
-                for (int c = 0; c < row.Length; c++)
-                {
-                    var field = row[c];
-
-                    _writer.Write(field);
-                    _writer.Write(new string(' ', columnWidths[c] - field.Length));
-                }
-
-                _writer.WriteLine();
-
-                // header
-                if (r == 0)
-                {
-                    _writer.WriteLine(horizontalSeparator);
-                }
-            }
-
-            _writer.WriteLine();
-            _pendingRows.Clear();
-        }
-
-        private EntityHandle GetAggregateHandle(EntityHandle generationHandle, int generation)
-        {
-            var encMap = _encMaps[generation - 1];
-
-            int start, count;
-            if (!TryGetHandleRange(encMap, generationHandle.Kind, out start, out count))
-            {
-                throw new BadImageFormatException(string.Format("EncMap is missing record for {0:8X}.", MetadataTokens.GetToken(generationHandle)));
-            }
-
-            return encMap[start + MetadataTokens.GetRowNumber(generationHandle) - 1];
-        }
-
-        private static bool TryGetHandleRange(ImmutableArray<EntityHandle> handles, HandleKind handleType, out int start, out int count)
-        {
-            TableIndex tableIndex;
-            MetadataTokens.TryGetTableIndex(handleType, out tableIndex);
-
-            int mapIndex = handles.BinarySearch(MetadataTokens.Handle(tableIndex, 0), TokenTypeComparer.Instance);
-            if (mapIndex < 0)
-            {
-                start = 0;
-                count = 0;
-                return false;
-            }
-
-            int s = mapIndex;
-            while (s >= 0 && handles[s].Kind == handleType)
-            {
-                s--;
-            }
-
-            int e = mapIndex;
-            while (e < handles.Length && handles[e].Kind == handleType)
-            {
-                e++;
-            }
-
-            start = s + 1;
-            count = e - start;
-            return true;
-        }
-
-        private MethodDefinition GetMethod(MethodDefinitionHandle handle)
-        {
-            return Get(handle, (reader, h) => reader.GetMethodDefinition((MethodDefinitionHandle)h));
-        }
-
-        private BlobHandle GetLocalSignature(StandaloneSignatureHandle handle)
-        {
-            return Get(handle, (reader, h) => reader.GetStandaloneSignature((StandaloneSignatureHandle)h).Signature);
-        }
-
-        private TEntity Get<TEntity>(Handle handle, Func<MetadataReader, Handle, TEntity> getter)
-        {
-            if (_aggregator != null)
-            {
-                int generation;
-                var generationHandle = _aggregator.GetGenerationHandle(handle, out generation);
-                return getter(_readers[generation], generationHandle);
-            }
-            else
-            {
-                return getter(_reader, handle);
-            }
-        }
-
-        private string Literal(StringHandle handle)
-        {
-            return Literal(handle, BlobKind.None, (r, h) => "'" + StringUtilities.EscapeNonPrintableCharacters(r.GetString((StringHandle)h)) + "'");
-        }
-
-        private string Literal(NamespaceDefinitionHandle handle)
-        {
-            return Literal(handle, BlobKind.None, (r, h) => "'" + StringUtilities.EscapeNonPrintableCharacters(r.GetString((NamespaceDefinitionHandle)h)) + "'");
-        }
-
-        private string Literal(GuidHandle handle)
-        {
-            return Literal(handle, BlobKind.None, (r, h) => "{" + r.GetGuid((GuidHandle)h) + "}");
-        }
-
-        private static Guid CSharpGuid = new Guid("3f5162f8-07c6-11d3-9053-00c04fa302a1");
-        private static Guid VisualBasicGuid = new Guid("3a12d0b8-c26c-11d0-b442-00a0244a1dd2");
-        private static Guid FSharpGuid = new Guid("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3");
-        private static Guid Sha1Guid = new Guid("ff1816ec-aa5e-4d10-87f7-6f4963833460");
-        private static Guid Sha256Guid = new Guid("8829d00f-11b8-4213-878b-770e8597ac16");
-
-        private string GetLanguage(Guid guid)
-        {
-            if (guid == CSharpGuid) return "C#";
-            if (guid == VisualBasicGuid) return "Visual Basic";
-            if (guid == FSharpGuid) return "F#";
-
-            return "{" + guid + "}";
-        }
-
-        private string GetHashAlgorithm(Guid guid)
-        {
-            if (guid == Sha1Guid) return "SHA-1";
-            if (guid == Sha256Guid) return "SHA-256";
-
-            return "{" + guid + "}";
-        }
-
-        private string Language(GuidHandle handle)
-        {
-            return Literal(handle, BlobKind.None, (r, h) => GetLanguage(r.GetGuid((GuidHandle)h)));
-        }
-
-        private string HashAlgorithm(GuidHandle handle)
-        {
-            return Literal(handle, BlobKind.None, (r, h) => GetHashAlgorithm(r.GetGuid((GuidHandle)h)));
-        }
-
-/*
-        private string Literal(DocumentNameBlobHandle handle)
-        {
-            return Literal((BlobHandle)handle, BlobKind.DocumentName, (r, h) => "'" + r.GetString((DocumentNameBlobHandle)(BlobHandle)h) + "'");
-        }
-*/
-        private string LiteralUtf8Blob(BlobHandle handle, BlobKind kind)
-        {
-            return Literal(handle, kind, (r, h) =>
-            {
-                var bytes = r.GetBlobBytes((BlobHandle)h);
-                return "'" + Encoding.UTF8.GetString(bytes, 0, bytes.Length) + "'";
-            });
-        }
-
-        private string Literal(BlobHandle handle, BlobKind kind)
-        {
-            return Literal(handle, kind, (r, h) => BitConverter.ToString(r.GetBlobBytes((BlobHandle)h)));
-        }
-
-        private string Literal(Handle handle, BlobKind kind, Func<MetadataReader, Handle, string> getValue)
-        {
-            if (handle.IsNil)
-            {
-                return "nil";
-            }
-
-            if (kind != BlobKind.None)
-            {
-                _blobKinds[(BlobHandle)handle] = kind;
-            }
-
-            if (_aggregator != null)
-            {
-                int generation;
-                Handle generationHandle = _aggregator.GetGenerationHandle(handle, out generation);
-
-                var generationReader = _readers[generation];
-                string value = GetValueChecked(getValue, generationReader, generationHandle);
-                int offset = generationReader.GetHeapOffset(handle);
-                int generationOffset = generationReader.GetHeapOffset(generationHandle);
-
-                if (offset == generationOffset)
-                {
-                    return $"{value} (#{offset:x})";
-                }
-                else
-                {
-                    return $"{value} (#{offset:x}/{generationOffset:x})";
-                }
-            }
-
-            if (IsDelta)
-            {
-                // we can't resolve the literal without aggregate reader
-                return string.Format("#{0:x}", _reader.GetHeapOffset(handle));
-            }
-
-            // virtual heap handles don't have offset:
-            int heapOffset = MetadataTokens.GetHeapOffset(handle);
-            return $"{GetValueChecked(getValue, _reader, handle):x}" + (heapOffset >= 0 ? $" (#{heapOffset:x})" : "");
-        }
-
-        private string GetValueChecked(Func<MetadataReader, Handle, string> getValue, MetadataReader reader, Handle handle)
-        {
-            try
-            {
-                return getValue(reader, handle);
-            }
-            catch (BadImageFormatException)
-            {
-                return "<bad metadata>";
-            }
-        }
-
-        private string Hex(ushort value)
-        {
-            return "0x" + value.ToString("X4");
-        }
-
-        private string Hex(int value)
-        {
-            return "0x" + value.ToString("X8");
-        }
-
-        public string Token(Func<Handle> handleFunc, bool displayTable = true)
-        {
-            Handle handle;
-
-            try
-            {
-                handle = handleFunc();
-            }
-            catch (BadImageFormatException)
-            {
-                return "<bad metadata>";
-            }
-
-            if (handle.IsNil)
-            {
-                return "nil";
-            }
-
-            TableIndex table;
-            if (displayTable && MetadataTokens.TryGetTableIndex(handle.Kind, out table))
-            {
-                return string.Format("0x{0:x8} ({1})", _reader.GetToken(handle), table);
-            }
-            else
-            {
-                return string.Format("0x{0:x8}", _reader.GetToken(handle));
-            }
-        }
-
-        private static string EnumValue<T>(object value) where T : IEquatable<T>
-        {
-            T integralValue = (T)value;
-            if (integralValue.Equals(default(T)))
-            {
-                return "0";
-            }
-
-            return string.Format("0x{0:x8} ({1})", integralValue, value);
-        }
-
-        // TODO (tomat): handle collections should implement IReadOnlyCollection<Handle>
-        private string TokenRange<THandle>(IReadOnlyCollection<THandle> handles, Func<THandle, EntityHandle> conversion)
-        {
-            var genericHandles = handles.Select(conversion);
-
-            if (handles.Count < 0)
-            {
-                return "<bad token range>";
-            }
-
-            return (handles.Count == 0) ? "nil" : Token(() => genericHandles.First(), displayTable: false) + "-" + Token(() => genericHandles.Last(), displayTable: false);
-        }
-
-        public string TokenList(IReadOnlyCollection<EntityHandle> handles, bool displayTable = false)
-        {
-            if (handles.Count == 0)
-            {
-                return "nil";
-            }
-
-            return string.Join(", ", handles.Select(h => Token(() => h, displayTable)));
-        }
-
-        private string FormatAwaits(BlobHandle handle)
-        {
-            var sb = new StringBuilder();
-            var blobReader = _reader.GetBlobReader(handle);
-
-            while (blobReader.RemainingBytes > 0)
-            {
-                if (blobReader.Offset > 0)
-                {
-                    sb.Append(", ");
-                }
-
-                int value;
-                sb.Append("(");
-                sb.Append(blobReader.TryReadCompressedInteger(out value) ? value.ToString() : "?");
-                sb.Append(", ");
-                sb.Append(blobReader.TryReadCompressedInteger(out value) ? value.ToString() : "?");
-                sb.Append(", ");
-                sb.Append(blobReader.TryReadCompressedInteger(out value) ? Token(() => MetadataTokens.MethodDefinitionHandle(value)) : "?");
-                sb.Append(')');
-            }
-
-            return sb.ToString();
-        }
-
-        private string FormatImports(BlobHandle handle)
-        {
-            if (handle.IsNil)
-            {
-                return "nil";
-            }
-
-            var sb = new StringBuilder();
-
-            var importsReader = _reader.GetImportsReader(handle);
-            while (importsReader.MoveNext())
-            {
-                if (sb.Length > 0)
-                {
-                    sb.Append(", ");
-                }
-
-                var import = importsReader.Current;
-                switch (import.Kind)
-                {
-                    case ImportDefinitionKind.ImportNamespace:
-                        sb.AppendFormat("{0}", LiteralUtf8Blob(import.TargetNamespace, BlobKind.ImportNamespace));
-                        break;
-
-                    case ImportDefinitionKind.ImportAssemblyNamespace:
-                        sb.AppendFormat("{0}::{1}",
-                            Token(() => import.TargetAssembly),
-                            LiteralUtf8Blob(import.TargetNamespace, BlobKind.ImportNamespace));
-                        break;
-
-                    case ImportDefinitionKind.ImportType:
-                        sb.AppendFormat("{0}::{1}",
-                            Token(() => import.TargetAssembly),
-                            Token(() => import.TargetType));
-                        break;
-
-                    case ImportDefinitionKind.ImportXmlNamespace:
-                        sb.AppendFormat("<{0} = {1}>",
-                            LiteralUtf8Blob(import.Alias, BlobKind.ImportAlias),
-                            LiteralUtf8Blob(import.TargetNamespace, BlobKind.ImportNamespace));
-                        break;
-
-                    case ImportDefinitionKind.ImportAssemblyReferenceAlias:
-                        sb.AppendFormat("Extern Alias {0}",
-                            LiteralUtf8Blob(import.Alias, BlobKind.ImportAlias));
-                        break;
-
-                    case ImportDefinitionKind.AliasAssemblyReference:
-                        sb.AppendFormat("{0} = {1}",
-                            LiteralUtf8Blob(import.Alias, BlobKind.ImportAlias),
-                            Token(() => import.TargetAssembly));
-                        break;
-
-                    case ImportDefinitionKind.AliasNamespace:
-                        sb.AppendFormat("{0} = {1}",
-                            LiteralUtf8Blob(import.Alias, BlobKind.ImportAlias),
-                            LiteralUtf8Blob(import.TargetNamespace, BlobKind.ImportNamespace));
-                        break;
-
-                    case ImportDefinitionKind.AliasAssemblyNamespace:
-                        sb.AppendFormat("{0} = {1}::{2}",
-                            LiteralUtf8Blob(import.Alias, BlobKind.ImportAlias),
-                            Token(() => import.TargetAssembly),
-                            LiteralUtf8Blob(import.TargetNamespace, BlobKind.ImportNamespace));
-                        break;
-
-                    case ImportDefinitionKind.AliasType:
-                        sb.AppendFormat("{0} = {1}",
-                            LiteralUtf8Blob(import.Alias, BlobKind.ImportAlias),
-                            Token(() => import.TargetType));
-                        break;
-                }
-            }
-
-            return sb.ToString();
-        }
-
-/*
-        private string SequencePoint(SequencePoint sequencePoint)
-        {
-            string range = sequencePoint.IsHidden ? "<hidden>" : $"({sequencePoint.StartLine}, {sequencePoint.StartColumn}) - ({sequencePoint.EndLine}, {sequencePoint.EndColumn})";
-            return $"IL_{sequencePoint.Offset:X4}: " + range;
-        }
-*/
-        public void VisualizeHeaders()
-        {
-            _reader = _readers[0];
-
-            _writer.WriteLine("MetadataVersion: {0}", _reader.MetadataVersion);
-
-            if (_reader.DebugMetadataHeader != null)
-            {
-                if (!_reader.DebugMetadataHeader.EntryPoint.IsNil)
-                {
-                    _writer.WriteLine("EntryPoint: {0}", Token(() => _reader.DebugMetadataHeader.EntryPoint));
-                }
-            }
-
-            _writer.WriteLine();
-        }
-
-        private void WriteModule()
-        {
-            if (_reader.DebugMetadataHeader != null)
-            {
-                return;
-            }
-
-            var def = _reader.GetModuleDefinition();
-
-            AddHeader(
-                "Gen",
-                "Name",
-                "Mvid",
-                "EncId",
-                "EncBaseId"
-            );
-
-            AddRow(
-                def.Generation.ToString(),
-                Literal(def.Name),
-                Literal(def.Mvid),
-                Literal(def.GenerationId),
-                Literal(def.BaseGenerationId));
-
-            WriteRows("Module (0x00):");
-        }
-
-        private void WriteTypeRef()
-        {
-            AddHeader(
-                "Scope",
-                "Name",
-                "Namespace"
-            );
-
-            foreach (var handle in _reader.TypeReferences)
-            {
-                var entry = _reader.GetTypeReference(handle);
-
-                AddRow(
-                    Token(() => entry.ResolutionScope),
-                    Literal(entry.Name),
-                    Literal(entry.Namespace)
-                );
-            }
-
-            WriteRows("TypeRef (0x01):");
-        }
-
-        private void WriteTypeDef()
-        {
-            AddHeader(
-                "Name",
-                "Namespace",
-                "EnclosingType",
-                "BaseType",
-                "Interfaces",
-                "Fields",
-                "Methods",
-                "Attributes",
-                "ClassSize",
-                "PackingSize"
-            );
-
-            foreach (var handle in _reader.TypeDefinitions)
-            {
-                var entry = _reader.GetTypeDefinition(handle);
-
-                var layout = entry.GetLayout();
-
-                // TODO: Visualize InterfaceImplementations
-                var implementedInterfaces = entry.GetInterfaceImplementations().Select(h => _reader.GetInterfaceImplementation(h).Interface).ToArray();
-
-                AddRow(
-                    Literal(entry.Name),
-                    Literal(entry.Namespace),
-                    Token(() => entry.GetDeclaringType()),
-                    Token(() => entry.BaseType),
-                    TokenList(implementedInterfaces),
-                    TokenRange(entry.GetFields(), h => h),
-                    TokenRange(entry.GetMethods(), h => h),
-                    EnumValue<int>(entry.Attributes),
-                    !layout.IsDefault ? layout.Size.ToString() : "n/a",
-                    !layout.IsDefault ? layout.PackingSize.ToString() : "n/a"
-                );
-            }
-
-            WriteRows("TypeDef (0x02):");
-        }
-
-        private void WriteField()
-        {
-            AddHeader(
-                "Name",
-                "Signature",
-                "Attributes",
-                "Marshalling",
-                "Offset",
-                "RVA"
-            );
-
-            foreach (var handle in _reader.FieldDefinitions)
-            {
-                var entry = _reader.GetFieldDefinition(handle);
-
-                int offset = entry.GetOffset();
-
-                AddRow(
-                    Literal(entry.Name),
-                    Literal(entry.Signature, BlobKind.FieldSignature),
-                    EnumValue<int>(entry.Attributes),
-                    Literal(entry.GetMarshallingDescriptor(), BlobKind.Marshalling),
-                    offset >= 0 ? offset.ToString() : "n/a",
-                    entry.GetRelativeVirtualAddress().ToString()
-                );
-            }
-
-            WriteRows("Field (0x04):");
-        }
-
-        private void WriteMethod()
-        {
-            AddHeader(
-                "Name",
-                "Signature",
-                "RVA",
-                "Parameters",
-                "GenericParameters",
-                "ImplAttributes",
-                "Attributes",
-                "ImportAttributes",
-                "ImportName",
-                "ImportModule"
-            );
-
-            foreach (var handle in _reader.MethodDefinitions)
-            {
-                var entry = _reader.GetMethodDefinition(handle);
-                var import = entry.GetImport();
-
-                AddRow(
-                    Literal(entry.Name),
-                    Literal(entry.Signature, BlobKind.MethodSignature),
-                    Hex(entry.RelativeVirtualAddress),
-                    TokenRange(entry.GetParameters(), h => h),
-                    TokenRange(entry.GetGenericParameters(), h => h),
-                    EnumValue<int>(entry.Attributes),    // TODO: we need better visualizer than the default enum
-                    EnumValue<int>(entry.ImplAttributes),
-                    EnumValue<short>(import.Attributes),
-                    Literal(import.Name),
-                    Token(() => import.Module)
-                );
-            }
-
-            WriteRows("Method (0x06, 0x1C):");
-        }
-
-        private void WriteParam()
-        {
-            AddHeader(
-                "Name",
-                "Seq#",
-                "Attributes",
-                "Marshalling"
-            );
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.Param); i <= count; i++)
-            {
-                var entry = _reader.GetParameter(MetadataTokens.ParameterHandle(i));
-
-                AddRow(
-                    Literal(entry.Name),
-                    entry.SequenceNumber.ToString(),
-                    EnumValue<int>(entry.Attributes),
-                    Literal(entry.GetMarshallingDescriptor(), BlobKind.Marshalling)
-                );
-            }
-
-            WriteRows("Param (0x08):");
-        }
-
-        private void WriteMemberRef()
-        {
-            AddHeader(
-                "Parent",
-                "Name",
-                "Signature"
-            );
-
-            foreach (var handle in _reader.MemberReferences)
-            {
-                var entry = _reader.GetMemberReference(handle);
-
-                AddRow(
-                    Token(() => entry.Parent),
-                    Literal(entry.Name),
-                    Literal(entry.Signature, BlobKind.MemberRefSignature)
-                );
-            }
-
-            WriteRows("MemberRef (0x0a):");
-        }
-
-        private void WriteConstant()
-        {
-            AddHeader(
-                "Parent",
-                "Type",
-                "Value"
-            );
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.Constant); i <= count; i++)
-            {
-                var entry = _reader.GetConstant(MetadataTokens.ConstantHandle(i));
-
-                AddRow(
-                    Token(() => entry.Parent),
-                    EnumValue<byte>(entry.TypeCode),
-                    Literal(entry.Value, BlobKind.ConstantValue)
-                );
-            }
-
-            WriteRows("Constant (0x0b):");
-        }
-
-        private void WriteCustomAttribute()
-        {
-            AddHeader(
-                "Parent",
-                "Constructor",
-                "Value"
-            );
-
-            foreach (var handle in _reader.CustomAttributes)
-            {
-                var entry = _reader.GetCustomAttribute(handle);
-
-                AddRow(
-                    Token(() => entry.Parent),
-                    Token(() => entry.Constructor),
-                    Literal(entry.Value, BlobKind.CustomAttribute)
-                );
-            }
-
-            WriteRows("CustomAttribute (0x0c):");
-        }
-
-        private void WriteDeclSecurity()
-        {
-            AddHeader(
-                "Parent",
-                "PermissionSet",
-                "Action"
-            );
-
-            foreach (var handle in _reader.DeclarativeSecurityAttributes)
-            {
-                var entry = _reader.GetDeclarativeSecurityAttribute(handle);
-
-                AddRow(
-                    Token(() => entry.Parent),
-                    Literal(entry.PermissionSet, BlobKind.PermissionSet),
-                    EnumValue<short>(entry.Action)
-                );
-            }
-
-            WriteRows("DeclSecurity (0x0e):");
-        }
-
-        private void WriteStandAloneSig()
-        {
-            AddHeader("Signature");
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.StandAloneSig); i <= count; i++)
-            {
-                var value = _reader.GetStandaloneSignature(MetadataTokens.StandaloneSignatureHandle(i)).Signature;
-
-                AddRow(Literal(value, BlobKind.StandAloneSignature));
-            }
-
-            WriteRows("StandAloneSig (0x11):");
-        }
-
-        private void WriteEvent()
-        {
-            AddHeader(
-                "Name",
-                "Add",
-                "Remove",
-                "Fire",
-                "Attributes"
-            );
-
-            foreach (var handle in _reader.EventDefinitions)
-            {
-                var entry = _reader.GetEventDefinition(handle);
-                var accessors = entry.GetAccessors();
-
-                AddRow(
-                    Literal(entry.Name),
-                    Token(() => accessors.Adder),
-                    Token(() => accessors.Remover),
-                    Token(() => accessors.Raiser),
-                    EnumValue<int>(entry.Attributes)
-                );
-            }
-
-            WriteRows("Event (0x12, 0x14, 0x18):");
-        }
-
-        private void WriteProperty()
-        {
-            AddHeader(
-                "Name",
-                "Get",
-                "Set",
-                "Attributes"
-            );
-
-            foreach (var handle in _reader.PropertyDefinitions)
-            {
-                var entry = _reader.GetPropertyDefinition(handle);
-                var accessors = entry.GetAccessors();
-
-                AddRow(
-                    Literal(entry.Name),
-                    Token(() => accessors.Getter),
-                    Token(() => accessors.Setter),
-                    EnumValue<int>(entry.Attributes)
-                );
-            }
-
-            WriteRows("Property (0x15, 0x17, 0x18):");
-        }
-
-        private void WriteMethodImpl()
-        {
-            AddHeader(
-                "Type",
-                "Body",
-                "Declaration"
-            );
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.MethodImpl); i <= count; i++)
-            {
-                var entry = _reader.GetMethodImplementation(MetadataTokens.MethodImplementationHandle(i));
-
-                AddRow(
-                    Token(() => entry.Type),
-                    Token(() => entry.MethodBody),
-                    Token(() => entry.MethodDeclaration)
-                );
-            }
-
-            WriteRows("MethodImpl (0x19):");
-        }
-
-        private void WriteModuleRef()
-        {
-            AddHeader("Name");
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.ModuleRef); i <= count; i++)
-            {
-                var value = _reader.GetModuleReference(MetadataTokens.ModuleReferenceHandle(i)).Name;
-                AddRow(Literal(value));
-            }
-
-            WriteRows("ModuleRef (0x1a):");
-        }
-
-        private void WriteTypeSpec()
-        {
-            AddHeader("Name");
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.TypeSpec); i <= count; i++)
-            {
-                var value = _reader.GetTypeSpecification(MetadataTokens.TypeSpecificationHandle(i)).Signature;
-                AddRow(Literal(value, BlobKind.TypeSpec));
-            }
-
-            WriteRows("TypeSpec (0x1b):");
-        }
-
-        private void WriteEnCLog()
-        {
-            AddHeader(
-                "Entity",
-                "Operation");
-
-            foreach (var entry in _reader.GetEditAndContinueLogEntries())
-            {
-                AddRow(
-                    Token(() => entry.Handle),
-                    EnumValue<int>(entry.Operation));
-            }
-
-            WriteRows("EnC Log (0x1e):");
-        }
-
-        private void WriteEnCMap()
-        {
-            if (_aggregator != null)
-            {
-                AddHeader("Entity", "Gen", "Row", "Edit");
-            }
-            else
-            {
-                AddHeader("Entity");
-            }
-
-
-            foreach (var entry in _reader.GetEditAndContinueMapEntries())
-            {
-                if (_aggregator != null)
-                {
-                    int generation;
-                    EntityHandle primary = (EntityHandle)_aggregator.GetGenerationHandle(entry, out generation);
-                    bool isUpdate = _readers[generation] != _reader;
-
-                    var primaryModule = _readers[generation].GetModuleDefinition();
-
-                    AddRow(
-                        Token(() => entry),
-                        primaryModule.Generation.ToString(),
-                        "0x" + MetadataTokens.GetRowNumber(primary).ToString("x6"),
-                        isUpdate ? "update" : "add");
-                }
-                else
-                {
-                    AddRow(Token(() => entry));
-                }
-            }
-
-            WriteRows("EnC Map (0x1f):");
-        }
-
-        private void WriteAssembly()
-        {
-            if (!_reader.IsAssembly)
-            {
-                return;
-            }
-
-            AddHeader(
-                "Name",
-                "Version",
-                "Culture",
-                "PublicKey",
-                "Flags",
-                "HashAlgorithm"
-            );
-
-            var entry = _reader.GetAssemblyDefinition();
-
-            AddRow(
-                Literal(entry.Name),
-                entry.Version.Major + "." + entry.Version.Minor + "." + entry.Version.Revision + "." + entry.Version.Build,
-                Literal(entry.Culture),
-                Literal(entry.PublicKey, BlobKind.Key),
-                EnumValue<int>(entry.Flags),
-                EnumValue<int>(entry.HashAlgorithm)
-            );
-
-            WriteRows("Assembly (0x20):");
-        }
-
-        private void WriteAssemblyRef()
-        {
-            AddHeader(
-                "Name",
-                "Version",
-                "Culture",
-                "PublicKeyOrToken",
-                "Flags"
-            );
-
-            foreach (var handle in _reader.AssemblyReferences)
-            {
-                var entry = _reader.GetAssemblyReference(handle);
-
-                AddRow(
-                    Literal(entry.Name),
-                    entry.Version.Major + "." + entry.Version.Minor + "." + entry.Version.Revision + "." + entry.Version.Build,
-                    Literal(entry.Culture),
-                    Literal(entry.PublicKeyOrToken, BlobKind.Key),
-                    EnumValue<int>(entry.Flags)
-                );
-            }
-
-            WriteRows("AssemblyRef (0x23):");
-        }
-
-        private void WriteFile()
-        {
-            AddHeader(
-                "Name",
-                "Metadata",
-                "HashValue"
-            );
-
-            foreach (var handle in _reader.AssemblyFiles)
-            {
-                var entry = _reader.GetAssemblyFile(handle);
-
-                AddRow(
-                    Literal(entry.Name),
-                    entry.ContainsMetadata ? "Yes" : "No",
-                    Literal(entry.HashValue, BlobKind.FileHash)
-                );
-            }
-
-            WriteRows("File (0x26):");
-        }
-        private void WriteExportedType()
-        {
-            AddHeader(
-                "Name",
-                "Namespace",
-                "Attributes",
-                "Implementation",
-                "TypeDefinitionId"
-            );
-
-            foreach (var handle in _reader.ExportedTypes)
-            {
-                var entry = _reader.GetExportedType(handle);
-                AddRow(
-                    Literal(entry.Name),
-                    Literal(entry.Namespace),
-                    entry.Attributes.ToString(),
-                    Token(() => entry.Implementation),
-                    Hex(entry.GetTypeDefinitionId())
-                );
-            }
-
-            WriteRows("ExportedType (0x27):");
-        }
-
-        private void WriteManifestResource()
-        {
-            AddHeader(
-                "Name",
-                "Attributes",
-                "Offset",
-                "Implementation"
-            );
-
-            foreach (var handle in _reader.ManifestResources)
-            {
-                var entry = _reader.GetManifestResource(handle);
-
-                AddRow(
-                    Literal(entry.Name),
-                    entry.Attributes.ToString(),
-                    entry.Offset.ToString(),
-                    Token(() => entry.Implementation)
-                );
-            }
-
-            WriteRows("ManifestResource (0x28):");
-        }
-
-        private void WriteGenericParam()
-        {
-            AddHeader(
-                "Name",
-                "Seq#",
-                "Attributes",
-                "Parent",
-                "TypeConstraints"
-            );
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.GenericParam); i <= count; i++)
-            {
-                var entry = _reader.GetGenericParameter(MetadataTokens.GenericParameterHandle(i));
-
-                AddRow(
-                    Literal(entry.Name),
-                    entry.Index.ToString(),
-                    EnumValue<int>(entry.Attributes),
-                    Token(() => entry.Parent),
-                    TokenRange(entry.GetConstraints(), h => h)
-                );
-            }
-
-            WriteRows("GenericParam (0x2a):");
-        }
-
-        private void WriteMethodSpec()
-        {
-            AddHeader(
-                "Method",
-                "Signature"
-            );
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.MethodSpec); i <= count; i++)
-            {
-                var entry = _reader.GetMethodSpecification(MetadataTokens.MethodSpecificationHandle(i));
-
-                AddRow(
-                    Token(() => entry.Method),
-                    Literal(entry.Signature, BlobKind.MethodSpec)
-                );
-            }
-
-            WriteRows("MethodSpec (0x2b):");
-        }
-
-        private void WriteGenericParamConstraint()
-        {
-            AddHeader(
-                "Parent",
-                "Type"
-            );
-
-            for (int i = 1, count = _reader.GetTableRowCount(TableIndex.GenericParamConstraint); i <= count; i++)
-            {
-                var entry = _reader.GetGenericParameterConstraint(MetadataTokens.GenericParameterConstraintHandle(i));
-
-                AddRow(
-                    Token(() => entry.Parameter),
-                    Token(() => entry.Type)
-                );
-            }
-
-            WriteRows("GenericParamConstraint (0x2c):");
-        }
-
-        private void WriteUserStrings()
-        {
-            int size = _reader.GetHeapSize(HeapIndex.UserString);
-            if (size == 0)
-            {
-                return;
-            }
-
-            // TODO: the heap is aligned, don't display the trailing empty strings
-            _writer.WriteLine($"#US (size = {size}):");
-            var handle = MetadataTokens.UserStringHandle(0);
-            do
-            {
-                string value = StringUtilities.EscapeNonPrintableCharacters(_reader.GetUserString(handle));
-                _writer.WriteLine($"  {_reader.GetHeapOffset(handle):x}: '{value}'");
-                handle = _reader.GetNextHandle(handle);
-            }
-            while (!handle.IsNil);
-
-            _writer.WriteLine();
-        }
-
-        private void WriteStrings()
-        {
-            int size = _reader.GetHeapSize(HeapIndex.String);
-            if (size == 0)
-            {
-                return;
-            }
-
-            _writer.WriteLine($"#String (size = {size}):");
-            var handle = MetadataTokens.StringHandle(0);
-            do
-            {
-                string value = StringUtilities.EscapeNonPrintableCharacters(_reader.GetString(handle));
-                _writer.WriteLine($"  {_reader.GetHeapOffset(handle):x}: '{value}'");
-                handle = _reader.GetNextHandle(handle);
-            }
-            while (!handle.IsNil);
-
-            _writer.WriteLine();
-        }
-
-        private void WriteBlobs()
-        {
-            int size = _reader.GetHeapSize(HeapIndex.Blob);
-            if (size == 0)
-            {
-                return;
-            }
-
-            int[] sizePerKind = new int[(int)BlobKind.Count];
-
-            _writer.WriteLine($"#Blob (size = {size}):");
-            var handle = MetadataTokens.BlobHandle(0);
-            do
-            {
-                byte[] value = _reader.GetBlobBytes(handle);
-
-                BlobKind kind;
-                string kindString;
-                if (_blobKinds.TryGetValue(handle, out kind))
-                {
-                    kindString = " (" + kind + ")";
-
-                    // ignoring the compressed blob size:
-                    sizePerKind[(int)kind] += value.Length;
-                }
-                else
-                {
-                    kindString = "";
-                }
-
-                int displayLength = (_options & MetadataVisualizerOptions.ShortenBlobs) != 0 ? Math.Min(4, value.Length) : value.Length;
-                string valueString = BitConverter.ToString(value, 0, displayLength) + (displayLength < value.Length ? "-..." : null);
-
-                _writer.WriteLine($"  {_reader.GetHeapOffset(handle):x}{kindString}: {valueString}");
-                handle = _reader.GetNextHandle(handle);
-            }
-            while (!handle.IsNil);
-
-            _writer.WriteLine();
-            _writer.WriteLine("Sizes:");
-
-            for (int i = 0; i < sizePerKind.Length; i++)
-            {
-                if (sizePerKind[i] > 0)
-                {
-                    _writer.WriteLine($"  {(BlobKind)i}: {(decimal)sizePerKind[i]} bytes");
-                }
-            }
-
-            // don't calculate statistics for EnC delta, it's not interesting
-            if (_aggregator == null)
-            {
-                _writer.WriteLine();
-                _writer.WriteLine("CustomAttribute sizes by constructor:");
-                try
-                {
-                    foreach (var grouping in from caHandle in _reader.CustomAttributes
-                                             let ca = _reader.GetCustomAttribute(caHandle)
-                                             group ca.Constructor by ca.Value into values   // blob -> { ctor1, ctor2, ... }
-                                             group values.Key by values.First() into g      // ctor1 -> { blob1, ... }
-                                             select new { Ctor = g.Key, Size = g.Sum(ca => _reader.GetBlobReader(ca).Length) } into ctorAndSize
-                                             orderby ctorAndSize.Size descending
-                                             select ctorAndSize)
-                    {
-                        string typeStr = null;
-                        switch (grouping.Ctor.Kind)
-                        {
-                            case HandleKind.MemberReference:
-                                var memberRef = _reader.GetMemberReference((MemberReferenceHandle)grouping.Ctor);
-
-                                switch (memberRef.Parent.Kind)
-                                {
-                                    case HandleKind.TypeReference:
-                                        var typeRef = _reader.GetTypeReference((TypeReferenceHandle)memberRef.Parent);
-                                        typeStr = typeRef.Namespace.IsNil ? _reader.GetString(typeRef.Name) : _reader.GetString(typeRef.Namespace) + "." + _reader.GetString(typeRef.Name);
-                                        break;
-
-                                    case HandleKind.TypeDefinition:
-                                        var typeDef = _reader.GetTypeDefinition((TypeDefinitionHandle)memberRef.Parent);
-                                        typeStr = typeDef.Namespace.IsNil ? _reader.GetString(typeDef.Name) : _reader.GetString(typeDef.Namespace) + "." + _reader.GetString(typeDef.Name);
-                                        break;
-
-                                    case HandleKind.MethodDefinition:
-                                    case HandleKind.ModuleReference:
-                                    case HandleKind.TypeSpecification:
-                                        break;
-                                }
-
-                                break;
-
-                            case HandleKind.MethodDefinition:
-                                // TODO
-                                break;
-                        }
-
-
-                        // grouping.Key
-                        _writer.WriteLine($"  {typeStr ?? Token(() => grouping.Ctor)}: {grouping.Size} bytes");
-                    }
-                }
-                catch (BadImageFormatException)
-                {
-                    _writer.WriteLine("<bad metadata>");
-                }
-
-                _writer.WriteLine();
-            }
-        }
-
-        private void WriteGuids()
-        {
-            int size = _reader.GetHeapSize(HeapIndex.Guid);
-            if (size == 0)
-            {
-                return;
-            }
-
-            _writer.WriteLine(string.Format("#Guid (size = {0}):", size));
-            int i = 1;
-            while (i <= size / 16)
-            {
-                string value = _reader.GetGuid(MetadataTokens.GuidHandle(i)).ToString();
-                _writer.WriteLine("  {0:x}: {{{1}}}", i, value);
-                i++;
-            }
-
-            _writer.WriteLine();
-        }
-
-        private void WriteDocument()
-        {
-            AddHeader(
-                "Name",
-                "Language",
-                "HashAlgorithm",
-                "Hash"
-            );
-
-            foreach (var handle in _reader.Documents)
-            {
-                var entry = _reader.GetDocument(handle);
-
-                AddRow(
-                    Literal(entry.Name),
-                    Language(entry.Language),
-                    HashAlgorithm(entry.HashAlgorithm),
-                    Literal(entry.Hash, BlobKind.DocumentHash)
-               );
-            }
-
-            WriteTableName(TableIndex.Document);
-        }
-
-        private void WriteMethodBody()
-        {
-            if (_reader.MethodBodies.Count == 0)
-            {
-                return;
-            }
-
-            _writer.WriteLine(MakeTableName(TableIndex.MethodBody));
-            _writer.WriteLine(new string('=', 50));
-
-            foreach (var handle in _reader.MethodBodies)
-            {
-                if (handle.IsNil)
-                {
-                    continue;
-                }
-
-                var entry = _reader.GetMethodBody(handle);
-
-                _writer.WriteLine($"{MetadataTokens.GetRowNumber(handle)}: #{_reader.GetHeapOffset(entry.SequencePoints)}");
-
-                if (entry.SequencePoints.IsNil)
-                {
-                    continue;
-                }
-
-                _blobKinds[entry.SequencePoints] = BlobKind.SequencePoints;
-
-                _writer.WriteLine("{");
-
-                bool addLineBreak = false;
-
-                var kickoffMethod = entry.GetStateMachineKickoffMethod();
-                if (!kickoffMethod.IsNil)
-                {
-                    _writer.WriteLine($"  Kickoff Method: {Token(() => kickoffMethod)}");
-                    addLineBreak = true;
-                }
-
-                if (!entry.LocalSignature.IsNil)
-                {
-                    _writer.WriteLine($"  Locals: {Token(() => entry.LocalSignature)}");
-                    addLineBreak = true;
-                }
-
-                if (addLineBreak)
-                {
-                    _writer.WriteLine();
-                }
-
-                try
-                {
-                    var spReader = _reader.GetSequencePointsReader(entry.SequencePoints);
-                    while (spReader.MoveNext())
-                    {
-                        _writer.Write("  ");
-                        _writer.WriteLine(SequencePoint(spReader.Current));
-                    }
-                }
-                catch (BadImageFormatException)
-                {
-                    _writer.WriteLine("<bad metadata>");
-                }
-
-                _writer.WriteLine("}");
-            }
-
-            _writer.WriteLine();
-        }
-
-        private void WriteLocalScope()
-        {
-            AddHeader(
-                "Method",
-                "ImportScope",
-                "Variables",
-                "Constants",
-                "StartOffset",
-                "Length"
-            );
-
-            foreach (var handle in _reader.LocalScopes)
-            {
-                var entry = _reader.GetLocalScope(handle);
-
-                AddRow(
-                    Token(() => entry.Method),
-                    Token(() => entry.ImportScope),
-                    TokenRange(entry.GetLocalVariables(), h => h),
-                    TokenRange(entry.GetLocalConstants(), h => h),
-                    entry.StartOffset.ToString("X4"),
-                    entry.Length.ToString()
-               );
-            }
-
-            WriteTableName(TableIndex.LocalScope);
-        }
-
-        private void WriteLocalVariable()
-        {
-            AddHeader(
-                "Name",
-                "Index",
-                "Attributes"
-            );
-
-            foreach (var handle in _reader.LocalVariables)
-            {
-                var entry = _reader.GetLocalVariable(handle);
-
-                AddRow(
-                    Literal(entry.Name),
-                    entry.Index.ToString(),
-                    entry.Attributes.ToString()
-               );
-            }
-
-            WriteTableName(TableIndex.LocalVariable);
-        }
-
-        private void WriteLocalConstant()
-        {
-            AddHeader(
-                "Name",
-                "Signature"
-            );
-
-            foreach (var handle in _reader.LocalConstants)
-            {
-                var entry = _reader.GetLocalConstant(handle);
-
-                AddRow(
-                    Literal(entry.Name),
-                    Literal(entry.Signature, BlobKind.LocalConstantSignature, (r, h) => FormatLocalConstant(r, (BlobHandle)h))
-               );
-            }
-
-            WriteTableName(TableIndex.LocalConstant);
-        }
-
-/*
-        private SignatureTypeCode ReadConstantTypeCode(ref BlobReader sigReader, List<CustomModifier<Handle>> modifiers)
-        {
-            while (true)
-            {
-                var s = sigReader.ReadSignatureTypeCode();
-                if (s == SignatureTypeCode.OptionalModifier || s == SignatureTypeCode.RequiredModifier)
-                {
-                    var type = sigReader.ReadTypeHandle();
-                    modifiers.Add(new CustomModifier<Handle>(type, isRequired: s == SignatureTypeCode.RequiredModifier));
-                }
-                else
-                {
-                    return s;
-                }
-            }
-        }
-
-        private string FormatLocalConstant(MetadataReader reader, BlobHandle signature)
-        {
-            var sigReader = reader.GetBlobReader(signature);
-
-            var modifiers = new List<CustomModifier<Handle>>();
-
-            SignatureTypeCode typeCode = ReadConstantTypeCode(ref sigReader, modifiers);
-
-            Handle typeHandle = default(Handle);
-            object value;
-            if (IsPrimitiveType(typeCode))
-            {
-                if (typeCode == SignatureTypeCode.String)
-                {
-                    if (sigReader.RemainingBytes == 1)
-                    {
-                        value = (sigReader.ReadByte() == 0xff) ? "null" : "<bad metadata>";
-                    }
-                    else if (sigReader.RemainingBytes % 2 != 0)
-                    {
-                        value = "<bad metadata>";
-                    }
-                    else
-                    {
-                        value = "'" + sigReader.ReadUTF16(sigReader.RemainingBytes) + "'";
-                    }
-                }
-                else
-                {
-                    value = string.Format(CultureInfo.InvariantCulture, "{0}", sigReader.ReadConstant((ConstantTypeCode)typeCode));
-                }
-
-                if (sigReader.RemainingBytes > 0)
-                {
-                    typeHandle = sigReader.ReadTypeHandle();
-                }
-            }
-            else if (typeCode == SignatureTypeCode.TypeHandle)
-            {
-                typeHandle = sigReader.ReadTypeHandle();
-                value = (sigReader.RemainingBytes > 0) ? BitConverter.ToString(sigReader.ReadBytes(sigReader.RemainingBytes)) : "default";
-            }
-            else
-            {
-                value = (typeCode == SignatureTypeCode.Object) ? "null" : $"<bad type code: {typeCode}>";
-            }
-
-            return string.Format("{0} [{1}{2}]",
-                value,
-                FormatCustomModifiers(modifiers),
-                typeHandle.IsNil ? typeCode.ToString() : Token(() => typeHandle));
-        }
-
-        private string FormatCustomModifiers(IEnumerable<CustomModifier<Handle>> modifiers)
-        {
-            return string.Join(" ", modifiers.Select(m => (m.IsRequired ? "modreq" : "modopt") + "(" + Token(() => m.Type) + ")"));
-        }
-*/
-        private static bool IsPrimitiveType(SignatureTypeCode typeCode)
-        {
-            switch (typeCode)
-            {
-                case SignatureTypeCode.Boolean:
-                case SignatureTypeCode.Char:
-                case SignatureTypeCode.SByte:
-                case SignatureTypeCode.Byte:
-                case SignatureTypeCode.Int16:
-                case SignatureTypeCode.UInt16:
-                case SignatureTypeCode.Int32:
-                case SignatureTypeCode.UInt32:
-                case SignatureTypeCode.Int64:
-                case SignatureTypeCode.UInt64:
-                case SignatureTypeCode.Single:
-                case SignatureTypeCode.Double:
-                case SignatureTypeCode.String:
-                    return true;
-
-                default:
-                    return false;
-            }
-        }
-
-        private void WriteLocalImport()
-        {
-            AddHeader(
-                "Parent",
-                "Imports"
-            );
-
-            foreach (var handle in _reader.ImportScopes)
-            {
-                var entry = _reader.GetImportScope(handle);
-
-                _blobKinds[entry.Imports] = BlobKind.Imports;
-
-                AddRow(
-                    Token(() => entry.Parent),
-                    FormatImports(entry.Imports)
-               );
-            }
-
-            WriteTableName(TableIndex.ImportScope);
-        }
-
-        private void WriteCustomDebugInformation()
-        {
-            AddHeader(
-                "Parent",
-                "Value"
-            );
-
-            foreach (var handle in _reader.CustomDebugInformation)
-            {
-                var entry = _reader.GetCustomDebugInformation(handle);
-
-                AddRow(
-                    Token(() => entry.Parent),
-                    Literal(entry.Value, BlobKind.CustomDebugInformation)
-               );
-            }
-
-            WriteTableName(TableIndex.CustomDebugInformation);
-        }
-
-        public void VisualizeMethodBody(MethodBodyBlock body, MethodDefinitionHandle generationHandle, int generation)
-        {
-            VisualizeMethodBody(body, (MethodDefinitionHandle)GetAggregateHandle(generationHandle, generation));
-        }
-
-        public void VisualizeMethodBody(MethodBodyBlock body, MethodDefinitionHandle methodHandle, bool emitHeader = true)
-        {
-            StringBuilder builder = new StringBuilder();
-
-            // TODO: Inspect EncLog to find a containing type and display qualified name.
-            var method = GetMethod(methodHandle);
-            if (emitHeader)
-            {
-                builder.AppendFormat("Method {0} (0x{1:X8})", Literal(method.Name), MetadataTokens.GetToken(methodHandle));
-                builder.AppendLine();
-            }
-
-            // TODO: decode signature
-            if (!body.LocalSignature.IsNil)
-            {
-                var localSignature = GetLocalSignature(body.LocalSignature);
-                builder.AppendFormat("  Locals: {0}", Literal(localSignature, BlobKind.StandAloneSignature));
-                builder.AppendLine();
-            }
-
-            ILVisualizerAsTokens.Instance.DumpMethod(
-                builder,
-                body.MaxStack,
-                body.GetILContent(),
-                ImmutableArray.Create<ILVisualizer.LocalInfo>(),     // TODO
-                ImmutableArray.Create<ILVisualizer.HandlerSpan>());  // TOOD: ILVisualizer.GetHandlerSpans(body.ExceptionRegions)
-
-            builder.AppendLine();
-
-            _writer.Write(builder.ToString());
-        }
-
-        public void WriteLine(string line)
-        {
-            _writer.WriteLine(line);
-        }
-
-        private sealed class TokenTypeComparer : IComparer<EntityHandle>
-        {
-            public static readonly TokenTypeComparer Instance = new TokenTypeComparer();
-
-            public int Compare(EntityHandle x, EntityHandle y)
-            {
-                return x.Kind.CompareTo(y.Kind);
-            }
-        }
-    }
-}
-
-#endif

+ 0 - 57
Build/AtomicNETTest/AtomicEditor/MethodILExtensions.cs

@@ -1,57 +0,0 @@
-// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
-
-using System;
-using System.Collections.Immutable;
-using System.Linq;
-using System.Reflection.Metadata;
-using System.Text;
-
-namespace AtomicEditor
-{
-    public static class MethodILExtensions
-    {
-        public static unsafe string GetMethodIL(this ImmutableArray<byte> ilArray)
-        {
-            var result = new StringBuilder();
-            fixed (byte* ilPtr = ilArray.ToArray())
-            {
-                int offset = 0;
-                while (true)
-                {
-                    // skip padding:
-                    while (offset < ilArray.Length && ilArray[offset] == 0)
-                    {
-                        offset++;
-                    }
-
-                    if (offset == ilArray.Length)
-                    {
-                        break;
-                    }
-
-                    var reader = new BlobReader(ilPtr + offset, ilArray.Length - offset);
-                    var methodIL = MethodBodyBlock.Create(reader);
-
-                    if (methodIL == null)
-                    {
-                        result.AppendFormat("<invalid byte 0x{0:X2} at offset {1}>", ilArray[offset], offset);
-                        offset++;
-                    }
-                    else
-                    {
-                        ILVisualizerAsTokens.Instance.DumpMethod(
-                            result,
-                            methodIL.MaxStack,
-                            methodIL.GetILContent(),
-                            ImmutableArray.Create<ILVisualizer.LocalInfo>(),
-                            ImmutableArray.Create<ILVisualizer.HandlerSpan>());
-
-                        offset += methodIL.Size;
-                    }
-                }
-            }
-
-            return result.ToString();
-        }
-    }
-}

+ 549 - 0
Build/AtomicNETTest/AtomicEditor/MiniJSON.cs

@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2012 Calvin Rien
+ *
+ * Based on the JSON parser by Patrick van Bergen
+ * http://techblog.procurios.nl/k/618/news/view/14605/14863/How-do-I-write-my-own-parser-for-JSON.html
+ *
+ * Simplified it so that it doesn't throw exceptions
+ * and can be used in Unity iPhone with maximum code stripping.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace MiniJSON {
+    // Example usage:
+    //
+    //  using UnityEngine;
+    //  using System.Collections;
+    //  using System.Collections.Generic;
+    //  using MiniJSON;
+    //
+    //  public class MiniJSONTest : MonoBehaviour {
+    //      void Start () {
+    //          var jsonString = "{ \"array\": [1.44,2,3], " +
+    //                          "\"object\": {\"key1\":\"value1\", \"key2\":256}, " +
+    //                          "\"string\": \"The quick brown fox \\\"jumps\\\" over the lazy dog \", " +
+    //                          "\"unicode\": \"\\u3041 Men\u00fa sesi\u00f3n\", " +
+    //                          "\"int\": 65536, " +
+    //                          "\"float\": 3.1415926, " +
+    //                          "\"bool\": true, " +
+    //                          "\"null\": null }";
+    //
+    //          var dict = Json.Deserialize(jsonString) as Dictionary<string,object>;
+    //
+    //          Debug.Log("deserialized: " + dict.GetType());
+    //          Debug.Log("dict['array'][0]: " + ((List<object>) dict["array"])[0]);
+    //          Debug.Log("dict['string']: " + (string) dict["string"]);
+    //          Debug.Log("dict['float']: " + (double) dict["float"]); // floats come out as doubles
+    //          Debug.Log("dict['int']: " + (long) dict["int"]); // ints come out as longs
+    //          Debug.Log("dict['unicode']: " + (string) dict["unicode"]);
+    //
+    //          var str = Json.Serialize(dict);
+    //
+    //          Debug.Log("serialized: " + str);
+    //      }
+    //  }
+
+    /// <summary>
+    /// This class encodes and decodes JSON strings.
+    /// Spec. details, see http://www.json.org/
+    ///
+    /// JSON uses Arrays and Objects. These correspond here to the datatypes IList and IDictionary.
+    /// All numbers are parsed to doubles.
+    /// </summary>
+    public static class Json {
+        /// <summary>
+        /// Parses the string json into a value
+        /// </summary>
+        /// <param name="json">A JSON string.</param>
+        /// <returns>An List&lt;object&gt;, a Dictionary&lt;string, object&gt;, a double, an integer,a string, null, true, or false</returns>
+        public static object Deserialize(string json) {
+            // save the string for debug information
+            if (json == null) {
+                return null;
+            }
+
+            return Parser.Parse(json);
+        }
+
+        sealed class Parser : IDisposable {
+            const string WHITE_SPACE = " \t\n\r";
+            const string WORD_BREAK = " \t\n\r{}[],:\"";
+
+            enum TOKEN {
+                NONE,
+                CURLY_OPEN,
+                CURLY_CLOSE,
+                SQUARED_OPEN,
+                SQUARED_CLOSE,
+                COLON,
+                COMMA,
+                STRING,
+                NUMBER,
+                TRUE,
+                FALSE,
+                NULL
+            };
+
+            StringReader json;
+
+            Parser(string jsonString) {
+                json = new StringReader(jsonString);
+            }
+
+            public static object Parse(string jsonString) {
+                using (var instance = new Parser(jsonString)) {
+                    return instance.ParseValue();
+                }
+            }
+
+            public void Dispose() {
+                json.Dispose();
+                json = null;
+            }
+
+            Dictionary<string, object> ParseObject() {
+                Dictionary<string, object> table = new Dictionary<string, object>();
+
+                // ditch opening brace
+                json.Read();
+
+                // {
+                while (true) {
+                    switch (NextToken) {
+                    case TOKEN.NONE:
+                        return null;
+                    case TOKEN.COMMA:
+                        continue;
+                    case TOKEN.CURLY_CLOSE:
+                        return table;
+                    default:
+                        // name
+                        string name = ParseString();
+                        if (name == null) {
+                            return null;
+                        }
+
+                        // :
+                        if (NextToken != TOKEN.COLON) {
+                            return null;
+                        }
+                        // ditch the colon
+                        json.Read();
+
+                        // value
+                        table[name] = ParseValue();
+                        break;
+                    }
+                }
+            }
+
+            List<object> ParseArray() {
+                List<object> array = new List<object>();
+
+                // ditch opening bracket
+                json.Read();
+
+                // [
+                var parsing = true;
+                while (parsing) {
+                    TOKEN nextToken = NextToken;
+
+                    switch (nextToken) {
+                    case TOKEN.NONE:
+                        return null;
+                    case TOKEN.COMMA:
+                        continue;
+                    case TOKEN.SQUARED_CLOSE:
+                        parsing = false;
+                        break;
+                    default:
+                        object value = ParseByToken(nextToken);
+
+                        array.Add(value);
+                        break;
+                    }
+                }
+
+                return array;
+            }
+
+            object ParseValue() {
+                TOKEN nextToken = NextToken;
+                return ParseByToken(nextToken);
+            }
+
+            object ParseByToken(TOKEN token) {
+                switch (token) {
+                case TOKEN.STRING:
+                    return ParseString();
+                case TOKEN.NUMBER:
+                    return ParseNumber();
+                case TOKEN.CURLY_OPEN:
+                    return ParseObject();
+                case TOKEN.SQUARED_OPEN:
+                    return ParseArray();
+                case TOKEN.TRUE:
+                    return true;
+                case TOKEN.FALSE:
+                    return false;
+                case TOKEN.NULL:
+                    return null;
+                default:
+                    return null;
+                }
+            }
+
+            string ParseString() {
+                StringBuilder s = new StringBuilder();
+                char c;
+
+                // ditch opening quote
+                json.Read();
+
+                bool parsing = true;
+                while (parsing) {
+
+                    if (json.Peek() == -1) {
+                        parsing = false;
+                        break;
+                    }
+
+                    c = NextChar;
+                    switch (c) {
+                    case '"':
+                        parsing = false;
+                        break;
+                    case '\\':
+                        if (json.Peek() == -1) {
+                            parsing = false;
+                            break;
+                        }
+
+                        c = NextChar;
+                        switch (c) {
+                        case '"':
+                        case '\\':
+                        case '/':
+                            s.Append(c);
+                            break;
+                        case 'b':
+                            s.Append('\b');
+                            break;
+                        case 'f':
+                            s.Append('\f');
+                            break;
+                        case 'n':
+                            s.Append('\n');
+                            break;
+                        case 'r':
+                            s.Append('\r');
+                            break;
+                        case 't':
+                            s.Append('\t');
+                            break;
+                        case 'u':
+                            var hex = new StringBuilder();
+
+                            for (int i=0; i< 4; i++) {
+                                hex.Append(NextChar);
+                            }
+
+                            s.Append((char) Convert.ToInt32(hex.ToString(), 16));
+                            break;
+                        }
+                        break;
+                    default:
+                        s.Append(c);
+                        break;
+                    }
+                }
+
+                return s.ToString();
+            }
+
+            object ParseNumber() {
+                string number = NextWord;
+
+                if (number.IndexOf('.') == -1) {
+                    long parsedInt;
+                    Int64.TryParse(number, out parsedInt);
+                    return parsedInt;
+                }
+
+                double parsedDouble;
+                Double.TryParse(number, out parsedDouble);
+                return parsedDouble;
+            }
+
+            void EatWhitespace() {
+                while (WHITE_SPACE.IndexOf(PeekChar) != -1) {
+                    json.Read();
+
+                    if (json.Peek() == -1) {
+                        break;
+                    }
+                }
+            }
+
+            char PeekChar {
+                get {
+                    return Convert.ToChar(json.Peek());
+                }
+            }
+
+            char NextChar {
+                get {
+                    return Convert.ToChar(json.Read());
+                }
+            }
+
+            string NextWord {
+                get {
+                    StringBuilder word = new StringBuilder();
+
+                    while (WORD_BREAK.IndexOf(PeekChar) == -1) {
+                        word.Append(NextChar);
+
+                        if (json.Peek() == -1) {
+                            break;
+                        }
+                    }
+
+                    return word.ToString();
+                }
+            }
+
+            TOKEN NextToken {
+                get {
+                    EatWhitespace();
+
+                    if (json.Peek() == -1) {
+                        return TOKEN.NONE;
+                    }
+
+                    char c = PeekChar;
+                    switch (c) {
+                    case '{':
+                        return TOKEN.CURLY_OPEN;
+                    case '}':
+                        json.Read();
+                        return TOKEN.CURLY_CLOSE;
+                    case '[':
+                        return TOKEN.SQUARED_OPEN;
+                    case ']':
+                        json.Read();
+                        return TOKEN.SQUARED_CLOSE;
+                    case ',':
+                        json.Read();
+                        return TOKEN.COMMA;
+                    case '"':
+                        return TOKEN.STRING;
+                    case ':':
+                        return TOKEN.COLON;
+                    case '0':
+                    case '1':
+                    case '2':
+                    case '3':
+                    case '4':
+                    case '5':
+                    case '6':
+                    case '7':
+                    case '8':
+                    case '9':
+                    case '-':
+                        return TOKEN.NUMBER;
+                    }
+
+                    string word = NextWord;
+
+                    switch (word) {
+                    case "false":
+                        return TOKEN.FALSE;
+                    case "true":
+                        return TOKEN.TRUE;
+                    case "null":
+                        return TOKEN.NULL;
+                    }
+
+                    return TOKEN.NONE;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Converts a IDictionary / IList object or a simple type (string, int, etc.) into a JSON string
+        /// </summary>
+        /// <param name="json">A Dictionary&lt;string, object&gt; / List&lt;object&gt;</param>
+        /// <returns>A JSON encoded string, or null if object 'json' is not serializable</returns>
+        public static string Serialize(object obj) {
+            return Serializer.Serialize(obj);
+        }
+
+        sealed class Serializer {
+            StringBuilder builder;
+
+            Serializer() {
+                builder = new StringBuilder();
+            }
+
+            public static string Serialize(object obj) {
+                var instance = new Serializer();
+
+                instance.SerializeValue(obj);
+
+                return instance.builder.ToString();
+            }
+
+            void SerializeValue(object value) {
+                IList asList;
+                IDictionary asDict;
+                string asStr;
+
+                if (value == null) {
+                    builder.Append("null");
+                }
+                else if ((asStr = value as string) != null) {
+                    SerializeString(asStr);
+                }
+                else if (value is bool) {
+                    builder.Append(value.ToString().ToLower());
+                }
+                else if ((asList = value as IList) != null) {
+                    SerializeArray(asList);
+                }
+                else if ((asDict = value as IDictionary) != null) {
+                    SerializeObject(asDict);
+                }
+                else if (value is char) {
+                    SerializeString(value.ToString());
+                }
+                else {
+                    SerializeOther(value);
+                }
+            }
+
+            void SerializeObject(IDictionary obj) {
+                bool first = true;
+
+                builder.Append('{');
+
+                foreach (object e in obj.Keys) {
+                    if (!first) {
+                        builder.Append(',');
+                    }
+
+                    SerializeString(e.ToString());
+                    builder.Append(':');
+
+                    SerializeValue(obj[e]);
+
+                    first = false;
+                }
+
+                builder.Append('}');
+            }
+
+            void SerializeArray(IList anArray) {
+                builder.Append('[');
+
+                bool first = true;
+
+                foreach (object obj in anArray) {
+                    if (!first) {
+                        builder.Append(',');
+                    }
+
+                    SerializeValue(obj);
+
+                    first = false;
+                }
+
+                builder.Append(']');
+            }
+
+            void SerializeString(string str) {
+                builder.Append('\"');
+
+                char[] charArray = str.ToCharArray();
+                foreach (var c in charArray) {
+                    switch (c) {
+                    case '"':
+                        builder.Append("\\\"");
+                        break;
+                    case '\\':
+                        builder.Append("\\\\");
+                        break;
+                    case '\b':
+                        builder.Append("\\b");
+                        break;
+                    case '\f':
+                        builder.Append("\\f");
+                        break;
+                    case '\n':
+                        builder.Append("\\n");
+                        break;
+                    case '\r':
+                        builder.Append("\\r");
+                        break;
+                    case '\t':
+                        builder.Append("\\t");
+                        break;
+                    default:
+                        int codepoint = Convert.ToInt32(c);
+                        if ((codepoint >= 32) && (codepoint <= 126)) {
+                            builder.Append(c);
+                        }
+                        else {
+                            builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0'));
+                        }
+                        break;
+                    }
+                }
+
+                builder.Append('\"');
+            }
+
+            void SerializeOther(object value) {
+                if (value is float
+                    || value is int
+                    || value is uint
+                    || value is long
+                    || value is double
+                    || value is sbyte
+                    || value is byte
+                    || value is short
+                    || value is ushort
+                    || value is ulong
+                    || value is decimal) {
+                    builder.Append(value.ToString());
+                }
+                else {
+                    SerializeString(value.ToString());
+                }
+            }
+        }
+    }
+}

+ 1 - 1
Source/AtomicNET/NETCore/NETCore.cpp

@@ -387,7 +387,7 @@ bool NETCore::Initialize(const String &coreCLRFilesAbsPath, String& errorMsg)
     st = sCreateDelegate(hostHandle_,
                     domainId_,
                     "AtomicEditor",
-                    "AtomicEditor.AssemblyInspector",
+                    "AtomicEditor.AtomicEditor",
                     "InspectAssembly",
                     (void**) &inspectAssembly);