diff --git a/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs b/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs index daf5b30a0..f8f09b7a3 100644 --- a/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs +++ b/Debugger/ILSpy.Debugger/Services/Debugger/WindowsDebugger.cs @@ -48,7 +48,7 @@ namespace ILSpy.Debugger.Services //DynamicTreeDebuggerRow currentTooltipRow; //Expression currentTooltipExpression; - private ConcurrentDictionary> CodeMappingsStorage { + private ConcurrentDictionary> CodeMappingsStorage { get { return CodeMappings.GetStorage(DebugData.Language); } @@ -302,7 +302,7 @@ namespace ILSpy.Debugger.Services var mapping = val.Find(m => m.MetadataToken == token); - return mapping.MethodCodeMappings.FirstOrDefault(s => s.ILInstructionOffset.From == instruction.ILInstructionOffset.From); + return mapping.MemberCodeMappings.FirstOrDefault(s => s.ILInstructionOffset.From == instruction.ILInstructionOffset.From); } StackFrame GetStackFrame() diff --git a/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/ICSharpCode.Decompiler/Ast/AstBuilder.cs index f9a4b6881..9da9f6c84 100644 --- a/ICSharpCode.Decompiler/Ast/AstBuilder.cs +++ b/ICSharpCode.Decompiler/Ast/AstBuilder.cs @@ -167,7 +167,7 @@ namespace ICSharpCode.Decompiler.Ast { // create CSharp code mappings - used for debugger if (!CSharpCodeMapping.SourceCodeMappings.ContainsKey(typeDef.FullName)) { - CSharpCodeMapping.SourceCodeMappings.TryAdd(typeDef.FullName, new List()); + CSharpCodeMapping.SourceCodeMappings.TryAdd(typeDef.FullName, new List()); } else { CSharpCodeMapping.SourceCodeMappings[typeDef.FullName].Clear(); } @@ -596,12 +596,10 @@ namespace ICSharpCode.Decompiler.Ast MethodDeclaration CreateMethod(MethodDefinition methodDef) { // Create mapping - used in debugger - MethodMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); + MemberMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); MethodDeclaration astMethod = new MethodDeclaration(); astMethod.AddAnnotation(methodDef); - if (methodMapping != null) - astMethod.AddAnnotation(methodMapping); astMethod.ReturnType = ConvertType(methodDef.ReturnType, methodDef.MethodReturnType); astMethod.Name = CleanName(methodDef.Name); astMethod.TypeParameters.AddRange(MakeTypeParameters(methodDef.GenericParameters)); @@ -615,6 +613,7 @@ namespace ICSharpCode.Decompiler.Ast astMethod.Body = AstMethodBodyBuilder.CreateMethodBody(methodDef, context); } ConvertAttributes(astMethod, methodDef); + astMethod.WithAnnotation(methodMapping); return astMethod; } @@ -659,12 +658,10 @@ namespace ICSharpCode.Decompiler.Ast ConstructorDeclaration CreateConstructor(MethodDefinition methodDef) { // Create mapping - used in debugger - MethodMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); + MemberMapping methodMapping = methodDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); ConstructorDeclaration astMethod = new ConstructorDeclaration(); astMethod.AddAnnotation(methodDef); - if (methodMapping != null) - astMethod.AddAnnotation(methodMapping); astMethod.Modifiers = ConvertModifiers(methodDef); if (methodDef.IsStatic) { // don't show visibility for static ctors @@ -674,11 +671,15 @@ namespace ICSharpCode.Decompiler.Ast astMethod.Parameters.AddRange(MakeParameters(methodDef.Parameters)); astMethod.Body = AstMethodBodyBuilder.CreateMethodBody(methodDef, context); ConvertAttributes(astMethod, methodDef); + astMethod.WithAnnotation(methodMapping); return astMethod; } IndexerDeclaration ConvertPropertyToIndexer(PropertyDeclaration astProp, PropertyDefinition propDef) { + // Create mapping - used in debugger + MemberMapping memberMapping = propDef.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); + var astIndexer = new IndexerDeclaration(); astIndexer.Name = astProp.Name; astIndexer.CopyAnnotationsFrom(astProp); @@ -689,6 +690,9 @@ namespace ICSharpCode.Decompiler.Ast astIndexer.Getter = astProp.Getter.Detach(); astIndexer.Setter = astProp.Setter.Detach(); astIndexer.Parameters.AddRange(MakeParameters(propDef.Parameters)); + + propDef.WithAnnotation(memberMapping); + return astIndexer; } @@ -723,7 +727,7 @@ namespace ICSharpCode.Decompiler.Ast astProp.ReturnType = ConvertType(propDef.PropertyType, propDef); if (propDef.GetMethod != null) { // Create mapping - used in debugger - MethodMapping methodMapping = propDef.GetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); + MemberMapping methodMapping = propDef.GetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); astProp.Getter = new Accessor { Body = AstMethodBodyBuilder.CreateMethodBody(propDef.GetMethod, context) @@ -734,12 +738,11 @@ namespace ICSharpCode.Decompiler.Ast if ((getterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask)) astProp.Getter.Modifiers = getterModifiers & Modifiers.VisibilityMask; - if (methodMapping != null) - astProp.Getter.AddAnnotation(methodMapping); + astProp.Getter.WithAnnotation(methodMapping); } if (propDef.SetMethod != null) { // Create mapping - used in debugger - MethodMapping methodMapping = propDef.SetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); + MemberMapping methodMapping = propDef.SetMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); astProp.Setter = new Accessor { Body = AstMethodBodyBuilder.CreateMethodBody(propDef.SetMethod, context) @@ -751,8 +754,7 @@ namespace ICSharpCode.Decompiler.Ast if ((setterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask)) astProp.Setter.Modifiers = setterModifiers & Modifiers.VisibilityMask; - if (methodMapping != null) - astProp.Setter.AddAnnotation(methodMapping); + astProp.Setter.WithAnnotation(methodMapping); } ConvertCustomAttributes(astProp, propDef); return astProp; @@ -782,27 +784,25 @@ namespace ICSharpCode.Decompiler.Ast astEvent.PrivateImplementationType = ConvertType(eventDef.AddMethod.Overrides.First().DeclaringType); if (eventDef.AddMethod != null) { // Create mapping - used in debugger - MethodMapping methodMapping = eventDef.AddMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); + MemberMapping methodMapping = eventDef.AddMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); astEvent.AddAccessor = new Accessor { Body = AstMethodBodyBuilder.CreateMethodBody(eventDef.AddMethod, context) }.WithAnnotation(eventDef.AddMethod); ConvertAttributes(astEvent.AddAccessor, eventDef.AddMethod); - if (methodMapping != null) - astEvent.AddAccessor.AddAnnotation(methodMapping); + astEvent.AddAccessor.WithAnnotation(methodMapping); } if (eventDef.RemoveMethod != null) { // Create mapping - used in debugger - MethodMapping methodMapping = eventDef.RemoveMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); + MemberMapping methodMapping = eventDef.RemoveMethod.CreateCodeMapping(CSharpCodeMapping.SourceCodeMappings); astEvent.RemoveAccessor = new Accessor { Body = AstMethodBodyBuilder.CreateMethodBody(eventDef.RemoveMethod, context) }.WithAnnotation(eventDef.RemoveMethod); ConvertAttributes(astEvent.RemoveAccessor, eventDef.RemoveMethod); - if (methodMapping != null) - astEvent.RemoveAccessor.AddAnnotation(methodMapping); + astEvent.RemoveAccessor.WithAnnotation(methodMapping); } return astEvent; } diff --git a/ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs b/ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs index 51f50e072..fc90fad73 100644 --- a/ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs +++ b/ICSharpCode.Decompiler/Ast/CSharpCodeMapping.cs @@ -14,12 +14,12 @@ namespace ICSharpCode.Decompiler.Ast /// public static class CSharpCodeMapping { - static ConcurrentDictionary> codeMappings = new ConcurrentDictionary>(); + static ConcurrentDictionary> codeMappings = new ConcurrentDictionary>(); /// /// Stores the source codes mappings: CSharp <-> editor lines /// - public static ConcurrentDictionary> SourceCodeMappings { + public static ConcurrentDictionary> SourceCodeMappings { get { return codeMappings; } set { codeMappings = value; } } diff --git a/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs b/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs index 0db9aec88..aa89f8dce 100644 --- a/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs +++ b/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs @@ -129,11 +129,11 @@ namespace ICSharpCode.Decompiler.Ast // find the ancestor that has method mapping as annotation if (node.Ancestors != null && node.Ancestors.Count() > 0) { - var n = node.Ancestors.FirstOrDefault(a => a.Annotation() != null); + var n = node.Ancestors.FirstOrDefault(a => a.Annotation() != null); if (n != default(AstType)) { - MethodMapping mapping = n.Annotation(); + MemberMapping mapping = n.Annotation(); foreach (var range in ranges) { - mapping.MethodCodeMappings.Add(new SourceCodeMapping { + mapping.MemberCodeMappings.Add(new SourceCodeMapping { ILInstructionOffset = range, SourceCodeLine = output.CurrentLine }); diff --git a/ICSharpCode.Decompiler/CodeMappings.cs b/ICSharpCode.Decompiler/CodeMappings.cs index 0b8572f79..58b9768b6 100644 --- a/ICSharpCode.Decompiler/CodeMappings.cs +++ b/ICSharpCode.Decompiler/CodeMappings.cs @@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler /// /// Stores the method information and its source code mappings. /// - public sealed class MethodMapping + public sealed class MemberMapping { /// /// Gets or sets the type of the mapping. @@ -62,36 +62,34 @@ namespace ICSharpCode.Decompiler /// /// Gets or sets the source code mappings. /// - public List MethodCodeMappings { get; set; } + public List MemberCodeMappings { get; set; } public int[] ToArray() { - int[] result = new int[MethodCodeMappings.Count * 2]; + int[] result = new int[MemberCodeMappings.Count * 2]; int i = 0; - foreach (var element in MethodCodeMappings) { - result[i] = element.ILInstructionOffset.From; - result[i+1] = element.ILInstructionOffset.To; + foreach (var element in MemberCodeMappings) { + result[i] = element.ILInstructionOffset.From; + result[i+1] = element.ILInstructionOffset.To; i+=2; } - //result[MethodCodeMappings.Count] = MethodCodeMappings[MethodCodeMappings.Count - 1].ILInstructionOffset.To; - return result; } } public static class CodeMappings { - public static ConcurrentDictionary> GetStorage(DecompiledLanguages language) + public static ConcurrentDictionary> GetStorage(DecompiledLanguages language) { - ConcurrentDictionary> storage = null; + ConcurrentDictionary> storage = null; switch (language) { case DecompiledLanguages.IL: - storage = ILCodeMapping.SourceCodeMappings; + storage = ILCodeMapping.SourceCodeMappings; break; case DecompiledLanguages.CSharp: - storage = CSharpCodeMapping.SourceCodeMappings; + storage = CSharpCodeMapping.SourceCodeMappings; break; default: throw new System.Exception("Invalid value for DecompiledLanguages"); @@ -105,25 +103,25 @@ namespace ICSharpCode.Decompiler /// /// Method to create the mapping for. /// Source code mapping storage. - public static MethodMapping CreateCodeMapping( - this MethodDefinition method, - ConcurrentDictionary> sourceCodeMappings) + public static MemberMapping CreateCodeMapping( + this MemberReference member, + ConcurrentDictionary> codeMappings) { // create IL/CSharp code mappings - used in debugger - MethodMapping currentMethodMapping = null; - if (sourceCodeMappings.ContainsKey(method.DeclaringType.FullName)) { - var mapping = sourceCodeMappings[method.DeclaringType.FullName]; - if (mapping.Find(map => (int)map.MetadataToken == method.MetadataToken.ToInt32()) == null) { - currentMethodMapping = new MethodMapping() { - MetadataToken = (uint)method.MetadataToken.ToInt32(), - Type = method.DeclaringType, - MethodCodeMappings = new List() + MemberMapping currentMemberMapping = null; + if (codeMappings.ContainsKey(member.DeclaringType.FullName)) { + var mapping = codeMappings[member.DeclaringType.FullName]; + if (mapping.Find(map => (int)map.MetadataToken == member.MetadataToken.ToInt32()) == null) { + currentMemberMapping = new MemberMapping() { + MetadataToken = (uint)member.MetadataToken.ToInt32(), + Type = member.DeclaringType.Resolve(), + MemberCodeMappings = new List() }; - mapping.Add(currentMethodMapping); + mapping.Add(currentMemberMapping); } } - return currentMethodMapping; + return currentMemberMapping; } /// @@ -135,7 +133,7 @@ namespace ICSharpCode.Decompiler /// Metadata token. /// public static SourceCodeMapping GetInstructionByTypeAndLine( - this ConcurrentDictionary> codeMappings, + this ConcurrentDictionary> codeMappings, string typeName, int lineNumber, out uint metadataToken) @@ -152,7 +150,7 @@ namespace ICSharpCode.Decompiler var methodMappings = codeMappings[typeName]; foreach (var maping in methodMappings) { - var map = maping.MethodCodeMappings.Find(m => m.SourceCodeLine == lineNumber); + var map = maping.MemberCodeMappings.Find(m => m.SourceCodeLine == lineNumber); if (map != null) { metadataToken = maping.MetadataToken; return map; @@ -172,7 +170,7 @@ namespace ICSharpCode.Decompiler /// Type definition. /// Line number. public static bool GetSourceCodeFromMetadataTokenAndOffset( - this ConcurrentDictionary> codeMappings, + this ConcurrentDictionary> codeMappings, uint token, int ilOffset, out TypeDefinition type, @@ -186,17 +184,17 @@ namespace ICSharpCode.Decompiler if (mapping == null) continue; - var codeMapping = mapping.MethodCodeMappings.Find( + var codeMapping = mapping.MemberCodeMappings.Find( cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1); if (codeMapping == null) { - codeMapping = mapping.MethodCodeMappings.Find(cm => (cm.ILInstructionOffset.From >= ilOffset)); + codeMapping = mapping.MemberCodeMappings.Find(cm => (cm.ILInstructionOffset.From >= ilOffset)); if (codeMapping == null) { - codeMapping = mapping.MethodCodeMappings.LastOrDefault(); + codeMapping = mapping.MemberCodeMappings.LastOrDefault(); if (codeMapping == null) continue; } } - + type = mapping.Type; line = codeMapping.SourceCodeLine; diff --git a/ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs b/ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs index f08d6bb92..de78bcbb5 100644 --- a/ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs +++ b/ICSharpCode.Decompiler/Disassembler/ILCodeMapping.cs @@ -12,12 +12,12 @@ namespace ICSharpCode.Decompiler.Disassembler /// public static class ILCodeMapping { - static ConcurrentDictionary> codeMappings = new ConcurrentDictionary>(); + static ConcurrentDictionary> codeMappings = new ConcurrentDictionary>(); /// /// Stores the source codes mappings: IL <-> editor lines /// - public static ConcurrentDictionary> SourceCodeMappings { + public static ConcurrentDictionary> SourceCodeMappings { get { return codeMappings; } set { codeMappings = value; } } diff --git a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index 6361f122e..88056ee71 100644 --- a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -50,7 +50,7 @@ namespace ICSharpCode.Decompiler.Disassembler public void Disassemble(MethodBody body) { // create IL code mappings - used in debugger - MethodMapping methodMapping = body.Method.CreateCodeMapping(ILCodeMapping.SourceCodeMappings); + MemberMapping methodMapping = body.Method.CreateCodeMapping(ILCodeMapping.SourceCodeMappings); // start writing IL code MethodDefinition method = body.Method; @@ -84,7 +84,7 @@ namespace ICSharpCode.Decompiler.Disassembler } else { foreach (var inst in method.Body.Instructions) { // add IL code mappings - methodMapping.MethodCodeMappings.Add( + methodMapping.MemberCodeMappings.Add( new SourceCodeMapping() { SourceCodeLine = output.CurrentLine, ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset } @@ -146,13 +146,13 @@ namespace ICSharpCode.Decompiler.Disassembler output.Indent(); } - void WriteStructureBody(ILStructure s, ref Instruction inst, MethodMapping currentMethodMapping, int codeSize) + void WriteStructureBody(ILStructure s, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize) { int childIndex = 0; while (inst != null && inst.Offset < s.EndOffset) { // add IL code mappings - used in debugger if (currentMethodMapping != null) { - currentMethodMapping.MethodCodeMappings.Add( + currentMethodMapping.MemberCodeMappings.Add( new SourceCodeMapping() { SourceCodeLine = output.CurrentLine, ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset } diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index ccc5cfa18..2f6207361 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -314,7 +314,7 @@ namespace ICSharpCode.Decompiler.Disassembler { // create IL code mappings - used for debugger if (!ILCodeMapping.SourceCodeMappings.ContainsKey(type.FullName)) { - ILCodeMapping.SourceCodeMappings.TryAdd(type.FullName, new List()); + ILCodeMapping.SourceCodeMappings.TryAdd(type.FullName, new List()); } else { ILCodeMapping.SourceCodeMappings[type.FullName].Clear(); }