diff options
author | Mike Krüger <mkrueger@xamarin.com> | 2014-01-02 15:33:32 +0400 |
---|---|---|
committer | Mike Krüger <mkrueger@xamarin.com> | 2014-01-02 15:33:32 +0400 |
commit | 063a25397b46a84b52f5033052e352b9b7946cb3 (patch) | |
tree | 60a85525872fd2d5a0daba74805d6270c1e23222 /main/contrib | |
parent | d9837ac8da7f69da2389578348aa8354d0a5b1c1 (diff) |
[Decompiler] Updated decompiler / track nrefactory API changes.
Diffstat (limited to 'main/contrib')
20 files changed, 189 insertions, 371 deletions
diff --git a/main/contrib/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/main/contrib/ICSharpCode.Decompiler/Ast/AstBuilder.cs index a9131951fb..b488cf4840 100644 --- a/main/contrib/ICSharpCode.Decompiler/Ast/AstBuilder.cs +++ b/main/contrib/ICSharpCode.Decompiler/Ast/AstBuilder.cs @@ -52,7 +52,7 @@ namespace ICSharpCode.Decompiler.Ast public class AstBuilder { DecompilerContext context; - SyntaxTree astCompileUnit = new SyntaxTree(); + SyntaxTree syntaxTree = new SyntaxTree(); Dictionary<string, NamespaceDeclaration> astNamespaces = new Dictionary<string, NamespaceDeclaration>(); bool transformationsHaveRun; @@ -70,7 +70,7 @@ namespace ICSharpCode.Decompiler.Ast if (method != null) { if (method.IsGetter || method.IsSetter || method.IsAddOn || method.IsRemoveOn) return true; - if (settings.HideNonPublicMembers && !(method.IsPublic || method.IsFamily)) + if (settings.AnonymousMethods && method.HasGeneratedName() && method.IsCompilerGenerated()) return true; } @@ -155,15 +155,15 @@ namespace ICSharpCode.Decompiler.Ast public void RunTransformations(Predicate<IAstTransform> transformAbortCondition) { - TransformationPipeline.RunTransformationsUntil(astCompileUnit, transformAbortCondition, context); + TransformationPipeline.RunTransformationsUntil(syntaxTree, transformAbortCondition, context); transformationsHaveRun = true; } /// <summary> /// Gets the abstract source tree. /// </summary> - public SyntaxTree CompilationUnit { - get { return astCompileUnit; } + public SyntaxTree SyntaxTree { + get { return syntaxTree; } } /// <summary> @@ -175,16 +175,16 @@ namespace ICSharpCode.Decompiler.Ast if (!transformationsHaveRun) RunTransformations(); - astCompileUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); - var outputFormatter = new TextOutputFormatter(output) { FoldBraces = context.Settings.FoldBraces }; + syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); + var outputFormatter = new TextTokenWriter(output) { FoldBraces = context.Settings.FoldBraces }; var formattingPolicy = context.Settings.CSharpFormattingOptions; - astCompileUnit.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy)); + syntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy)); } public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false) { if (assemblyDefinition.Name.Version != null) { - astCompileUnit.AddChild( + syntaxTree.AddChild( new AttributeSection { AttributeTarget = "assembly", Attributes = { @@ -201,10 +201,10 @@ namespace ICSharpCode.Decompiler.Ast }, EntityDeclaration.AttributeRole); } - ConvertCustomAttributes(astCompileUnit, assemblyDefinition, "assembly"); - ConvertSecurityAttributes(astCompileUnit, assemblyDefinition, "assembly"); - ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, "module"); - AddTypeForwarderAttributes(astCompileUnit, assemblyDefinition.MainModule, "assembly"); + ConvertCustomAttributes(syntaxTree, assemblyDefinition, "assembly"); + ConvertSecurityAttributes(syntaxTree, assemblyDefinition, "assembly"); + ConvertCustomAttributes(syntaxTree, assemblyDefinition.MainModule, "module"); + AddTypeForwarderAttributes(syntaxTree, assemblyDefinition.MainModule, "assembly"); if (!onlyAssemblyLevel) { foreach (TypeDefinition typeDef in assemblyDefinition.MainModule.Types) { @@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.Ast } else { // Create the namespace NamespaceDeclaration astNamespace = new NamespaceDeclaration { Name = name }; - astCompileUnit.AddChild(astNamespace, SyntaxTree.MemberRole); + syntaxTree.Members.Add(astNamespace); astNamespaces[name] = astNamespace; return astNamespace; } @@ -264,31 +264,31 @@ namespace ICSharpCode.Decompiler.Ast var astType = CreateType(typeDef); NamespaceDeclaration astNS = GetCodeNamespace(typeDef.Namespace); if (astNS != null) { - astNS.AddChild(astType, NamespaceDeclaration.MemberRole); + astNS.Members.Add(astType); } else { - astCompileUnit.AddChild(astType, SyntaxTree.MemberRole); + syntaxTree.Members.Add(astType); } } public void AddMethod(MethodDefinition method) { AstNode node = method.IsConstructor ? (AstNode)CreateConstructor(method) : CreateMethod(method); - astCompileUnit.AddChild(node, SyntaxTree.MemberRole); + syntaxTree.Members.Add(node); } public void AddProperty(PropertyDefinition property) { - astCompileUnit.AddChild(CreateProperty(property), SyntaxTree.MemberRole); + syntaxTree.Members.Add(CreateProperty(property)); } public void AddField(FieldDefinition field) { - astCompileUnit.AddChild(CreateField(field), SyntaxTree.MemberRole); + syntaxTree.Members.Add(CreateField(field)); } public void AddEvent(EventDefinition ev) { - astCompileUnit.AddChild(CreateEvent(ev), SyntaxTree.MemberRole); + syntaxTree.Members.Add(CreateEvent(ev)); } /// <summary> diff --git a/main/contrib/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs b/main/contrib/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs index 3437af546b..fae41f6860 100644 --- a/main/contrib/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs +++ b/main/contrib/ICSharpCode.Decompiler/Ast/AstMethodBodyBuilder.cs @@ -126,7 +126,7 @@ namespace ICSharpCode.Decompiler.Ast astBlock.Statements.InsertBefore(insertionPoint, newVarDecl); } - astBlock.AddAnnotation(new MemberMapping(methodDef) { LocalVariables = localVariables }); + astBlock.AddAnnotation(new MethodDebugSymbols(methodDef) { LocalVariables = localVariables.ToList() }); return astBlock; } @@ -147,7 +147,7 @@ namespace ICSharpCode.Decompiler.Ast if (node is ILLabel) { yield return new Ast.LabelStatement { Label = ((ILLabel)node).Name }; } else if (node is ILExpression) { - List<ILRange> ilRanges = ILRange.OrderAndJoint(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges)); + List<ILRange> ilRanges = ILRange.OrderAndJoin(node.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges)); AstNode codeExpr = TransformExpression((ILExpression)node); if (codeExpr != null) { codeExpr = codeExpr.WithAnnotation(ilRanges); @@ -253,7 +253,7 @@ namespace ICSharpCode.Decompiler.Ast Expression astExpr = node as Expression; // get IL ranges - used in debugger - List<ILRange> ilRanges = ILRange.OrderAndJoint(expr.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges)); + List<ILRange> ilRanges = ILRange.OrderAndJoin(expr.GetSelfAndChildrenRecursive<ILExpression>().SelectMany(e => e.ILRanges)); AstNode result; if (astExpr != null) diff --git a/main/contrib/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs b/main/contrib/ICSharpCode.Decompiler/Ast/TextTokenWriter.cs index 5e3cef9947..45ed21bd69 100644 --- a/main/contrib/ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs +++ b/main/contrib/ICSharpCode.Decompiler/Ast/TextTokenWriter.cs @@ -27,7 +27,7 @@ using Mono.Cecil; namespace ICSharpCode.Decompiler.Ast { - public class TextOutputFormatter : IOutputFormatter + public class TextTokenWriter : TokenWriter { readonly ITextOutput output; readonly Stack<AstNode> nodeStack = new Stack<AstNode>(); @@ -36,39 +36,41 @@ namespace ICSharpCode.Decompiler.Ast bool firstUsingDeclaration; bool lastUsingDeclaration; + TextLocation? lastEndOfLine; + public bool FoldBraces = false; - public TextOutputFormatter(ITextOutput output) + public TextTokenWriter(ITextOutput output) { if (output == null) throw new ArgumentNullException("output"); this.output = output; } - public void WriteIdentifier(string identifier) + public override void WriteIdentifier(Identifier identifier) { var definition = GetCurrentDefinition(); if (definition != null) { - output.WriteDefinition(identifier, definition, false); + output.WriteDefinition(identifier.Name, definition, false); return; } object memberRef = GetCurrentMemberReference(); if (memberRef != null) { - output.WriteReference(identifier, memberRef); + output.WriteReference(identifier.Name, memberRef); return; } definition = GetCurrentLocalDefinition(); if (definition != null) { - output.WriteDefinition(identifier, definition); + output.WriteDefinition(identifier.Name, definition); return; } memberRef = GetCurrentLocalReference(); if (memberRef != null) { - output.WriteReference(identifier, memberRef, true); + output.WriteReference(identifier.Name, memberRef, true); return; } @@ -77,7 +79,7 @@ namespace ICSharpCode.Decompiler.Ast firstUsingDeclaration = false; } - output.Write(identifier); + output.Write(identifier.Name); } MemberReference GetCurrentMemberReference() @@ -150,22 +152,20 @@ namespace ICSharpCode.Decompiler.Ast return null; var node = nodeStack.Peek(); + if (node is Identifier) + node = node.Parent; if (IsDefinition(node)) return node.Annotation<MemberReference>(); - var fieldDef = node.Parent.Annotation<FieldDefinition>(); - if (fieldDef != null) - return node.Parent.Annotation<MemberReference>(); - return null; } - public void WriteKeyword(string keyword) + public override void WriteKeyword(Role role, string keyword) { output.Write(keyword); } - public void WriteToken(string token) + public override void WriteToken(Role role, string token) { // Attach member reference to token only if there's no identifier in the current node. MemberReference memberRef = GetCurrentMemberReference(); @@ -176,7 +176,7 @@ namespace ICSharpCode.Decompiler.Ast output.Write(token); } - public void Space() + public override void Space() { output.Write(' '); } @@ -203,26 +203,27 @@ namespace ICSharpCode.Decompiler.Ast braceLevelWithinType--; } - public void Indent() + public override void Indent() { output.Indent(); } - public void Unindent() + public override void Unindent() { output.Unindent(); } - public void NewLine() + public override void NewLine() { if (lastUsingDeclaration) { output.MarkFoldEnd(); lastUsingDeclaration = false; } + lastEndOfLine = output.Location; output.WriteLine(); } - public void WriteComment(CommentType commentType, string content) + public override void WriteComment(CommentType commentType, string content) { switch (commentType) { case CommentType.SingleLine: @@ -254,7 +255,7 @@ namespace ICSharpCode.Decompiler.Ast } } - public void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument) + public override void WritePreProcessorDirective(PreProcessorDirectiveType type, string argument) { // pre-processor directive must start on its own line output.Write('#'); @@ -266,11 +267,23 @@ namespace ICSharpCode.Decompiler.Ast output.WriteLine(); } + public override void WritePrimitiveValue(object value, string literalValue = null) + { + + } + + public override void WritePrimitiveType(string type) + { + output.Write(type); + if (type == "new") { + output.Write("()"); + } + } + Stack<TextLocation> startLocations = new Stack<TextLocation>(); - MemberMapping currentMemberMapping; - Stack<MemberMapping> parentMemberMappings = new Stack<MemberMapping>(); + Stack<MethodDebugSymbols> symbolsStack = new Stack<MethodDebugSymbols>(); - public void StartNode(AstNode node) + public override void StartNode(AstNode node) { if (nodeStack.Count == 0) { if (IsUsingDeclaration(node)) { @@ -286,11 +299,10 @@ namespace ICSharpCode.Decompiler.Ast if (node is EntityDeclaration && node.Annotation<MemberReference>() != null && node.GetChildByRole(Roles.Identifier).IsNull) output.WriteDefinition("", node.Annotation<MemberReference>(), false); - - MemberMapping mapping = node.Annotation<MemberMapping>(); - if (mapping != null) { - parentMemberMappings.Push(currentMemberMapping); - currentMemberMapping = mapping; + + if (node.Annotation<MethodDebugSymbols>() != null) { + symbolsStack.Push(node.Annotation<MethodDebugSymbols>()); + symbolsStack.Peek().StartLocation = startLocations.Peek(); } } @@ -299,7 +311,7 @@ namespace ICSharpCode.Decompiler.Ast return node is UsingDeclaration || node is UsingAliasDeclaration; } - public void EndNode(AstNode node) + public override void EndNode(AstNode node) { if (nodeStack.Pop() != node) throw new InvalidOperationException(); @@ -307,32 +319,29 @@ namespace ICSharpCode.Decompiler.Ast var startLocation = startLocations.Pop(); // code mappings - if (currentMemberMapping != null) { - var ranges = node.Annotation<List<ILRange>>(); - if (ranges != null && ranges.Count > 0) { - // add all ranges - foreach (var range in ranges) { - currentMemberMapping.MemberCodeMappings.Add( - new SourceCodeMapping { - ILInstructionOffset = range, - StartLocation = startLocation, - EndLocation = output.Location, - MemberMapping = currentMemberMapping - }); - } - } + var ranges = node.Annotation<List<ILRange>>(); + if (symbolsStack.Count > 0 && ranges != null && ranges.Count > 0) { + // Ignore the newline which was printed at the end of the statement + TextLocation endLocation = (node is Statement) ? (lastEndOfLine ?? output.Location) : output.Location; + symbolsStack.Peek().SequencePoints.Add( + new SequencePoint() { + ILRanges = ILRange.OrderAndJoin(ranges).ToArray(), + StartLocation = startLocation, + EndLocation = endLocation + }); } - - if (node.Annotation<MemberMapping>() != null) { - output.AddDebuggerMemberMapping(currentMemberMapping); - currentMemberMapping = parentMemberMappings.Pop(); + if (node.Annotation<MethodDebugSymbols>() != null) { + symbolsStack.Peek().EndLocation = output.Location; + output.AddDebugSymbols(symbolsStack.Pop()); } } private static bool IsDefinition(AstNode node) { - return node is EntityDeclaration; + return node is EntityDeclaration + || (node is VariableInitializer && node.Parent is FieldDeclaration) + || node is FixedVariableInitializer; } } } diff --git a/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs b/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs index bb188d33ab..5c3784fa4c 100644 --- a/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs +++ b/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/IntroduceUsingDeclarations.cs @@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) { string oldNamespace = currentNamespace; - foreach (var ident in namespaceDeclaration.Identifiers) { + foreach (string ident in namespaceDeclaration.Identifiers) { currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident); transform.declaredNamespaces.Add(currentNamespace); } @@ -154,7 +154,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms public override object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data) { string oldNamespace = currentNamespace; - foreach (var ident in namespaceDeclaration.Identifiers) { + foreach (string ident in namespaceDeclaration.Identifiers) { currentNamespace = NamespaceDeclaration.BuildQualifiedName(currentNamespace, ident); } base.VisitNamespaceDeclaration(namespaceDeclaration, data); diff --git a/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs b/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs index fc02a15d72..22d1afe627 100644 --- a/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs +++ b/main/contrib/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs @@ -897,6 +897,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms #region Automatic Events static readonly Accessor automaticEventPatternV4 = new Accessor { + Attributes = { new Repeat(new AnyNode()) }, Body = new BlockStatement { new VariableDeclarationStatement { Type = new AnyNode("type"), Variables = { new AnyNode() } }, new VariableDeclarationStatement { Type = new Backreference("type"), Variables = { new AnyNode() } }, @@ -965,6 +966,10 @@ namespace ICSharpCode.Decompiler.Ast.Transforms return null; EventDeclaration ed = new EventDeclaration(); ev.Attributes.MoveTo(ed.Attributes); + foreach (var attr in ev.AddAccessor.Attributes) { + attr.AttributeTarget = "method"; + ed.Attributes.Add(attr.Detach()); + } ed.ReturnType = ev.ReturnType.Detach(); ed.Modifiers = ev.Modifiers; ed.Variables.Add(new VariableInitializer(ev.Name)); diff --git a/main/contrib/ICSharpCode.Decompiler/CodeMappings.cs b/main/contrib/ICSharpCode.Decompiler/CodeMappings.cs index 3fef8970b4..b2dcab8621 100644 --- a/main/contrib/ICSharpCode.Decompiler/CodeMappings.cs +++ b/main/contrib/ICSharpCode.Decompiler/CodeMappings.cs @@ -17,240 +17,41 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using ICSharpCode.Decompiler.Ast; -using ICSharpCode.Decompiler.Disassembler; using ICSharpCode.Decompiler.ILAst; using ICSharpCode.NRefactory; -using ICSharpCode.NRefactory.CSharp; using Mono.Cecil; namespace ICSharpCode.Decompiler { - /// <summary> - /// Maps the source code to IL. - /// </summary> - public sealed class SourceCodeMapping + /// <summary> Maps method's source code to IL </summary> + public class MethodDebugSymbols { - /// <summary> - /// Gets or sets the start location of the instruction. - /// </summary> + public MethodDefinition CecilMethod { get; set; } + public List<ILVariable> LocalVariables { get; set; } + public List<SequencePoint> SequencePoints { get; set; } public TextLocation StartLocation { get; set; } - - /// <summary> - /// Gets or sets the end location of the instruction. - /// </summary> public TextLocation EndLocation { get; set; } - /// <summary> - /// Gets or sets IL Range offset for the source code line. E.g.: 13-19 <-> 135. - /// </summary> - public ILRange ILInstructionOffset { get; set; } - - /// <summary> - /// Gets or sets the member mapping this source code mapping belongs to. - /// </summary> - public MemberMapping MemberMapping { get; set; } - - /// <summary> - /// Retrieves the array that contains the IL range and the missing gaps between ranges. - /// </summary> - /// <returns>The array representation of the step aranges.</returns> - public int[] ToArray(bool isMatch) - { - var currentList = new List<ILRange>(); - - // add list for the current source code line - currentList.AddRange(ILRange.OrderAndJoint(MemberMapping.MemberCodeMappings - .FindAll(m => m.StartLocation.Line == this.StartLocation.Line) - .ConvertAll<ILRange>(m => m.ILInstructionOffset))); - - if (!isMatch) { - // add inverted - currentList.AddRange(MemberMapping.InvertedList); - } else { - // if the current list contains the last mapping, add also the last gap - var lastInverted = MemberMapping.InvertedList.LastOrDefault(); - if (lastInverted != null && lastInverted.From == currentList[currentList.Count - 1].To) - currentList.Add(lastInverted); - } - - // set the output - var resultList = new List<int>(); - foreach (var element in ILRange.OrderAndJoint(currentList)) { - resultList.Add(element.From); - resultList.Add(element.To); - } - - return resultList.ToArray(); - } - } - - /// <summary> - /// Stores the member information and its source code mappings. - /// </summary> - public sealed class MemberMapping - { - IEnumerable<ILRange> invertedList; - - internal MemberMapping() - { - } - - public MemberMapping(MethodDefinition method) - { - this.MetadataToken = method.MetadataToken.ToInt32(); - this.MemberCodeMappings = new List<SourceCodeMapping>(); - this.MemberReference = method; - this.CodeSize = method.Body.CodeSize; - } - - /// <summary> - /// Gets or sets the type of the mapping. - /// </summary> - public MemberReference MemberReference { get; internal set; } - - /// <summary> - /// Metadata token of the member. - /// </summary> - public int MetadataToken { get; internal set; } - - /// <summary> - /// Gets or sets the code size for the member mapping. - /// </summary> - public int CodeSize { get; internal set; } - - /// <summary> - /// Gets or sets the source code mappings. - /// </summary> - public List<SourceCodeMapping> MemberCodeMappings { get; internal set; } - - /// <summary> - /// Gets or sets the local variables. - /// </summary> - public IEnumerable<ILVariable> LocalVariables { get; internal set; } - - /// <summary> - /// Gets the inverted IL Ranges.<br/> - /// E.g.: for (0-9, 11-14, 14-18, 21-25) => (9-11,18-21). - /// </summary> - /// <returns>IL Range inverted list.</returns> - public IEnumerable<ILRange> InvertedList + public MethodDebugSymbols(MethodDefinition methodDef) { - get { - if (invertedList == null) { - var list = MemberCodeMappings.ConvertAll<ILRange>( - s => new ILRange { From = s.ILInstructionOffset.From, To = s.ILInstructionOffset.To }); - invertedList = ILRange.OrderAndJoint(ILRange.Invert(list, CodeSize)); - } - return invertedList; - } + this.CecilMethod = methodDef; + this.LocalVariables = new List<ILVariable>(); + this.SequencePoints = new List<SequencePoint>(); } } - /// <summary> - /// Code mappings helper class. - /// </summary> - public static class CodeMappings + public class SequencePoint { - /// <summary> - /// Gets source code mapping and metadata token based on type name and line number. - /// </summary> - /// <param name="codeMappings">Code mappings storage.</param> - /// <param name="typeName">Member reference name.</param> - /// <param name="lineNumber">Line number.</param> - /// <param name="metadataToken">Metadata token.</param> - /// <returns></returns> - public static SourceCodeMapping GetInstructionByLineNumber( - this MemberMapping codeMapping, - int lineNumber, - out int metadataToken) - { - if (codeMapping == null) - throw new ArgumentException("CodeMappings storage must be valid!"); - - var map = codeMapping.MemberCodeMappings.Find(m => m.StartLocation.Line == lineNumber); - if (map != null) { - metadataToken = codeMapping.MetadataToken; - return map; - } - - metadataToken = 0; - return null; - } - - /// <summary> - /// Gets a mapping given a type, a token and an IL offset. - /// </summary> - /// <param name="codeMappings">Code mappings storage.</param> - /// <param name="token">Token.</param> - /// <param name="ilOffset">IL offset.</param> - /// <param name="isMatch">True, if perfect match.</param> - /// <returns>A code mapping.</returns> - public static SourceCodeMapping GetInstructionByTokenAndOffset( - this MemberMapping codeMapping, - int ilOffset, - out bool isMatch) - { - isMatch = false; - - if (codeMapping == null) - throw new ArgumentNullException("CodeMappings storage must be valid!"); - - // try find an exact match - var map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From <= ilOffset && ilOffset < m.ILInstructionOffset.To); - - if (map == null) { - // get the immediate next one - map = codeMapping.MemberCodeMappings.Find(m => m.ILInstructionOffset.From > ilOffset); - isMatch = false; - if (map == null) - map = codeMapping.MemberCodeMappings.LastOrDefault(); // get the last - - return map; - } - - isMatch = true; - return map; - } + public ILRange[] ILRanges { get; set; } + public TextLocation StartLocation { get; set; } + public TextLocation EndLocation { get; set; } + public int ILOffset { get { return this.ILRanges[0].From; } } - /// <summary> - /// Gets the source code and type name from metadata token and offset. - /// </summary> - /// <param name="codeMappings">Code mapping storage.</param> - /// <param name="token">Metadata token.</param> - /// <param name="ilOffset">IL offset.</param> - /// <param name="typeName">Type definition.</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> - public static bool GetInstructionByTokenAndOffset( - this MemberMapping mapping, - int ilOffset, - out MemberReference member, - out int line) + public override string ToString() { - member = null; - line = 0; - - if (mapping == null) - throw new ArgumentException("CodeMappings storage must be valid!"); - - var codeMapping = mapping.MemberCodeMappings.Find( - cm => cm.ILInstructionOffset.From <= ilOffset && ilOffset <= cm.ILInstructionOffset.To - 1); - if (codeMapping == null) { - codeMapping = mapping.MemberCodeMappings.Find(cm => cm.ILInstructionOffset.From > ilOffset); - if (codeMapping == null) { - codeMapping = mapping.MemberCodeMappings.LastOrDefault(); - if (codeMapping == null) - return false; - } - } - - member = mapping.MemberReference; - line = codeMapping.StartLocation.Line; - return true; + return string.Join(" ", this.ILRanges) + " " + this.StartLocation + "-" + this.EndLocation; } } } diff --git a/main/contrib/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs b/main/contrib/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs index 63567c71ff..4c2080045e 100644 --- a/main/contrib/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs +++ b/main/contrib/ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs @@ -222,7 +222,7 @@ namespace ICSharpCode.Decompiler.Disassembler } else { // The ECMA specification says that ' inside SQString should be ecaped using an octal escape sequence, // but we follow Microsoft's ILDasm and use \'. - return "'" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(identifier).Replace("'", "\\'") + "'"; + return "'" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(identifier).Replace("'", "\\'") + "'"; } } @@ -353,7 +353,7 @@ namespace ICSharpCode.Decompiler.Disassembler string s = operand as string; if (s != null) { - writer.Write("\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(s) + "\""); + writer.Write("\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(s) + "\""); } else if (operand is char) { writer.Write(((int)(char)operand).ToString()); } else if (operand is float) { diff --git a/main/contrib/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/main/contrib/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index 04abfe5118..a45a718207 100644 --- a/main/contrib/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/main/contrib/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.Disassembler this.cancellationToken = cancellationToken; } - public void Disassemble(MethodBody body, MemberMapping methodMapping) + public void Disassemble(MethodBody body, MethodDebugSymbols debugSymbols) { // start writing IL code MethodDefinition method = body.Method; @@ -82,20 +82,19 @@ namespace ICSharpCode.Decompiler.Disassembler if (detectControlStructure && body.Instructions.Count > 0) { Instruction inst = body.Instructions[0]; HashSet<int> branchTargets = GetBranchTargets(body.Instructions); - WriteStructureBody(new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize); + WriteStructureBody(new ILStructure(body), branchTargets, ref inst, debugSymbols, method.Body.CodeSize); } else { foreach (var inst in method.Body.Instructions) { var startLocation = output.Location; inst.WriteTo(output); - if (methodMapping != null) { + if (debugSymbols != null) { // add IL code mappings - used in debugger - methodMapping.MemberCodeMappings.Add( - new SourceCodeMapping() { + debugSymbols.SequencePoints.Add( + new SequencePoint() { StartLocation = output.Location, EndLocation = output.Location, - ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset }, - MemberMapping = methodMapping + ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) } }); } @@ -174,7 +173,7 @@ namespace ICSharpCode.Decompiler.Disassembler output.Indent(); } - void WriteStructureBody(ILStructure s, HashSet<int> branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize) + void WriteStructureBody(ILStructure s, HashSet<int> branchTargets, ref Instruction inst, MethodDebugSymbols debugSymbols, int codeSize) { bool isFirstInstructionInStructure = true; bool prevInstructionWasBranch = false; @@ -184,7 +183,7 @@ namespace ICSharpCode.Decompiler.Disassembler if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) { ILStructure child = s.Children[childIndex++]; WriteStructureHeader(child); - WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize); + WriteStructureBody(child, branchTargets, ref inst, debugSymbols, codeSize); WriteStructureFooter(child); } else { if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) { @@ -194,13 +193,12 @@ namespace ICSharpCode.Decompiler.Disassembler inst.WriteTo(output); // add IL code mappings - used in debugger - if (currentMethodMapping != null) { - currentMethodMapping.MemberCodeMappings.Add( - new SourceCodeMapping() { + if (debugSymbols != null) { + debugSymbols.SequencePoints.Add( + new SequencePoint() { StartLocation = startLocation, EndLocation = output.Location, - ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset }, - MemberMapping = currentMethodMapping + ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) } }); } diff --git a/main/contrib/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/main/contrib/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index ed246a092a..1a7d1a4f71 100644 --- a/main/contrib/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/main/contrib/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -22,6 +22,7 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; +using ICSharpCode.NRefactory; using Mono.Cecil; using Mono.Collections.Generic; @@ -114,6 +115,8 @@ namespace ICSharpCode.Decompiler.Disassembler // instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed // + TextLocation startLocation = output.Location; + //emit flags WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility); WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags); @@ -123,10 +126,10 @@ namespace ICSharpCode.Decompiler.Disassembler output.Write("pinvokeimpl"); if (method.HasPInvokeInfo && method.PInvokeInfo != null) { PInvokeInfo info = method.PInvokeInfo; - output.Write("(\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(info.Module.Name) + "\""); + output.Write("(\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(info.Module.Name) + "\""); if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name) - output.Write(" as \"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(info.EntryPoint) + "\""); + output.Write(" as \"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(info.EntryPoint) + "\""); if (info.IsNoMangle) output.Write(" nomangle"); @@ -217,9 +220,11 @@ namespace ICSharpCode.Decompiler.Disassembler if (method.HasBody) { // create IL code mappings - used in debugger - MemberMapping methodMapping = new MemberMapping(method); - methodBodyDisassembler.Disassemble(method.Body, methodMapping); - output.AddDebuggerMemberMapping(methodMapping); + MethodDebugSymbols debugSymbols = new MethodDebugSymbols(method); + debugSymbols.StartLocation = startLocation; + methodBodyDisassembler.Disassemble(method.Body, debugSymbols); + debugSymbols.EndLocation = output.Location; + output.AddDebugSymbols(debugSymbols); } CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name)); @@ -341,7 +346,7 @@ namespace ICSharpCode.Decompiler.Disassembler output.Write(" = "); if (na.Argument.Value is string) { // secdecls use special syntax for strings - output.Write("string('{0}')", NRefactory.CSharp.CSharpOutputVisitor.ConvertString((string)na.Argument.Value).Replace("'", "\'")); + output.Write("string('{0}')", NRefactory.CSharp.TextWriterTokenWriter.ConvertString((string)na.Argument.Value).Replace("'", "\'")); } else { WriteConstant(na.Argument.Value); } @@ -569,10 +574,10 @@ namespace ICSharpCode.Decompiler.Disassembler if (cmi == null) goto default; output.Write("custom(\"{0}\", \"{1}\"", - NRefactory.CSharp.CSharpOutputVisitor.ConvertString(cmi.ManagedType.FullName), - NRefactory.CSharp.CSharpOutputVisitor.ConvertString(cmi.Cookie)); + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(cmi.ManagedType.FullName), + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(cmi.Cookie)); if (cmi.Guid != Guid.Empty || !string.IsNullOrEmpty(cmi.UnmanagedType)) { - output.Write(", \"{0}\", \"{1}\"", cmi.Guid.ToString(), NRefactory.CSharp.CSharpOutputVisitor.ConvertString(cmi.UnmanagedType)); + output.Write(", \"{0}\", \"{1}\"", cmi.Guid.ToString(), NRefactory.CSharp.TextWriterTokenWriter.ConvertString(cmi.UnmanagedType)); } output.Write(')'); break; diff --git a/main/contrib/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj b/main/contrib/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj index 9a9bccbead..ca4fc4e5bf 100644 --- a/main/contrib/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj +++ b/main/contrib/ICSharpCode.Decompiler/ICSharpCode.Decompiler.csproj @@ -56,7 +56,6 @@ <Compile Include="Ast\DecompilerContext.cs" /> <Compile Include="Ast\NameVariables.cs" /> <Compile Include="Ast\NRefactoryExtensions.cs" /> - <Compile Include="Ast\TextOutputFormatter.cs" /> <Compile Include="Ast\Transforms\AddCheckedBlocks.cs" /> <Compile Include="Ast\Transforms\CombineQueryExpressions.cs" /> <Compile Include="Ast\Transforms\ContextTrackingVisitor.cs" /> @@ -121,6 +120,7 @@ <Compile Include="ILAst\StateRange.cs" /> <Compile Include="ILAst\SymbolicExecution.cs" /> <Compile Include="ILAst\AsyncDecompiler.cs" /> + <Compile Include="Ast\TextTokenWriter.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\external\cecil\Mono.Cecil.csproj"> diff --git a/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs b/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs index cbdc5d771f..da8c6c6beb 100644 --- a/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs +++ b/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs @@ -743,7 +743,7 @@ namespace ICSharpCode.Decompiler.ILAst // Convert stack-based IL code to ILAst tree foreach(ByteCode byteCode in body) { - ILRange ilRange = new ILRange() { From = byteCode.Offset, To = byteCode.EndOffset }; + ILRange ilRange = new ILRange(byteCode.Offset, byteCode.EndOffset); if (byteCode.StackBefore == null) { // Unreachable code diff --git a/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs b/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs index 4f3930fcdd..9cd42a14fc 100644 --- a/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs +++ b/main/contrib/ICSharpCode.Decompiler/ILAst/ILAstTypes.cs @@ -221,37 +221,43 @@ namespace ICSharpCode.Decompiler.ILAst } } - public class ILRange + public struct ILRange { - public int From; - public int To; // Exlusive + public readonly int From; + public readonly int To; // Exlusive + + public ILRange(int @from, int to) + { + this.From = @from; + this.To = to; + } public override string ToString() { - return string.Format("{0}-{1}", From.ToString("X"), To.ToString("X")); + return string.Format("{0:X2}-{1:X2}", From, To); } - public static List<ILRange> OrderAndJoint(IEnumerable<ILRange> input) + public static List<ILRange> OrderAndJoin(IEnumerable<ILRange> input) { if (input == null) throw new ArgumentNullException("Input is null!"); - List<ILRange> ranges = input.Where(r => r != null).OrderBy(r => r.From).ToList(); - for (int i = 0; i < ranges.Count - 1;) { - ILRange curr = ranges[i]; - ILRange next = ranges[i + 1]; - // Merge consequtive ranges if they intersect - if (curr.From <= next.From && next.From <= curr.To) { - curr.To = Math.Max(curr.To, next.To); - ranges.RemoveAt(i + 1); - } else { - i++; + List<ILRange> result = new List<ILRange>(); + foreach(ILRange curr in input.OrderBy(r => r.From)) { + if (result.Count > 0) { + // Merge consequtive ranges if possible + ILRange last = result[result.Count - 1]; + if (curr.From <= last.To) { + result[result.Count - 1] = new ILRange(last.From, Math.Max(last.To, curr.To)); + continue; + } } + result.Add(curr); } - return ranges; + return result; } - public static IEnumerable<ILRange> Invert(IEnumerable<ILRange> input, int codeSize) + public static List<ILRange> Invert(IEnumerable<ILRange> input, int codeSize) { if (input == null) throw new ArgumentNullException("Input is null!"); @@ -259,23 +265,25 @@ namespace ICSharpCode.Decompiler.ILAst if (codeSize <= 0) throw new ArgumentException("Code size must be grater than 0"); - var ordered = OrderAndJoint(input); + List<ILRange> ordered = OrderAndJoin(input); + List<ILRange> result = new List<ILRange>(ordered.Count + 1); if (ordered.Count == 0) { - yield return new ILRange() { From = 0, To = codeSize }; + result.Add(new ILRange(0, codeSize)); } else { // Gap before the first element if (ordered.First().From != 0) - yield return new ILRange() { From = 0, To = ordered.First().From }; + result.Add(new ILRange(0, ordered.First().From)); // Gaps between elements for (int i = 0; i < ordered.Count - 1; i++) - yield return new ILRange() { From = ordered[i].To, To = ordered[i + 1].From }; + result.Add(new ILRange(ordered[i].To, ordered[i + 1].From)); // Gap after the last element Debug.Assert(ordered.Last().To <= codeSize); if (ordered.Last().To != codeSize) - yield return new ILRange() { From = ordered.Last().To, To = codeSize }; + result.Add(new ILRange(ordered.Last().To, codeSize)); } + return result; } } diff --git a/main/contrib/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs b/main/contrib/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs index 58632fd96e..b050353ab4 100644 --- a/main/contrib/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs +++ b/main/contrib/ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs @@ -303,7 +303,13 @@ namespace ICSharpCode.Decompiler.ILAst return v.Type; } case ILCode.Ldloca: - return new ByReferenceType(((ILVariable)expr.Operand).Type); + { + ILVariable v = (ILVariable)expr.Operand; + if (v.Type != null) + return new ByReferenceType(v.Type); + else + return null; + } #endregion #region Call / NewObj case ILCode.Call: diff --git a/main/contrib/ICSharpCode.Decompiler/ITextOutput.cs b/main/contrib/ICSharpCode.Decompiler/ITextOutput.cs index 0bcf5eac6b..f13a55d61b 100644 --- a/main/contrib/ICSharpCode.Decompiler/ITextOutput.cs +++ b/main/contrib/ICSharpCode.Decompiler/ITextOutput.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.Decompiler void WriteDefinition(string text, object definition, bool isLocal = true); void WriteReference(string text, object reference, bool isLocal = false); - void AddDebuggerMemberMapping(MemberMapping memberMapping); + void AddDebugSymbols(MethodDebugSymbols methodDebugSymbols); void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false); void MarkFoldEnd(); diff --git a/main/contrib/ICSharpCode.Decompiler/PlainTextOutput.cs b/main/contrib/ICSharpCode.Decompiler/PlainTextOutput.cs index f2d709cdd5..6319226d16 100644 --- a/main/contrib/ICSharpCode.Decompiler/PlainTextOutput.cs +++ b/main/contrib/ICSharpCode.Decompiler/PlainTextOutput.cs @@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler { } - void ITextOutput.AddDebuggerMemberMapping(MemberMapping memberMapping) + void ITextOutput.AddDebugSymbols(MethodDebugSymbols methodDebugSymbols) { } } diff --git a/main/contrib/ICSharpCode.Decompiler/Properties/AssemblyInfo.template.cs b/main/contrib/ICSharpCode.Decompiler/Properties/AssemblyInfo.template.cs deleted file mode 100644 index bec57df5fd..0000000000 --- a/main/contrib/ICSharpCode.Decompiler/Properties/AssemblyInfo.template.cs +++ /dev/null @@ -1,27 +0,0 @@ -#region Using directives - -using System; -using System.Resources; -using System.Reflection; -using System.Runtime.InteropServices; - -#endregion - -[assembly: AssemblyTitle("ICSharpCode.Decompiler")] -[assembly: AssemblyDescription("IL decompiler engine")] -[assembly: AssemblyCompany("ic#code")] -[assembly: AssemblyProduct("ILSpy")] -[assembly: AssemblyCopyright("Copyright 2011 AlphaSierraPapa for the SharpDevelop Team")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// This sets the default COM visibility of types in the assembly to invisible. -// If you need to expose a type to COM, use [ComVisible(true)] on that type. -[assembly: ComVisible(false)] - -[assembly: AssemblyVersion("$INSERTVERSION$")] -[assembly: AssemblyInformationalVersion("$INSERTVERSION$$INSERTBRANCHPOSTFIX$$INSERTVERSIONNAMEPOSTFIX$-$INSERTSHORTCOMMITHASH$")] -[assembly: NeutralResourcesLanguage("en-US")] - -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly", - Justification = "AssemblyInformationalVersion does not need to be a parsable version")] diff --git a/main/contrib/ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs b/main/contrib/ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs index df395b446f..3af31e282c 100644 --- a/main/contrib/ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs +++ b/main/contrib/ICSharpCode.Decompiler/Tests/CustomAttributes/S_CustomAttributeSamples.cs @@ -69,6 +69,19 @@ namespace AppliedToEvent public event EventHandler MyEvent; } } +//$$ AppliedToEventMethods +namespace AppliedToEventMethods +{ + [AttributeUsage(AttributeTargets.Method)] + public class MyAttributeAttribute : Attribute + { + } + public class TestClass + { + [method: MyAttribute] + public event EventHandler MyEvent; + } +} //$$ AppliedToField namespace AppliedToField { diff --git a/main/contrib/ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs b/main/contrib/ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs index 5eb7012284..8205042a97 100644 --- a/main/contrib/ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs +++ b/main/contrib/ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs @@ -58,7 +58,7 @@ namespace ICSharpCode.Decompiler.Tests AssemblyDefinition assembly = Compile(code); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule) { Settings = settings }); decompiler.AddAssembly(assembly); - new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); + new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); return output.ToString(); diff --git a/main/contrib/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/main/contrib/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj index eaa88937a9..69598ac73f 100644 --- a/main/contrib/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj +++ b/main/contrib/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj @@ -34,7 +34,7 @@ <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <OutputPath>..\bin\Debug\</OutputPath> <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> + <DebugType>Full</DebugType> <Optimize>False</Optimize> <DefineConstants>DEBUG;TRACE</DefineConstants> </PropertyGroup> @@ -133,4 +133,4 @@ <None Include="BooleanConsumedAsInteger.il" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> -</Project> +</Project>
\ No newline at end of file diff --git a/main/contrib/ICSharpCode.Decompiler/Tests/TestRunner.cs b/main/contrib/ICSharpCode.Decompiler/Tests/TestRunner.cs index 52a03a4623..009a3c6c17 100644 --- a/main/contrib/ICSharpCode.Decompiler/Tests/TestRunner.cs +++ b/main/contrib/ICSharpCode.Decompiler/Tests/TestRunner.cs @@ -184,7 +184,7 @@ namespace ICSharpCode.Decompiler.Tests AssemblyDefinition assembly = Compile(code, optimize, useDebug); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule)); decompiler.AddAssembly(assembly); - new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); + new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); CodeAssert.AreEqual(code, output.ToString()); |