Browse Source

update to latest code mappings

pull/219/head
Eusebiu Marcu 14 years ago
parent
commit
207af4eced
  1. 35
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 133
      ICSharpCode.Decompiler/CodeMappings.cs
  3. 34
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  4. 9
      ICSharpCode.Decompiler/PlainTextOutput.cs

35
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.Decompiler.Ast
IncludeTypeParameterDefinitions = 2 IncludeTypeParameterDefinitions = 2
} }
public class AstBuilder : ICodeMappings public class AstBuilder : BaseCodeMappings
{ {
DecompilerContext context; DecompilerContext context;
CompilationUnit astCompileUnit = new CompilationUnit(); CompilationUnit astCompileUnit = new CompilationUnit();
@ -46,6 +46,8 @@ namespace ICSharpCode.Decompiler.Ast
this.DecompileMethodBodies = true; this.DecompileMethodBodies = true;
this.LocalVariables = new ConcurrentDictionary<int, IEnumerable<ILVariable>>(); this.LocalVariables = new ConcurrentDictionary<int, IEnumerable<ILVariable>>();
this.CodeMappings = new Dictionary<int, List<MemberMapping>>();
this.DecompiledMemberReferences = new Dictionary<int, MemberReference>();
} }
public static bool MemberIsHidden(MemberReference member, DecompilerSettings settings) public static bool MemberIsHidden(MemberReference member, DecompilerSettings settings)
@ -196,10 +198,6 @@ namespace ICSharpCode.Decompiler.Ast
/// <returns>TypeDeclaration or DelegateDeclaration.</returns> /// <returns>TypeDeclaration or DelegateDeclaration.</returns>
public AttributedNode CreateType(TypeDefinition typeDef) public AttributedNode CreateType(TypeDefinition typeDef)
{ {
// create CSharp code mappings - used for debugger
if (this.CodeMappings == null)
this.CodeMappings = new Tuple<string, List<MemberMapping>>(typeDef.FullName, new List<MemberMapping>());
// create type // create type
TypeDefinition oldCurrentType = context.CurrentType; TypeDefinition oldCurrentType = context.CurrentType;
context.CurrentType = typeDef; context.CurrentType = typeDef;
@ -627,7 +625,8 @@ namespace ICSharpCode.Decompiler.Ast
AttributedNode CreateMethod(MethodDefinition methodDef) AttributedNode CreateMethod(MethodDefinition methodDef)
{ {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings); CreateCodeMappings(methodDef.MetadataToken.ToInt32(), methodDef);
MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings[methodDef.MetadataToken.ToInt32()]);
MethodDeclaration astMethod = new MethodDeclaration().WithAnnotation(methodMapping); MethodDeclaration astMethod = new MethodDeclaration().WithAnnotation(methodMapping);
astMethod.AddAnnotation(methodDef); astMethod.AddAnnotation(methodDef);
@ -715,7 +714,8 @@ namespace ICSharpCode.Decompiler.Ast
ConstructorDeclaration CreateConstructor(MethodDefinition methodDef) ConstructorDeclaration CreateConstructor(MethodDefinition methodDef)
{ {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings); CreateCodeMappings(methodDef.MetadataToken.ToInt32(), methodDef);
MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings[methodDef.MetadataToken.ToInt32()]);
ConstructorDeclaration astMethod = new ConstructorDeclaration(); ConstructorDeclaration astMethod = new ConstructorDeclaration();
astMethod.AddAnnotation(methodDef); astMethod.AddAnnotation(methodDef);
@ -776,9 +776,11 @@ namespace ICSharpCode.Decompiler.Ast
} }
astProp.Name = CleanName(propDef.Name); astProp.Name = CleanName(propDef.Name);
astProp.ReturnType = ConvertType(propDef.PropertyType, propDef); astProp.ReturnType = ConvertType(propDef.PropertyType, propDef);
if (propDef.GetMethod != null) { if (propDef.GetMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = propDef.GetMethod.CreateCodeMapping(this.CodeMappings); CreateCodeMappings(propDef.GetMethod.MetadataToken.ToInt32(), propDef);
MemberMapping methodMapping = propDef.GetMethod.CreateCodeMapping(this.CodeMappings[propDef.GetMethod.MetadataToken.ToInt32()], propDef);
astProp.Getter = new Accessor(); astProp.Getter = new Accessor();
astProp.Getter.Body = CreateMethodBody(propDef.GetMethod); astProp.Getter.Body = CreateMethodBody(propDef.GetMethod);
@ -792,7 +794,8 @@ namespace ICSharpCode.Decompiler.Ast
} }
if (propDef.SetMethod != null) { if (propDef.SetMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = propDef.SetMethod.CreateCodeMapping(this.CodeMappings); CreateCodeMappings(propDef.SetMethod.MetadataToken.ToInt32(), propDef);
MemberMapping methodMapping = propDef.SetMethod.CreateCodeMapping(this.CodeMappings[propDef.SetMethod.MetadataToken.ToInt32()], propDef);
astProp.Setter = new Accessor(); astProp.Setter = new Accessor();
astProp.Setter.Body = CreateMethodBody(propDef.SetMethod); astProp.Setter.Body = CreateMethodBody(propDef.SetMethod);
@ -853,9 +856,11 @@ namespace ICSharpCode.Decompiler.Ast
astEvent.Modifiers = ConvertModifiers(eventDef.AddMethod); astEvent.Modifiers = ConvertModifiers(eventDef.AddMethod);
else else
astEvent.PrivateImplementationType = ConvertType(eventDef.AddMethod.Overrides.First().DeclaringType); astEvent.PrivateImplementationType = ConvertType(eventDef.AddMethod.Overrides.First().DeclaringType);
if (eventDef.AddMethod != null) { if (eventDef.AddMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = eventDef.AddMethod.CreateCodeMapping(this.CodeMappings); CreateCodeMappings(eventDef.AddMethod.MetadataToken.ToInt32(), eventDef);
MemberMapping methodMapping = eventDef.AddMethod.CreateCodeMapping(this.CodeMappings[eventDef.AddMethod.MetadataToken.ToInt32()], eventDef);
astEvent.AddAccessor = new Accessor { astEvent.AddAccessor = new Accessor {
Body = CreateMethodBody(eventDef.AddMethod) Body = CreateMethodBody(eventDef.AddMethod)
@ -866,7 +871,8 @@ namespace ICSharpCode.Decompiler.Ast
} }
if (eventDef.RemoveMethod != null) { if (eventDef.RemoveMethod != null) {
// Create mapping - used in debugger // Create mapping - used in debugger
MemberMapping methodMapping = eventDef.RemoveMethod.CreateCodeMapping(this.CodeMappings); CreateCodeMappings(eventDef.RemoveMethod.MetadataToken.ToInt32(), eventDef);
MemberMapping methodMapping = eventDef.RemoveMethod.CreateCodeMapping(this.CodeMappings[eventDef.RemoveMethod.MetadataToken.ToInt32()], eventDef);
astEvent.RemoveAccessor = new Accessor { astEvent.RemoveAccessor = new Accessor {
Body = CreateMethodBody(eventDef.RemoveMethod) Body = CreateMethodBody(eventDef.RemoveMethod)
@ -895,6 +901,8 @@ namespace ICSharpCode.Decompiler.Ast
FieldDeclaration CreateField(FieldDefinition fieldDef) FieldDeclaration CreateField(FieldDefinition fieldDef)
{ {
this.DecompiledMemberReferences.Add(fieldDef.MetadataToken.ToInt32(), fieldDef);
FieldDeclaration astField = new FieldDeclaration(); FieldDeclaration astField = new FieldDeclaration();
astField.AddAnnotation(fieldDef); astField.AddAnnotation(fieldDef);
VariableInitializer initializer = new VariableInitializer(CleanName(fieldDef.Name)); VariableInitializer initializer = new VariableInitializer(CleanName(fieldDef.Name));
@ -1451,11 +1459,6 @@ namespace ICSharpCode.Decompiler.Ast
&& TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType)); && TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType));
} }
/// <summary>
/// <inheritdoc/>
/// </summary>
public Tuple<string, List<MemberMapping>> CodeMappings { get; private set; }
/// <summary> /// <summary>
/// Gets the local variables for the current decompiled type, method, etc. /// Gets the local variables for the current decompiled type, method, etc.
/// <remarks>The key is the metadata token.</remarks> /// <remarks>The key is the metadata token.</remarks>

133
ICSharpCode.Decompiler/CodeMappings.cs

@ -35,14 +35,36 @@ namespace ICSharpCode.Decompiler
} }
/// <summary> /// <summary>
/// Interface for decompliler classes : AstBuilder & ReflectionDisassembler. /// Base class for decompliler classes : AstBuilder & ReflectionDisassembler.
/// </summary> /// </summary>
public interface ICodeMappings public abstract class BaseCodeMappings
{ {
/// <summary> /// <summary>
/// Gets the code mappings. /// Gets the code mappings.
/// <remarks>Key is the metadata token.</remarks>
/// </summary> /// </summary>
Tuple<string, List<MemberMapping>> CodeMappings { get; } public Dictionary<int, List<MemberMapping>> CodeMappings { get; protected set; }
/// <summary>
/// Gets the MembeReference that is decompiled (a MethodDefinition, PropertyDefinition etc.)
/// <remarks>Key is the metadata token.</remarks>
/// </summary>
public Dictionary<int, MemberReference> DecompiledMemberReferences { get; protected set; }
/// <summary>
/// Create data in the CodeMappings and DecompiledMemberReferences.
/// </summary>
/// <param name="token">Token of the current method.</param>
/// <param name="member">Current member (MethodDefinition, PropertyDefinition, EventDefinition).</param>
/// <remarks>The token is used in CodeMappings; member (and its token) is used in DecompiledMemberReferences.</remarks>
protected virtual void CreateCodeMappings(int token, MemberReference member)
{
this.CodeMappings.Add(token, new List<MemberMapping>());
int t = member.MetadataToken.ToInt32();
if (!this.DecompiledMemberReferences.ContainsKey(t))
this.DecompiledMemberReferences.Add(t, member);
}
} }
/// <summary> /// <summary>
@ -112,9 +134,9 @@ namespace ICSharpCode.Decompiler
public MemberReference MemberReference { get; internal set; } public MemberReference MemberReference { get; internal set; }
/// <summary> /// <summary>
/// Metadata token of the method. /// Metadata token of the member.
/// </summary> /// </summary>
public uint MetadataToken { get; internal set; } public int MetadataToken { get; internal set; }
/// <summary> /// <summary>
/// Gets or sets the code size for the member mapping. /// Gets or sets the code size for the member mapping.
@ -148,15 +170,17 @@ namespace ICSharpCode.Decompiler
/// Code mappings helper class. /// Code mappings helper class.
/// </summary> /// </summary>
public static class CodeMappings public static class CodeMappings
{ {
/// <summary> /// <summary>
/// Create code mapping for a method. /// Create code mapping for a method.
/// </summary> /// </summary>
/// <param name="method">Method to create the mapping for.</param> /// <param name="method">Method to create the mapping for.</param>
/// <param name="sourceCodeMappings">Source code mapping storage.</param> /// <param name="codeMappings">Source code mapping storage.</param>
/// <param name="actualMemberReference">The actual member reference.</param>
internal static MemberMapping CreateCodeMapping( internal static MemberMapping CreateCodeMapping(
this MethodDefinition member, this MethodDefinition member,
Tuple<string, List<MemberMapping>> codeMappings) List<MemberMapping> codeMappings,
MemberReference actualMemberReference = null)
{ {
if (member == null || !member.HasBody) if (member == null || !member.HasBody)
return null; return null;
@ -166,17 +190,16 @@ namespace ICSharpCode.Decompiler
// create IL/CSharp code mappings - used in debugger // create IL/CSharp code mappings - used in debugger
MemberMapping currentMemberMapping = null; MemberMapping currentMemberMapping = null;
if (codeMappings.Item1 == member.DeclaringType.FullName) {
var mapping = codeMappings.Item2; if (codeMappings.Find(map => map.MetadataToken == member.MetadataToken.ToInt32()) == null) {
if (mapping.Find(map => (int)map.MetadataToken == member.MetadataToken.ToInt32()) == null) { currentMemberMapping = new MemberMapping() {
currentMemberMapping = new MemberMapping() { MetadataToken = member.MetadataToken.ToInt32(),
MetadataToken = (uint)member.MetadataToken.ToInt32(), MemberCodeMappings = new List<SourceCodeMapping>(),
MemberReference = member.DeclaringType.Resolve(), MemberReference = actualMemberReference ?? member,
MemberCodeMappings = new List<SourceCodeMapping>(), CodeSize = member.Body.CodeSize
CodeSize = member.Body.CodeSize };
};
mapping.Add(currentMemberMapping); codeMappings.Add(currentMemberMapping);
}
} }
return currentMemberMapping; return currentMemberMapping;
@ -186,31 +209,19 @@ namespace ICSharpCode.Decompiler
/// Gets source code mapping and metadata token based on type name and line number. /// Gets source code mapping and metadata token based on type name and line number.
/// </summary> /// </summary>
/// <param name="codeMappings">Code mappings storage.</param> /// <param name="codeMappings">Code mappings storage.</param>
/// <param name="typeName">Type name.</param> /// <param name="typeName">Member reference name.</param>
/// <param name="lineNumber">Line number.</param> /// <param name="lineNumber">Line number.</param>
/// <param name="metadataToken">Metadata token.</param> /// <param name="metadataToken">Metadata token.</param>
/// <returns></returns> /// <returns></returns>
public static SourceCodeMapping GetInstructionByTypeAndLine( public static SourceCodeMapping GetInstructionByLineNumber(
this Tuple<string, List<MemberMapping>> codeMappings, this List<MemberMapping> codeMappings,
string memberReferenceName,
int lineNumber, int lineNumber,
out uint metadataToken) out int metadataToken)
{ {
if (codeMappings == null) if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!"); throw new ArgumentException("CodeMappings storage must be valid!");
if (codeMappings.Item1 != memberReferenceName) { foreach (var maping in codeMappings) {
metadataToken = 0;
return null;
}
if (lineNumber <= 0) {
metadataToken = 0;
return null;
}
var methodMappings = codeMappings.Item2;
foreach (var maping in methodMappings) {
var map = maping.MemberCodeMappings.Find(m => m.SourceCodeLine == lineNumber); var map = maping.MemberCodeMappings.Find(m => m.SourceCodeLine == lineNumber);
if (map != null) { if (map != null) {
metadataToken = maping.MetadataToken; metadataToken = maping.MetadataToken;
@ -226,40 +237,32 @@ namespace ICSharpCode.Decompiler
/// Gets a mapping given a type, a token and an IL offset. /// Gets a mapping given a type, a token and an IL offset.
/// </summary> /// </summary>
/// <param name="codeMappings">Code mappings storage.</param> /// <param name="codeMappings">Code mappings storage.</param>
/// <param name="typeName">Type name.</param>
/// <param name="token">Token.</param> /// <param name="token">Token.</param>
/// <param name="ilOffset">IL offset.</param> /// <param name="ilOffset">IL offset.</param>
/// <param name="isMatch">True, if perfect match.</param> /// <param name="isMatch">True, if perfect match.</param>
/// <returns>A code mapping.</returns> /// <returns>A code mapping.</returns>
public static SourceCodeMapping GetInstructionByTypeTokenAndOffset( public static SourceCodeMapping GetInstructionByTokenAndOffset(
this Tuple<string, List<MemberMapping>> codeMappings, this List<MemberMapping> codeMappings,
string memberReferenceName, int token,
uint token, int ilOffset,
int ilOffset, out bool isMatch) out bool isMatch)
{ {
isMatch = false; isMatch = false;
memberReferenceName = memberReferenceName.Replace("+", "/");
if (codeMappings == null) if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!"); throw new ArgumentNullException("CodeMappings storage must be valid!");
if (codeMappings.Item1 != memberReferenceName) { var maping = codeMappings.Find(m => m.MetadataToken == token);
return null;
}
var methodMappings = codeMappings.Item2;
var maping = methodMappings.Find(m => m.MetadataToken == token);
if (maping == null) { if (maping == null)
return null; return null;
}
// try find an exact match // try find an exact match
var map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To); var map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To);
if (map == null) { if (map == null) {
// get the immediate next one // get the immediate next one
map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From >= ilOffset); map = maping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From > ilOffset);
isMatch = false; isMatch = false;
if (map == null) if (map == null)
map = maping.MemberCodeMappings.LastOrDefault(); // get the last map = maping.MemberCodeMappings.LastOrDefault(); // get the last
@ -275,38 +278,32 @@ namespace ICSharpCode.Decompiler
/// Gets the source code and type name from metadata token and offset. /// Gets the source code and type name from metadata token and offset.
/// </summary> /// </summary>
/// <param name="codeMappings">Code mappings storage.</param> /// <param name="codeMappings">Code mappings storage.</param>
/// <param name="typeName">Current type name.</param>
/// <param name="token">Metadata token.</param> /// <param name="token">Metadata token.</param>
/// <param name="ilOffset">IL offset.</param> /// <param name="ilOffset">IL offset.</param>
/// <param name="typeName">Type definition.</param> /// <param name="typeName">Type definition.</param>
/// <param name="line">Line number.</param> /// <param name="line">Line number.</param>
/// <remarks>It is possible to exist to different types from different assemblies with the same metadata token.</remarks> /// <remarks>It is possible to exist to different types from different assemblies with the same metadata token.</remarks>
public static bool GetSourceCodeFromMetadataTokenAndOffset( public static bool GetInstructionByTokenAndOffset(
this Tuple<string, List<MemberMapping>> codeMappings, this List<MemberMapping> codeMappings,
string memberReferenceName, int token,
uint token,
int ilOffset, int ilOffset,
out MemberReference type, out MemberReference member,
out int line) out int line)
{ {
type = null; member = null;
line = 0; line = 0;
if (codeMappings == null) if (codeMappings == null)
throw new ArgumentNullException("CodeMappings storage must be valid!"); throw new ArgumentException("CodeMappings storage must be valid!");
memberReferenceName = memberReferenceName.Replace("+", "/");
if (codeMappings.Item1 != memberReferenceName)
return false;
var mapping = codeMappings.Item2.Find(m => m.MetadataToken == token); var mapping = codeMappings.Find(m => m.MetadataToken == token);
if (mapping == null) if (mapping == null)
return false; return false;
var codeMapping = mapping.MemberCodeMappings.Find( var codeMapping = mapping.MemberCodeMappings.Find(
cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1); cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1);
if (codeMapping == null) { if (codeMapping == null) {
codeMapping = mapping.MemberCodeMappings.Find(cm => (cm.ILInstructionOffset.From >= ilOffset)); codeMapping = mapping.MemberCodeMappings.Find(cm => cm.ILInstructionOffset.From > ilOffset);
if (codeMapping == null) { if (codeMapping == null) {
codeMapping = mapping.MemberCodeMappings.LastOrDefault(); codeMapping = mapping.MemberCodeMappings.LastOrDefault();
if (codeMapping == null) if (codeMapping == null)
@ -314,7 +311,7 @@ namespace ICSharpCode.Decompiler
} }
} }
type = mapping.MemberReference; member = mapping.MemberReference;
line = codeMapping.SourceCodeLine; line = codeMapping.SourceCodeLine;
return true; return true;
} }

34
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -28,13 +28,14 @@ namespace ICSharpCode.Decompiler.Disassembler
/// <summary> /// <summary>
/// Disassembles type and member definitions. /// Disassembles type and member definitions.
/// </summary> /// </summary>
public sealed class ReflectionDisassembler : ICodeMappings public sealed class ReflectionDisassembler : BaseCodeMappings
{ {
ITextOutput output; ITextOutput output;
CancellationToken cancellationToken; CancellationToken cancellationToken;
bool detectControlStructure; bool detectControlStructure;
bool isInType; // whether we are currently disassembling a whole type (-> defaultCollapsed for foldings) bool isInType; // whether we are currently disassembling a whole type (-> defaultCollapsed for foldings)
MethodBodyDisassembler methodBodyDisassembler; MethodBodyDisassembler methodBodyDisassembler;
MemberReference currentMember;
public ReflectionDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken) public ReflectionDisassembler(ITextOutput output, bool detectControlStructure, CancellationToken cancellationToken)
{ {
@ -44,6 +45,9 @@ namespace ICSharpCode.Decompiler.Disassembler
this.cancellationToken = cancellationToken; this.cancellationToken = cancellationToken;
this.detectControlStructure = detectControlStructure; this.detectControlStructure = detectControlStructure;
this.methodBodyDisassembler = new MethodBodyDisassembler(output, detectControlStructure, cancellationToken); this.methodBodyDisassembler = new MethodBodyDisassembler(output, detectControlStructure, cancellationToken);
this.CodeMappings = new Dictionary<int, List<MemberMapping>>();
this.DecompiledMemberReferences = new Dictionary<int, MemberReference>();
} }
#region Disassemble Method #region Disassemble Method
@ -94,6 +98,9 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleMethod(MethodDefinition method) public void DisassembleMethod(MethodDefinition method)
{ {
// set current member
currentMember = method;
// write method header // write method header
output.WriteDefinition(".method ", method); output.WriteDefinition(".method ", method);
DisassembleMethodInternal(method); DisassembleMethodInternal(method);
@ -118,7 +125,6 @@ namespace ICSharpCode.Decompiler.Disassembler
//call convention //call convention
WriteEnum(method.CallingConvention & (MethodCallingConvention)0x1f, callingConvention); WriteEnum(method.CallingConvention & (MethodCallingConvention)0x1f, callingConvention);
//return type //return type
method.ReturnType.WriteTo(output); method.ReturnType.WriteTo(output);
output.Write(' '); output.Write(' ');
@ -149,7 +155,9 @@ namespace ICSharpCode.Decompiler.Disassembler
if (method.HasBody) { if (method.HasBody) {
// create IL code mappings - used in debugger // create IL code mappings - used in debugger
MemberMapping methodMapping = method.CreateCodeMapping(this.CodeMappings); CreateCodeMappings(method.MetadataToken.ToInt32(), currentMember);
MemberMapping methodMapping = method.CreateCodeMapping(this.CodeMappings[method.MetadataToken.ToInt32()], currentMember);
methodBodyDisassembler.Disassemble(method.Body, methodMapping); methodBodyDisassembler.Disassemble(method.Body, methodMapping);
} }
@ -194,6 +202,9 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleField(FieldDefinition field) public void DisassembleField(FieldDefinition field)
{ {
// create mappings for decompiled fields only
this.DecompiledMemberReferences.Add(field.MetadataToken.ToInt32(), field);
output.WriteDefinition(".field ", field); output.WriteDefinition(".field ", field);
WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility); WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility);
WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | FieldAttributes.HasDefault), fieldAttributes); WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | FieldAttributes.HasDefault), fieldAttributes);
@ -223,6 +234,9 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleProperty(PropertyDefinition property) public void DisassembleProperty(PropertyDefinition property)
{ {
// set current member
currentMember = property;
output.WriteDefinition(".property ", property); output.WriteDefinition(".property ", property);
WriteFlags(property.Attributes, propertyAttributes); WriteFlags(property.Attributes, propertyAttributes);
property.PropertyType.WriteTo(output); property.PropertyType.WriteTo(output);
@ -232,6 +246,7 @@ namespace ICSharpCode.Decompiler.Disassembler
WriteAttributes(property.CustomAttributes); WriteAttributes(property.CustomAttributes);
WriteNestedMethod(".get", property.GetMethod); WriteNestedMethod(".get", property.GetMethod);
WriteNestedMethod(".set", property.SetMethod); WriteNestedMethod(".set", property.SetMethod);
foreach (var method in property.OtherMethods) { foreach (var method in property.OtherMethods) {
WriteNestedMethod(".method", method); WriteNestedMethod(".method", method);
} }
@ -263,6 +278,9 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleEvent(EventDefinition ev) public void DisassembleEvent(EventDefinition ev)
{ {
// set current member
currentMember = ev;
output.WriteDefinition(".event ", ev); output.WriteDefinition(".event ", ev);
WriteFlags(ev.Attributes, eventAttributes); WriteFlags(ev.Attributes, eventAttributes);
ev.EventType.WriteTo(output); ev.EventType.WriteTo(output);
@ -316,10 +334,6 @@ namespace ICSharpCode.Decompiler.Disassembler
public void DisassembleType(TypeDefinition type) public void DisassembleType(TypeDefinition type)
{ {
// create IL code mappings - used for debugger
if (this.CodeMappings == null)
this.CodeMappings = new Tuple<string, List<MemberMapping>>(type.FullName, new List<MemberMapping>());
// start writing IL // start writing IL
output.WriteDefinition(".class ", type); output.WriteDefinition(".class ", type);
@ -604,11 +618,5 @@ namespace ICSharpCode.Decompiler.Disassembler
WriteAttributes(asm.CustomAttributes); WriteAttributes(asm.CustomAttributes);
CloseBlock(); CloseBlock();
} }
/// <inheritdoc/>
public Tuple<string, List<MemberMapping>> CodeMappings {
get;
private set;
}
} }
} }

9
ICSharpCode.Decompiler/PlainTextOutput.cs

@ -26,22 +26,23 @@ namespace ICSharpCode.Decompiler
readonly TextWriter writer; readonly TextWriter writer;
int indent; int indent;
bool needsIndent; bool needsIndent;
int lineNumber = 1;
public PlainTextOutput(TextWriter writer) public PlainTextOutput(TextWriter writer)
{ {
if (writer == null) if (writer == null)
throw new ArgumentNullException("writer"); throw new ArgumentNullException("writer");
this.writer = writer; this.writer = writer;
CurrentLine = 1;
} }
public PlainTextOutput() public PlainTextOutput()
{ {
this.writer = new StringWriter(); this.writer = new StringWriter();
CurrentLine = 1;
} }
public int CurrentLine { get; set; } public int CurrentLine {
get { return lineNumber; }
}
public override string ToString() public override string ToString()
{ {
@ -82,9 +83,9 @@ namespace ICSharpCode.Decompiler
public void WriteLine() public void WriteLine()
{ {
lineNumber++;
writer.WriteLine(); writer.WriteLine();
needsIndent = true; needsIndent = true;
++CurrentLine;
} }
public void WriteDefinition(string text, object definition) public void WriteDefinition(string text, object definition)

Loading…
Cancel
Save