From 468e3da92cc74c9c85f169d72f775ca3063fb4fc Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Wed, 1 Jul 2026 12:05:30 +0200 Subject: [PATCH] Bracket ILAst WriteTo in one place via WriteToCore The debug-step node bracket (MarkNodeStart/try/finally/MarkNodeEnd) was copied into every hand-written WriteTo override and re-emitted by the T4 generator, so a newly added instruction could silently omit it and lose step highlighting with no compile error or test failure. Seal WriteTo on ILInstruction to apply the bracket once and delegate to a new abstract WriteToCore; move every override (hand-written and generated) to WriteToCore without the wrapper. Rendered output is unchanged -- the marks are no-ops unless the output tracks nodes. Assisted-by: Claude:claude-opus-4-8:Claude Code --- ICSharpCode.Decompiler/IL/Instructions.cs | 887 +++++++----------- ICSharpCode.Decompiler/IL/Instructions.tt | 8 +- .../Instructions/BinaryNumericInstruction.cs | 54 +- .../IL/Instructions/Block.cs | 60 +- .../IL/Instructions/BlockContainer.cs | 80 +- .../IL/Instructions/Branch.cs | 18 +- .../IL/Instructions/CallIndirect.cs | 42 +- .../IL/Instructions/CallInstruction.cs | 42 +- .../IL/Instructions/Comp.cs | 72 +- .../CompoundAssignmentInstruction.cs | 110 +-- .../IL/Instructions/Conv.cs | 78 +- .../IL/Instructions/DeconstructInstruction.cs | 58 +- .../DeconstructResultInstruction.cs | 24 +- .../IL/Instructions/DynamicInstructions.cs | 288 ++---- .../IL/Instructions/ExpressionTreeCast.cs | 28 +- .../IL/Instructions/ILFunction.cs | 140 ++- .../IL/Instructions/ILInstruction.cs | 24 +- .../IL/Instructions/IfInstruction.cs | 58 +- .../IL/Instructions/LdLen.cs | 24 +- .../IL/Instructions/Leave.cs | 26 +- .../IL/Instructions/LockInstruction.cs | 28 +- .../IL/Instructions/MatchInstruction.cs | 92 +- .../IL/Instructions/MemoryInstructions.cs | 98 +- .../Instructions/NullCoalescingInstruction.cs | 24 +- .../IL/Instructions/NullableInstructions.cs | 24 +- .../IL/Instructions/SimpleInstruction.cs | 82 +- .../IL/Instructions/StringToInt.cs | 42 +- .../IL/Instructions/SwitchInstruction.cs | 84 +- .../IL/Instructions/TryInstruction.cs | 94 +- .../IL/Instructions/UnaryInstruction.cs | 24 +- .../IL/Instructions/UsingInstruction.cs | 42 +- 31 files changed, 1082 insertions(+), 1673 deletions(-) diff --git a/ICSharpCode.Decompiler/IL/Instructions.cs b/ICSharpCode.Decompiler/IL/Instructions.cs index b29c7e745..314f6f198 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions.cs @@ -370,18 +370,13 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.None; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write('('); - this.argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write('('); + this.argument.WriteTo(output, options); + output.Write(')'); } } } @@ -471,20 +466,15 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.None; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write('('); - this.left.WriteTo(output, options); - output.Write(", "); - this.right.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write('('); + this.left.WriteTo(output, options); + output.Write(", "); + this.right.WriteTo(output, options); + output.Write(')'); } } } @@ -634,20 +624,15 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.None; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write('('); - this.target.WriteTo(output, options); - output.Write(", "); - this.value.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write('('); + this.target.WriteTo(output, options); + output.Write(", "); + this.value.WriteTo(output, options); + output.Write(')'); } } } @@ -1024,22 +1009,17 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayWriteLocals; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - variable.WriteTo(output); - output.Write('('); - this.init.WriteTo(output, options); - output.Write(", "); - this.body.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + variable.WriteTo(output); + output.Write('('); + this.init.WriteTo(output, options); + output.Write(", "); + this.body.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2359,17 +2339,12 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayReadLocals; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - variable.WriteTo(output); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + variable.WriteTo(output); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2438,17 +2413,12 @@ namespace ICSharpCode.Decompiler.IL base.Disconnected(); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - variable.WriteTo(output); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + variable.WriteTo(output); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2578,20 +2548,15 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayWriteLocals; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - variable.WriteTo(output); - output.Write('('); - this.value.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + variable.WriteTo(output); + output.Write('('); + this.value.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2688,20 +2653,15 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.None; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - this.value.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + this.value.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2858,17 +2818,12 @@ namespace ICSharpCode.Decompiler.IL } public readonly string Value; public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - Disassembler.DisassemblerHelpers.WriteOperand(output, Value); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + Disassembler.DisassemblerHelpers.WriteOperand(output, Value); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2900,17 +2855,12 @@ namespace ICSharpCode.Decompiler.IL } public readonly string Value; public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - Disassembler.DisassemblerHelpers.WriteOperand(output, Value); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + Disassembler.DisassemblerHelpers.WriteOperand(output, Value); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2942,17 +2892,12 @@ namespace ICSharpCode.Decompiler.IL } public readonly int Value; public override StackType ResultType { get { return StackType.I4; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - Disassembler.DisassemblerHelpers.WriteOperand(output, Value); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + Disassembler.DisassemblerHelpers.WriteOperand(output, Value); } public override void AcceptVisitor(ILVisitor visitor) { @@ -2984,17 +2929,12 @@ namespace ICSharpCode.Decompiler.IL } public readonly long Value; public override StackType ResultType { get { return StackType.I8; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - Disassembler.DisassemblerHelpers.WriteOperand(output, Value); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + Disassembler.DisassemblerHelpers.WriteOperand(output, Value); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3026,17 +2966,12 @@ namespace ICSharpCode.Decompiler.IL } public readonly float Value; public override StackType ResultType { get { return StackType.F4; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - Disassembler.DisassemblerHelpers.WriteOperand(output, Value); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + Disassembler.DisassemblerHelpers.WriteOperand(output, Value); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3068,17 +3003,12 @@ namespace ICSharpCode.Decompiler.IL } public readonly double Value; public override StackType ResultType { get { return StackType.F8; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - Disassembler.DisassemblerHelpers.WriteOperand(output, Value); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + Disassembler.DisassemblerHelpers.WriteOperand(output, Value); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3110,17 +3040,12 @@ namespace ICSharpCode.Decompiler.IL } public readonly decimal Value; public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - Disassembler.DisassemblerHelpers.WriteOperand(output, Value); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + Disassembler.DisassemblerHelpers.WriteOperand(output, Value); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3182,20 +3107,15 @@ namespace ICSharpCode.Decompiler.IL /// Returns the method operand. public IMethod Method => method; public override StackType ResultType { get { return StackType.I; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (method != null) { - WriteILRange(output, options); - output.Write(OpCode); - if (method != null) - { - output.Write(' '); - method.WriteTo(output); - } + output.Write(' '); + method.WriteTo(output); } - finally { output.MarkNodeEnd(this); } } public override void AcceptVisitor(ILVisitor visitor) { @@ -3238,23 +3158,18 @@ namespace ICSharpCode.Decompiler.IL return base.DirectFlags | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (method != null) { - WriteILRange(output, options); - output.Write(OpCode); - if (method != null) - { - output.Write(' '); - method.WriteTo(output); - } - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); + output.Write(' '); + method.WriteTo(output); } - finally { output.MarkNodeEnd(this); } + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3304,25 +3219,20 @@ namespace ICSharpCode.Decompiler.IL return base.DirectFlags | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + if (method != null) { - WriteILRange(output, options); - output.Write(OpCode); output.Write(' '); - type.WriteTo(output); - if (method != null) - { - output.Write(' '); - method.WriteTo(output); - } - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + method.WriteTo(output); + } + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3359,17 +3269,12 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3403,17 +3308,12 @@ namespace ICSharpCode.Decompiler.IL /// Returns the token operand. public IMember Member { get { return member; } } public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - member.WriteTo(output); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + member.WriteTo(output); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3496,20 +3396,15 @@ namespace ICSharpCode.Decompiler.IL return base.DirectFlags | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3639,26 +3534,21 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayThrow | InstructionFlags.SideEffect; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - if (IsVolatile) - output.Write("volatile."); - if (UnalignedPrefix > 0) - output.Write("unaligned(" + UnalignedPrefix + ")."); - output.Write(OpCode); - output.Write('('); - this.destAddress.WriteTo(output, options); - output.Write(", "); - this.sourceAddress.WriteTo(output, options); - output.Write(", "); - this.size.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + if (IsVolatile) + output.Write("volatile."); + if (UnalignedPrefix > 0) + output.Write("unaligned(" + UnalignedPrefix + ")."); + output.Write(OpCode); + output.Write('('); + this.destAddress.WriteTo(output, options); + output.Write(", "); + this.sourceAddress.WriteTo(output, options); + output.Write(", "); + this.size.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3795,26 +3685,21 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayThrow | InstructionFlags.SideEffect; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - if (IsVolatile) - output.Write("volatile."); - if (UnalignedPrefix > 0) - output.Write("unaligned(" + UnalignedPrefix + ")."); - output.Write(OpCode); - output.Write('('); - this.address.WriteTo(output, options); - output.Write(", "); - this.value.WriteTo(output, options); - output.Write(", "); - this.size.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + if (IsVolatile) + output.Write("volatile."); + if (UnalignedPrefix > 0) + output.Write("unaligned(" + UnalignedPrefix + ")."); + output.Write(OpCode); + output.Write('('); + this.address.WriteTo(output, options); + output.Write(", "); + this.value.WriteTo(output, options); + output.Write(", "); + this.size.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3916,22 +3801,17 @@ namespace ICSharpCode.Decompiler.IL return (DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow); } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - if (DelayExceptions) - output.Write("delayex."); - output.Write(OpCode); - output.Write(' '); - @field.WriteTo(output); - output.Write('('); - this.target.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + if (DelayExceptions) + output.Write("delayex."); + output.Write(OpCode); + output.Write(' '); + @field.WriteTo(output); + output.Write('('); + this.target.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -3965,17 +3845,12 @@ namespace ICSharpCode.Decompiler.IL readonly IField @field; /// Returns the field operand. public IField Field { get { return @field; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - @field.WriteTo(output); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + @field.WriteTo(output); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4021,20 +3896,15 @@ namespace ICSharpCode.Decompiler.IL return base.DirectFlags | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4071,20 +3941,15 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4299,20 +4164,15 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.SideEffect | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - this.target.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + this.target.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4495,20 +4355,15 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4554,20 +4409,15 @@ namespace ICSharpCode.Decompiler.IL return base.DirectFlags | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4613,20 +4463,15 @@ namespace ICSharpCode.Decompiler.IL return base.DirectFlags | InstructionFlags.SideEffect | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4735,28 +4580,23 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + bool first = true; + foreach (var indices in Indices) { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - bool first = true; - foreach (var indices in Indices) - { - if (!first) - output.Write(", "); - else - first = false; - indices.WriteTo(output, options); - } - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + if (!first) + output.Write(", "); + else + first = false; + indices.WriteTo(output, options); + } + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4793,17 +4633,12 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public override StackType ResultType { get { return type.GetStackType(); } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); } public override void AcceptVisitor(ILVisitor visitor) { @@ -4914,17 +4749,12 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public override StackType ResultType { get { return StackType.I4; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); } public override void AcceptVisitor(ILVisitor visitor) { @@ -5120,31 +4950,26 @@ namespace ICSharpCode.Decompiler.IL return (DelayExceptions ? InstructionFlags.None : InstructionFlags.MayThrow); } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + if (WithSystemIndex) + output.Write("withsystemindex."); + if (DelayExceptions) + output.Write("delayex."); + if (IsReadOnly) + output.Write("readonly."); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + this.array.WriteTo(output, options); + foreach (var indices in Indices) { - WriteILRange(output, options); - if (WithSystemIndex) - output.Write("withsystemindex."); - if (DelayExceptions) - output.Write("delayex."); - if (IsReadOnly) - output.Write("readonly."); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - this.array.WriteTo(output, options); - foreach (var indices in Indices) - { - output.Write(", "); - indices.WriteTo(output, options); - } - output.Write(')'); + output.Write(", "); + indices.WriteTo(output, options); } - finally { output.MarkNodeEnd(this); } + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -5250,27 +5075,22 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + if (IsReadOnly) + output.Write("readonly."); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + this.array.WriteTo(output, options); + foreach (var indices in Indices) { - WriteILRange(output, options); - if (IsReadOnly) - output.Write("readonly."); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - this.array.WriteTo(output, options); - foreach (var indices in Indices) - { - output.Write(", "); - indices.WriteTo(output, options); - } - output.Write(')'); + output.Write(", "); + indices.WriteTo(output, options); } - finally { output.MarkNodeEnd(this); } + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -5368,23 +5188,18 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.None; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (method != null) { - WriteILRange(output, options); - output.Write(OpCode); - if (method != null) - { - output.Write(' '); - method.WriteTo(output); - } - output.Write('('); - this.argument.WriteTo(output, options); - output.Write(')'); + output.Write(' '); + method.WriteTo(output); } - finally { output.MarkNodeEnd(this); } + output.Write('('); + this.argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -5621,25 +5436,20 @@ namespace ICSharpCode.Decompiler.IL clone.Right = this.right.Clone(); return clone; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (method != null) { - WriteILRange(output, options); - output.Write(OpCode); - if (method != null) - { - output.Write(' '); - method.WriteTo(output); - } - output.Write('('); - this.left.WriteTo(output, options); - output.Write(", "); - this.right.WriteTo(output, options); - output.Write(')'); + output.Write(' '); + method.WriteTo(output); } - finally { output.MarkNodeEnd(this); } + output.Write('('); + this.left.WriteTo(output, options); + output.Write(", "); + this.right.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -6823,20 +6633,15 @@ namespace ICSharpCode.Decompiler.IL set { type = value; InvalidateFlags(); } } public override StackType ResultType { get { return StackType.O; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -6910,20 +6715,15 @@ namespace ICSharpCode.Decompiler.IL return base.DirectFlags | InstructionFlags.MayThrow; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -7013,18 +6813,13 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.MayBranch | InstructionFlags.SideEffect; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write('('); - this.value.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write('('); + this.value.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -7114,18 +6909,13 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.SideEffect; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write('('); - this.value.WriteTo(output, options); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write('('); + this.value.WriteTo(output, options); + output.Write(')'); } public override void AcceptVisitor(ILVisitor visitor) { @@ -7239,17 +7029,12 @@ namespace ICSharpCode.Decompiler.IL.Patterns var clone = (AnyNode)ShallowClone(); return clone; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write('('); - output.Write(')'); - } - finally { output.MarkNodeEnd(this); } + WriteILRange(output, options); + output.Write(OpCode); + output.Write('('); + output.Write(')'); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions.tt b/ICSharpCode.Decompiler/IL/Instructions.tt index 103572235..96fcb35ef 100644 --- a/ICSharpCode.Decompiler/IL/Instructions.tt +++ b/ICSharpCode.Decompiler/IL/Instructions.tt @@ -429,12 +429,8 @@ namespace <#=opCode.Namespace#> void OriginalWriteTo(ITextOutput output, ILAstWritingOptions options) {<#=Body(opCode.WriteToBody)#>} <# } else { #> - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) - { - output.MarkNodeStart(this); - try {<#=Body(opCode.WriteToBody)#>} - finally { output.MarkNodeEnd(this); } - } + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) + {<#=Body(opCode.WriteToBody)#>} <# } #> <# } #> <# if (opCode.GenerateAcceptVisitor) { #> diff --git a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs index ca36302f0..b3499fb9a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs @@ -184,42 +184,34 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + output.Write("." + GetOperatorName(Operator)); + if (CheckForOverflow) { - WriteILRange(output, options); - output.Write(OpCode); - output.Write("." + GetOperatorName(Operator)); - if (CheckForOverflow) - { - output.Write(".ovf"); - } - if (Sign == Sign.Unsigned) - { - output.Write(".unsigned"); - } - else if (Sign == Sign.Signed) - { - output.Write(".signed"); - } - output.Write('.'); - output.Write(resultType.ToString().ToLowerInvariant()); - if (IsLifted) - { - output.Write(".lifted"); - } - output.Write('('); - Left.WriteTo(output, options); - output.Write(", "); - Right.WriteTo(output, options); - output.Write(')'); + output.Write(".ovf"); + } + if (Sign == Sign.Unsigned) + { + output.Write(".unsigned"); + } + else if (Sign == Sign.Signed) + { + output.Write(".signed"); } - finally + output.Write('.'); + output.Write(resultType.ToString().ToLowerInvariant()); + if (IsLifted) { - output.MarkNodeEnd(this); + output.Write(".lifted"); } + output.Write('('); + Left.WriteTo(output, options); + output.Write(", "); + Right.WriteTo(output, options); + output.Write(')'); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/Block.cs b/ICSharpCode.Decompiler/IL/Instructions/Block.cs index c6aae0f1b..6c8206c46 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Block.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Block.cs @@ -258,47 +258,39 @@ namespace ICSharpCode.Decompiler.IL get { return Disassembler.DisassemblerHelpers.OffsetToString(this.StartILOffset); } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write("Block "); + output.WriteLocalReference(Label, this, isDefinition: true); + if (Kind != BlockKind.ControlFlow) + output.Write($" ({Kind})"); + if (Parent is BlockContainer) + output.Write(" (incoming: {0})", IncomingEdgeCount); + output.Write(' '); + output.MarkFoldStart("{...}"); + output.WriteLine("{"); + output.Indent(); + int index = 0; + foreach (var inst in Instructions) { - WriteILRange(output, options); - output.Write("Block "); - output.WriteLocalReference(Label, this, isDefinition: true); - if (Kind != BlockKind.ControlFlow) - output.Write($" ({Kind})"); - if (Parent is BlockContainer) - output.Write(" (incoming: {0})", IncomingEdgeCount); - output.Write(' '); - output.MarkFoldStart("{...}"); - output.WriteLine("{"); - output.Indent(); - int index = 0; - foreach (var inst in Instructions) - { - if (options.ShowChildIndexInBlock) - { - output.Write("[" + index + "] "); - index++; - } - inst.WriteTo(output, options); - output.WriteLine(); - } - if (finalInstruction.OpCode != OpCode.Nop) + if (options.ShowChildIndexInBlock) { - output.Write("final: "); - finalInstruction.WriteTo(output, options); - output.WriteLine(); + output.Write("[" + index + "] "); + index++; } - output.Unindent(); - output.Write("}"); - output.MarkFoldEnd(); + inst.WriteTo(output, options); + output.WriteLine(); } - finally + if (finalInstruction.OpCode != OpCode.Nop) { - output.MarkNodeEnd(this); + output.Write("final: "); + finalInstruction.WriteTo(output, options); + output.WriteLine(); } + output.Unindent(); + output.Write("}"); + output.MarkFoldEnd(); } protected override int GetChildCount() diff --git a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs index fc341879b..9c212982d 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/BlockContainer.cs @@ -125,57 +125,49 @@ namespace ICSharpCode.Decompiler.IL entryPoint.IncomingEdgeCount--; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.WriteLocalReference("BlockContainer", this, isDefinition: true); + output.Write(' '); + switch (Kind) + { + case ContainerKind.Loop: + output.Write("(while-true) "); + break; + case ContainerKind.Switch: + output.Write("(switch) "); + break; + case ContainerKind.While: + output.Write("(while) "); + break; + case ContainerKind.DoWhile: + output.Write("(do-while) "); + break; + case ContainerKind.For: + output.Write("(for) "); + break; + } + output.MarkFoldStart("{...}"); + output.WriteLine("{"); + output.Indent(); + foreach (var inst in Blocks) { - WriteILRange(output, options); - output.WriteLocalReference("BlockContainer", this, isDefinition: true); - output.Write(' '); - switch (Kind) + if (inst.Parent == this) { - case ContainerKind.Loop: - output.Write("(while-true) "); - break; - case ContainerKind.Switch: - output.Write("(switch) "); - break; - case ContainerKind.While: - output.Write("(while) "); - break; - case ContainerKind.DoWhile: - output.Write("(do-while) "); - break; - case ContainerKind.For: - output.Write("(for) "); - break; + inst.WriteTo(output, options); } - output.MarkFoldStart("{...}"); - output.WriteLine("{"); - output.Indent(); - foreach (var inst in Blocks) + else { - if (inst.Parent == this) - { - inst.WriteTo(output, options); - } - else - { - output.Write("stale reference to "); - output.WriteLocalReference(inst.Label, inst); - } - output.WriteLine(); - output.WriteLine(); + output.Write("stale reference to "); + output.WriteLocalReference(inst.Label, inst); } - output.Unindent(); - output.Write("}"); - output.MarkFoldEnd(); - } - finally - { - output.MarkNodeEnd(this); + output.WriteLine(); + output.WriteLine(); } + output.Unindent(); + output.Write("}"); + output.MarkFoldEnd(); } protected override int GetChildCount() diff --git a/ICSharpCode.Decompiler/IL/Instructions/Branch.cs b/ICSharpCode.Decompiler/IL/Instructions/Branch.cs index a398d9261..9f5aee745 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Branch.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Branch.cs @@ -118,20 +118,12 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - output.WriteLocalReference(TargetLabel, (object?)targetBlock ?? TargetILOffset); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + output.WriteLocalReference(TargetLabel, (object?)targetBlock ?? TargetILOffset); } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs index d4be2caf8..54a2b8880 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CallIndirect.cs @@ -74,36 +74,28 @@ namespace ICSharpCode.Decompiler.IL Debug.Assert(Arguments.Count == FunctionPointerType.ParameterTypes.Length + (IsInstance ? 1 : 0)); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write("call.indirect "); + FunctionPointerType.ReturnType.WriteTo(output); + output.Write('('); + functionPointer.WriteTo(output, options); + int firstArgument = IsInstance ? 1 : 0; + if (firstArgument == 1) { - WriteILRange(output, options); - output.Write("call.indirect "); - FunctionPointerType.ReturnType.WriteTo(output); - output.Write('('); - functionPointer.WriteTo(output, options); - int firstArgument = IsInstance ? 1 : 0; - if (firstArgument == 1) - { - output.Write(", "); - Arguments[0].WriteTo(output, options); - } - foreach (var (inst, type) in Arguments.Zip(FunctionPointerType.ParameterTypes, (a, b) => (a, b))) - { - output.Write(", "); - inst.WriteTo(output, options); - output.Write(" : "); - type.WriteTo(output); - } - if (Arguments.Count > 0) - output.Write(')'); + output.Write(", "); + Arguments[0].WriteTo(output, options); } - finally + foreach (var (inst, type) in Arguments.Zip(FunctionPointerType.ParameterTypes, (a, b) => (a, b))) { - output.MarkNodeEnd(this); + output.Write(", "); + inst.WriteTo(output, options); + output.Write(" : "); + type.WriteTo(output); } + if (Arguments.Count > 0) + output.Write(')'); } protected override int GetChildCount() diff --git a/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs index 0a1025ff3..3aa46e16e 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CallInstruction.cs @@ -138,36 +138,28 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + if (ConstrainedTo != null) { - WriteILRange(output, options); - if (ConstrainedTo != null) - { - output.Write("constrained["); - ConstrainedTo.WriteTo(output); - output.Write("]."); - } - if (IsTail) - output.Write("tail."); - output.Write(OpCode); - output.Write(' '); - Method.WriteTo(output); - output.Write('('); - for (int i = 0; i < Arguments.Count; i++) - { - if (i > 0) - output.Write(", "); - Arguments[i].WriteTo(output, options); - } - output.Write(')'); + output.Write("constrained["); + ConstrainedTo.WriteTo(output); + output.Write("]."); } - finally + if (IsTail) + output.Write("tail."); + output.Write(OpCode); + output.Write(' '); + Method.WriteTo(output); + output.Write('('); + for (int i = 0; i < Arguments.Count; i++) { - output.MarkNodeEnd(this); + if (i > 0) + output.Write(", "); + Arguments[i].WriteTo(output, options); } + output.Write(')'); } protected internal sealed override bool PerformMatch(ILInstruction? other, ref Patterns.Match match) diff --git a/ICSharpCode.Decompiler/IL/Instructions/Comp.cs b/ICSharpCode.Decompiler/IL/Instructions/Comp.cs index 8e98e002e..2a6756644 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Comp.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Comp.cs @@ -179,52 +179,44 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + if (options.UseLogicOperationSugar && MatchLogicNot(out var arg)) { - WriteILRange(output, options); - if (options.UseLogicOperationSugar && MatchLogicNot(out var arg)) - { - output.Write("logic.not("); - arg.WriteTo(output, options); - output.Write(')'); - return; - } - output.Write(OpCode); - output.Write('.'); - output.Write(InputType.ToString().ToLower()); - switch (Sign) - { - case Sign.Signed: - output.Write(".signed"); - break; - case Sign.Unsigned: - output.Write(".unsigned"); - break; - } - switch (LiftingKind) - { - case ComparisonLiftingKind.CSharp: - output.Write(".lifted[C#]"); - break; - case ComparisonLiftingKind.ThreeValuedLogic: - output.Write(".lifted[3VL]"); - break; - } - output.Write('('); - Left.WriteTo(output, options); - output.Write(' '); - output.Write(Kind.GetToken()); - output.Write(' '); - Right.WriteTo(output, options); + output.Write("logic.not("); + arg.WriteTo(output, options); output.Write(')'); + return; } - finally + output.Write(OpCode); + output.Write('.'); + output.Write(InputType.ToString().ToLower()); + switch (Sign) { - output.MarkNodeEnd(this); + case Sign.Signed: + output.Write(".signed"); + break; + case Sign.Unsigned: + output.Write(".unsigned"); + break; } + switch (LiftingKind) + { + case ComparisonLiftingKind.CSharp: + output.Write(".lifted[C#]"); + break; + case ComparisonLiftingKind.ThreeValuedLogic: + output.Write(".lifted[3VL]"); + break; + } + output.Write('('); + Left.WriteTo(output, options); + output.Write(' '); + output.Write(Kind.GetToken()); + output.Write(' '); + Right.WriteTo(output, options); + output.Write(')'); } public static Comp LogicNot(ILInstruction arg) diff --git a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs index f6cecb8d1..85f49aad6 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/CompoundAssignmentInstruction.cs @@ -272,43 +272,35 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + output.Write("." + BinaryNumericInstruction.GetOperatorName(Operator)); + if (CheckForOverflow) { - WriteILRange(output, options); - output.Write(OpCode); - output.Write("." + BinaryNumericInstruction.GetOperatorName(Operator)); - if (CheckForOverflow) - { - output.Write(".ovf"); - } - if (Sign == Sign.Unsigned) - { - output.Write(".unsigned"); - } - else if (Sign == Sign.Signed) - { - output.Write(".signed"); - } - output.Write('.'); - output.Write(UnderlyingResultType.ToString().ToLowerInvariant()); - if (IsLifted) - { - output.Write(".lifted"); - } - base.WriteSuffix(output); - output.Write('('); - Target.WriteTo(output, options); - output.Write(", "); - Value.WriteTo(output, options); - output.Write(')'); + output.Write(".ovf"); + } + if (Sign == Sign.Unsigned) + { + output.Write(".unsigned"); } - finally + else if (Sign == Sign.Signed) { - output.MarkNodeEnd(this); + output.Write(".signed"); } + output.Write('.'); + output.Write(UnderlyingResultType.ToString().ToLowerInvariant()); + if (IsLifted) + { + output.Write(".lifted"); + } + base.WriteSuffix(output); + output.Write('('); + Target.WriteTo(output, options); + output.Write(", "); + Value.WriteTo(output, options); + output.Write(')'); } } @@ -344,26 +336,18 @@ namespace ICSharpCode.Decompiler.IL public override StackType ResultType => Method.ReturnType.GetStackType(); - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - base.WriteSuffix(output); - output.Write(' '); - Method.WriteTo(output); - output.Write('('); - this.Target.WriteTo(output, options); - output.Write(", "); - this.Value.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + base.WriteSuffix(output); + output.Write(' '); + Method.WriteTo(output); + output.Write('('); + this.Target.WriteTo(output, options); + output.Write(", "); + this.Value.WriteTo(output, options); + output.Write(')'); } } @@ -388,23 +372,15 @@ namespace ICSharpCode.Decompiler.IL this.ValueArgumentInfo = valueArgumentInfo; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write("." + Operation.ToString().ToLower()); - DynamicInstruction.WriteBinderFlags(BinderFlags, output, options); - base.WriteSuffix(output); - output.Write(' '); - DynamicInstruction.WriteArgumentList(output, options, (Target, TargetArgumentInfo), (Value, ValueArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + output.Write("." + Operation.ToString().ToLower()); + DynamicInstruction.WriteBinderFlags(BinderFlags, output, options); + base.WriteSuffix(output); + output.Write(' '); + DynamicInstruction.WriteArgumentList(output, options, (Target, TargetArgumentInfo), (Value, ValueArgumentInfo)); } internal static bool IsExpressionTypeSupported(ExpressionType type) diff --git a/ICSharpCode.Decompiler/IL/Instructions/Conv.cs b/ICSharpCode.Decompiler/IL/Instructions/Conv.cs index d5fe091fd..e029b1894 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Conv.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Conv.cs @@ -314,54 +314,46 @@ namespace ICSharpCode.Decompiler.IL get => TargetType.GetStackType(); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (CheckForOverflow) + { + output.Write(".ovf"); + } + if (InputSign == Sign.Unsigned) + { + output.Write(".unsigned"); + } + else if (InputSign == Sign.Signed) + { + output.Write(".signed"); + } + if (IsLifted) { - WriteILRange(output, options); - output.Write(OpCode); - if (CheckForOverflow) - { - output.Write(".ovf"); - } - if (InputSign == Sign.Unsigned) - { - output.Write(".unsigned"); - } - else if (InputSign == Sign.Signed) - { - output.Write(".signed"); - } - if (IsLifted) - { - output.Write(".lifted"); - } - output.Write(' '); - output.Write(InputType); - output.Write("->"); - output.Write(TargetType); - output.Write(' '); - switch (Kind) - { - case ConversionKind.SignExtend: - output.Write(""); - break; - case ConversionKind.ZeroExtend: - output.Write(""); - break; - case ConversionKind.Invalid: - output.Write(""); - break; - } - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); + output.Write(".lifted"); } - finally + output.Write(' '); + output.Write(InputType); + output.Write("->"); + output.Write(TargetType); + output.Write(' '); + switch (Kind) { - output.MarkNodeEnd(this); + case ConversionKind.SignExtend: + output.Write(""); + break; + case ConversionKind.ZeroExtend: + output.Write(""); + break; + case ConversionKind.Invalid: + output.Write(""); + break; } + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } protected override InstructionFlags ComputeFlags() diff --git a/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs index d02f1824c..f2993a7f8 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DeconstructInstruction.cs @@ -159,43 +159,35 @@ namespace ICSharpCode.Decompiler.IL assignments.ChildIndex = Init.Count + 2; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write("deconstruct "); + output.MarkFoldStart("{...}"); + output.WriteLine("{"); + output.Indent(); + output.WriteLine("init:"); + output.Indent(); + foreach (var inst in this.Init) { - WriteILRange(output, options); - output.Write("deconstruct "); - output.MarkFoldStart("{...}"); - output.WriteLine("{"); - output.Indent(); - output.WriteLine("init:"); - output.Indent(); - foreach (var inst in this.Init) - { - inst.WriteTo(output, options); - output.WriteLine(); - } - output.Unindent(); - output.WriteLine("pattern:"); - output.Indent(); - pattern.WriteTo(output, options); - output.Unindent(); - output.WriteLine(); - output.Write("conversions: "); - conversions.WriteTo(output, options); + inst.WriteTo(output, options); output.WriteLine(); - output.Write("assignments: "); - assignments.WriteTo(output, options); - output.Unindent(); - output.WriteLine(); - output.Write('}'); - output.MarkFoldEnd(); - } - finally - { - output.MarkNodeEnd(this); } + output.Unindent(); + output.WriteLine("pattern:"); + output.Indent(); + pattern.WriteTo(output, options); + output.Unindent(); + output.WriteLine(); + output.Write("conversions: "); + conversions.WriteTo(output, options); + output.WriteLine(); + output.Write("assignments: "); + assignments.WriteTo(output, options); + output.Unindent(); + output.WriteLine(); + output.Write('}'); + output.MarkFoldEnd(); } internal static bool IsConversionStLoc(ILInstruction inst, out ILVariable variable, out ILVariable inputVariable) diff --git a/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs index f3f171815..608aa4483 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DeconstructResultInstruction.cs @@ -37,23 +37,15 @@ namespace ICSharpCode.Decompiler.IL ResultType = resultType; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write(' '); - output.Write(Index.ToString()); - output.Write('('); - this.Argument.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + output.Write(' '); + output.Write(Index.ToString()); + output.Write('('); + this.Argument.WriteTo(output, options); + output.Write(')'); } MatchInstruction? FindMatch() diff --git a/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs index 568a31517..3e037a336 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/DynamicInstructions.cs @@ -130,24 +130,16 @@ namespace ICSharpCode.Decompiler.IL partial class DynamicConvertInstruction { - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - argument.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + argument.WriteTo(output, options); + output.Write(')'); } public DynamicConvertInstruction(CSharpBinderFlags binderFlags, IType type, IType? context, ILInstruction argument) @@ -190,35 +182,27 @@ namespace ICSharpCode.Decompiler.IL Arguments.AddRange(arguments); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write(Name); + if (TypeArguments.Count > 0) { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write(Name); - if (TypeArguments.Count > 0) + output.Write('<'); + int i = 0; + foreach (var typeArg in TypeArguments) { - output.Write('<'); - int i = 0; - foreach (var typeArg in TypeArguments) - { - if (i > 0) - output.Write(", "); - typeArg.WriteTo(output); - i++; - } - output.Write('>'); + if (i > 0) + output.Write(", "); + typeArg.WriteTo(output); + i++; } - WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); + output.Write('>'); } + WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -244,22 +228,14 @@ namespace ICSharpCode.Decompiler.IL Target = target; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write(Name); - WriteArgumentList(output, options, (Target, TargetArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write(Name); + WriteArgumentList(output, options, (Target, TargetArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -288,22 +264,14 @@ namespace ICSharpCode.Decompiler.IL Value = value; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write(Name); - WriteArgumentList(output, options, (Target, TargetArgumentInfo), (Value, ValueArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write(Name); + WriteArgumentList(output, options, (Target, TargetArgumentInfo), (Value, ValueArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -334,22 +302,14 @@ namespace ICSharpCode.Decompiler.IL Arguments.AddRange(arguments); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write("get_Item"); - WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write("get_Item"); + WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -374,22 +334,14 @@ namespace ICSharpCode.Decompiler.IL Arguments.AddRange(arguments); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write("set_Item"); - WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write("set_Item"); + WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -417,23 +369,15 @@ namespace ICSharpCode.Decompiler.IL this.resultType = type; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - resultType?.WriteTo(output); - output.Write(".ctor"); - WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + resultType?.WriteTo(output); + output.Write(".ctor"); + WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); } public override StackType ResultType => resultType?.GetStackType() ?? StackType.Unknown; @@ -462,22 +406,14 @@ namespace ICSharpCode.Decompiler.IL Right = right; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write(Operation.ToString()); - WriteArgumentList(output, options, (Left, LeftArgumentInfo), (Right, RightArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write(Operation.ToString()); + WriteArgumentList(output, options, (Left, LeftArgumentInfo), (Right, RightArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -512,22 +448,14 @@ namespace ICSharpCode.Decompiler.IL Right = right; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write(Operation.ToString()); - WriteArgumentList(output, options, (Left, LeftArgumentInfo), (Right, RightArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write(Operation.ToString()); + WriteArgumentList(output, options, (Left, LeftArgumentInfo), (Right, RightArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -567,22 +495,14 @@ namespace ICSharpCode.Decompiler.IL Operand = operand; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write(Operation.ToString()); - WriteArgumentList(output, options, (Operand, OperandArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write(Operation.ToString()); + WriteArgumentList(output, options, (Operand, OperandArgumentInfo)); } public override StackType ResultType { @@ -622,21 +542,13 @@ namespace ICSharpCode.Decompiler.IL Arguments.AddRange(arguments); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + WriteArgumentList(output, options, Arguments.Zip(ArgumentInfo)); } public override StackType ResultType => StackType.O; @@ -660,23 +572,15 @@ namespace ICSharpCode.Decompiler.IL Argument = argument; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - WriteBinderFlags(output, options); - output.Write(' '); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + WriteBinderFlags(output, options); + output.Write(' '); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override StackType ResultType => StackType.I4; diff --git a/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs b/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs index 4434ae5ca..670ebe653 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ExpressionTreeCast.cs @@ -14,25 +14,17 @@ namespace ICSharpCode.Decompiler.IL this.IsChecked = isChecked; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - if (IsChecked) - output.Write(".checked"); - output.Write(' '); - type.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + if (IsChecked) + output.Write(".checked"); + output.Write(' '); + type.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs index 97e601dd9..762d57e8a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILFunction.cs @@ -270,93 +270,85 @@ namespace ICSharpCode.Decompiler.IL throw new NotSupportedException("ILFunction.CloneVariables is currently not supported!"); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (Method != null) { - WriteILRange(output, options); - output.Write(OpCode); - if (Method != null) - { - output.Write(' '); - Method.WriteTo(output); - } - switch (kind) - { - case ILFunctionKind.ExpressionTree: - output.Write(".ET"); - break; - case ILFunctionKind.LocalFunction: - output.Write(".local"); - break; - } - if (DelegateType != null) - { - output.Write("["); - DelegateType.WriteTo(output); - output.Write("]"); - } - output.WriteLine(" {"); - output.Indent(); + output.Write(' '); + Method.WriteTo(output); + } + switch (kind) + { + case ILFunctionKind.ExpressionTree: + output.Write(".ET"); + break; + case ILFunctionKind.LocalFunction: + output.Write(".local"); + break; + } + if (DelegateType != null) + { + output.Write("["); + DelegateType.WriteTo(output); + output.Write("]"); + } + output.WriteLine(" {"); + output.Indent(); - if (IsAsync) - { - output.WriteLine(".async"); - } - if (IsIterator) - { - output.WriteLine(".iterator"); - } - if (DeclarationScope != null) - { - output.Write("declared as " + Name + " in "); - output.WriteLocalReference(DeclarationScope.EntryPoint.Label, DeclarationScope); - output.WriteLine(); - } + if (IsAsync) + { + output.WriteLine(".async"); + } + if (IsIterator) + { + output.WriteLine(".iterator"); + } + if (DeclarationScope != null) + { + output.Write("declared as " + Name + " in "); + output.WriteLocalReference(DeclarationScope.EntryPoint.Label, DeclarationScope); + output.WriteLine(); + } - output.MarkFoldStart(Variables.Count + " variable(s)", true); - foreach (var variable in Variables) - { - variable.WriteDefinitionTo(output); - output.WriteLine(); - } - output.MarkFoldEnd(); + output.MarkFoldStart(Variables.Count + " variable(s)", true); + foreach (var variable in Variables) + { + variable.WriteDefinitionTo(output); output.WriteLine(); + } + output.MarkFoldEnd(); + output.WriteLine(); - foreach (string warning in Warnings) - { - output.WriteLine("//" + warning); - } + foreach (string warning in Warnings) + { + output.WriteLine("//" + warning); + } - body.WriteTo(output, options); + body.WriteTo(output, options); + output.WriteLine(); + + foreach (var localFunction in LocalFunctions) + { output.WriteLine(); + localFunction.WriteTo(output, options); + } - foreach (var localFunction in LocalFunctions) + if (options.ShowILRanges) + { + var unusedILRanges = FindUnusedILRanges(); + if (!unusedILRanges.IsEmpty) { + output.Write("// Unused IL Ranges: "); + output.Write(string.Join(", ", unusedILRanges.Intervals.Select( + range => $"[{range.Start:x4}..{range.InclusiveEnd:x4}]"))); output.WriteLine(); - localFunction.WriteTo(output, options); } - - if (options.ShowILRanges) - { - var unusedILRanges = FindUnusedILRanges(); - if (!unusedILRanges.IsEmpty) - { - output.Write("// Unused IL Ranges: "); - output.Write(string.Join(", ", unusedILRanges.Intervals.Select( - range => $"[{range.Start:x4}..{range.InclusiveEnd:x4}]"))); - output.WriteLine(); - } - } - - output.Unindent(); - output.WriteLine("}"); - } - finally - { - output.MarkNodeEnd(this); } + + output.Unindent(); + output.WriteLine("}"); } LongSet FindUnusedILRanges() diff --git a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs index 028294cd5..e362d8a29 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs @@ -383,9 +383,29 @@ namespace ICSharpCode.Decompiler.IL } /// - /// Writes the ILAst to the text output. + /// Writes the ILAst to the text output. Brackets the instruction's rendered span so it can be + /// mapped back to its character range for debug-step highlighting; the bracket lives here, in + /// one place, so a new instruction cannot forget it. Override to + /// render an instruction, not this method. Both marks are no-ops unless the output tracks nodes. /// - public abstract void WriteTo(ITextOutput output, ILAstWritingOptions options); + public void WriteTo(ITextOutput output, ILAstWritingOptions options) + { + output.MarkNodeStart(this); + try + { + WriteToCore(output, options); + } + finally + { + output.MarkNodeEnd(this); + } + } + + /// + /// Renders this instruction to the text output. This is the override point; callers use + /// , which wraps this in the node-tracking bracket. + /// + protected abstract void WriteToCore(ITextOutput output, ILAstWritingOptions options); public override string ToString() { diff --git a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs index 7328beee0..f61e8b510 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/IfInstruction.cs @@ -82,47 +82,39 @@ namespace ICSharpCode.Decompiler.IL return InstructionFlags.ControlFlow | condition.Flags | SemanticHelper.CombineBranches(trueInst.Flags, falseInst.Flags); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + if (options.UseLogicOperationSugar) { - WriteILRange(output, options); - if (options.UseLogicOperationSugar) + if (MatchLogicAnd(out var lhs, out var rhs)) { - if (MatchLogicAnd(out var lhs, out var rhs)) - { - output.Write("logic.and("); - lhs.WriteTo(output, options); - output.Write(", "); - rhs.WriteTo(output, options); - output.Write(')'); - return; - } - if (MatchLogicOr(out lhs, out rhs)) - { - output.Write("logic.or("); - lhs.WriteTo(output, options); - output.Write(", "); - rhs.WriteTo(output, options); - output.Write(')'); - return; - } + output.Write("logic.and("); + lhs.WriteTo(output, options); + output.Write(", "); + rhs.WriteTo(output, options); + output.Write(')'); + return; } - output.Write(OpCode); - output.Write(" ("); - condition.WriteTo(output, options); - output.Write(") "); - trueInst.WriteTo(output, options); - if (falseInst.OpCode != OpCode.Nop) + if (MatchLogicOr(out lhs, out rhs)) { - output.Write(" else "); - falseInst.WriteTo(output, options); + output.Write("logic.or("); + lhs.WriteTo(output, options); + output.Write(", "); + rhs.WriteTo(output, options); + output.Write(')'); + return; } } - finally + output.Write(OpCode); + output.Write(" ("); + condition.WriteTo(output, options); + output.Write(") "); + trueInst.WriteTo(output, options); + if (falseInst.OpCode != OpCode.Nop) { - output.MarkNodeEnd(this); + output.Write(" else "); + falseInst.WriteTo(output, options); } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs b/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs index f52c4a20d..7a3603d5c 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LdLen.cs @@ -39,23 +39,15 @@ namespace ICSharpCode.Decompiler.IL get { return resultType; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write('.'); - output.Write(resultType); - output.Write('('); - this.array.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + output.Write('.'); + output.Write(resultType); + output.Write('('); + this.array.WriteTo(output, options); + output.Write(')'); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/Leave.cs b/ICSharpCode.Decompiler/IL/Instructions/Leave.cs index bd426503f..4d231e9b3 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/Leave.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/Leave.cs @@ -114,25 +114,17 @@ namespace ICSharpCode.Decompiler.IL Debug.Assert(phase <= ILPhase.InILReader || phase == ILPhase.InAsyncAwait || value.ResultType == targetContainer!.ResultType); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - if (targetContainer != null) - { - output.Write(' '); - output.WriteLocalReference(TargetLabel, targetContainer); - output.Write(" ("); - value.WriteTo(output, options); - output.Write(')'); - } - } - finally + WriteILRange(output, options); + output.Write(OpCode); + if (targetContainer != null) { - output.MarkNodeEnd(this); + output.Write(' '); + output.WriteLocalReference(TargetLabel, targetContainer); + output.Write(" ("); + value.WriteTo(output, options); + output.Write(')'); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs index 29d9c5f0a..13bfe9afc 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/LockInstruction.cs @@ -27,25 +27,17 @@ namespace ICSharpCode.Decompiler.IL { partial class LockInstruction { - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write("lock ("); - OnExpression.WriteTo(output, options); - output.WriteLine(") {"); - output.Indent(); - Body.WriteTo(output, options); - output.Unindent(); - output.WriteLine(); - output.Write("}"); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write("lock ("); + OnExpression.WriteTo(output, options); + output.WriteLine(") {"); + output.Indent(); + Body.WriteTo(output, options); + output.Unindent(); + output.WriteLine(); + output.Write("}"); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs index ede8f0569..899b7de9a 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/MatchInstruction.cs @@ -274,60 +274,52 @@ namespace ICSharpCode.Decompiler.IL return true; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (CheckNotNull) { - WriteILRange(output, options); - output.Write(OpCode); - if (CheckNotNull) - { - output.Write(".notnull"); - } - if (CheckType) - { - output.Write(".type["); - variable.Type.WriteTo(output); - output.Write(']'); - } - if (IsDeconstructCall) - { - output.Write(".deconstruct["); - if (method == null) - output.Write(""); - else - method.WriteTo(output); - output.Write(']'); - } - if (IsDeconstructTuple) - { - output.Write(".tuple"); - } - output.Write(' '); - output.Write('('); - Variable.WriteTo(output); - output.Write(" = "); - TestedOperand.WriteTo(output, options); - output.Write(')'); - if (SubPatterns.Count > 0) - { - output.MarkFoldStart("{...}"); - output.WriteLine("{"); - output.Indent(); - foreach (var pattern in SubPatterns) - { - pattern.WriteTo(output, options); - output.WriteLine(); - } - output.Unindent(); - output.Write('}'); - output.MarkFoldEnd(); - } + output.Write(".notnull"); + } + if (CheckType) + { + output.Write(".type["); + variable.Type.WriteTo(output); + output.Write(']'); } - finally + if (IsDeconstructCall) { - output.MarkNodeEnd(this); + output.Write(".deconstruct["); + if (method == null) + output.Write(""); + else + method.WriteTo(output); + output.Write(']'); + } + if (IsDeconstructTuple) + { + output.Write(".tuple"); + } + output.Write(' '); + output.Write('('); + Variable.WriteTo(output); + output.Write(" = "); + TestedOperand.WriteTo(output, options); + output.Write(')'); + if (SubPatterns.Count > 0) + { + output.MarkFoldStart("{...}"); + output.WriteLine("{"); + output.Indent(); + foreach (var pattern in SubPatterns) + { + pattern.WriteTo(output, options); + output.WriteLine(); + } + output.Unindent(); + output.Write('}'); + output.MarkFoldEnd(); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs index 75c7b191a..fe4d687f1 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/MemoryInstructions.cs @@ -37,78 +37,62 @@ namespace ICSharpCode.Decompiler.IL partial class LdObj { - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + if (options.UseFieldSugar) { - if (options.UseFieldSugar) + if (this.MatchLdFld(out var target, out var field)) { - if (this.MatchLdFld(out var target, out var field)) - { - WriteILRange(output, options); - output.Write("ldfld "); - field.WriteTo(output); - output.Write('('); - target.WriteTo(output, options); - output.Write(')'); - return; - } - else if (this.MatchLdsFld(out field)) - { - WriteILRange(output, options); - output.Write("ldsfld "); - field.WriteTo(output); - return; - } + WriteILRange(output, options); + output.Write("ldfld "); + field.WriteTo(output); + output.Write('('); + target.WriteTo(output, options); + output.Write(')'); + return; + } + else if (this.MatchLdsFld(out field)) + { + WriteILRange(output, options); + output.Write("ldsfld "); + field.WriteTo(output); + return; } - OriginalWriteTo(output, options); - } - finally - { - output.MarkNodeEnd(this); } + OriginalWriteTo(output, options); } } partial class StObj { - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + if (options.UseFieldSugar) { - if (options.UseFieldSugar) + if (this.MatchStFld(out var target, out var field, out var value)) { - if (this.MatchStFld(out var target, out var field, out var value)) - { - WriteILRange(output, options); - output.Write("stfld "); - field.WriteTo(output); - output.Write('('); - target.WriteTo(output, options); - output.Write(", "); - value.WriteTo(output, options); - output.Write(')'); - return; - } - else if (this.MatchStsFld(out field, out value)) - { - WriteILRange(output, options); - output.Write("stsfld "); - field.WriteTo(output); - output.Write('('); - value.WriteTo(output, options); - output.Write(')'); - return; - } + WriteILRange(output, options); + output.Write("stfld "); + field.WriteTo(output); + output.Write('('); + target.WriteTo(output, options); + output.Write(", "); + value.WriteTo(output, options); + output.Write(')'); + return; + } + else if (this.MatchStsFld(out field, out value)) + { + WriteILRange(output, options); + output.Write("stsfld "); + field.WriteTo(output); + output.Write('('); + value.WriteTo(output, options); + output.Write(')'); + return; } - OriginalWriteTo(output, options); - } - finally - { - output.MarkNodeEnd(this); } + OriginalWriteTo(output, options); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs index b8c8f7d3e..67085e040 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/NullCoalescingInstruction.cs @@ -90,23 +90,15 @@ namespace ICSharpCode.Decompiler.IL | SemanticHelper.CombineBranches(InstructionFlags.None, fallbackInst.Flags); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - output.Write("("); - valueInst.WriteTo(output, options); - output.Write(", "); - fallbackInst.WriteTo(output, options); - output.Write(")"); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + output.Write("("); + valueInst.WriteTo(output, options); + output.Write(", "); + fallbackInst.WriteTo(output, options); + output.Write(")"); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs b/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs index ab60c9493..8fc20f6a3 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/NullableInstructions.cs @@ -90,25 +90,17 @@ namespace ICSharpCode.Decompiler.IL Debug.Assert(Ancestors.Any(a => a is NullableRewrap)); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + output.Write("nullable.unwrap."); + if (RefInput) { - output.Write("nullable.unwrap."); - if (RefInput) - { - output.Write("refinput."); - } - output.Write(ResultType); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); + output.Write("refinput."); } + output.Write(ResultType); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(')'); } public override StackType ResultType { get; } diff --git a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs index 3b5821199..661c999fa 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/SimpleInstruction.cs @@ -24,19 +24,11 @@ namespace ICSharpCode.Decompiler.IL /// public abstract partial class SimpleInstruction : ILInstruction { - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - // the non-custom WriteTo would add useless parentheses - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(OpCode); + // the non-custom WriteTo would add useless parentheses } } @@ -52,25 +44,17 @@ namespace ICSharpCode.Decompiler.IL public NopKind Kind; - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (Kind != NopKind.Normal) { - WriteILRange(output, options); - output.Write(OpCode); - if (Kind != NopKind.Normal) - { - output.Write("." + Kind.ToString().ToLowerInvariant()); - } - if (!string.IsNullOrEmpty(Comment)) - { - output.Write(" // " + Comment); - } + output.Write("." + Kind.ToString().ToLowerInvariant()); } - finally + if (!string.IsNullOrEmpty(Comment)) { - output.MarkNodeEnd(this); + output.Write(" // " + Comment); } } } @@ -89,23 +73,15 @@ namespace ICSharpCode.Decompiler.IL get { return ExpectedResultType; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (!string.IsNullOrEmpty(Message)) { - WriteILRange(output, options); - output.Write(OpCode); - if (!string.IsNullOrEmpty(Message)) - { - output.Write("(\""); - output.Write(Message); - output.Write("\")"); - } - } - finally - { - output.MarkNodeEnd(this); + output.Write("(\""); + output.Write(Message); + output.Write("\")"); } } } @@ -125,23 +101,15 @@ namespace ICSharpCode.Decompiler.IL get { return ExpectedResultType; } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(OpCode); - if (!string.IsNullOrEmpty(Message)) - { - output.Write("(\""); - output.Write(Message); - output.Write("\")"); - } - } - finally + WriteILRange(output, options); + output.Write(OpCode); + if (!string.IsNullOrEmpty(Message)) { - output.MarkNodeEnd(this); + output.Write("(\""); + output.Write(Message); + output.Write("\")"); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs index 8802b8d64..c095665f7 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/StringToInt.cs @@ -52,34 +52,26 @@ namespace ICSharpCode.Decompiler.IL return dict; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write("string.to.int "); + ExpectedType.WriteTo(output); + output.Write('('); + Argument.WriteTo(output, options); + output.Write(", { "); + int i = 0; + foreach (var entry in Map) { - WriteILRange(output, options); - output.Write("string.to.int "); - ExpectedType.WriteTo(output); - output.Write('('); - Argument.WriteTo(output, options); - output.Write(", { "); - int i = 0; - foreach (var entry in Map) - { - if (i > 0) - output.Write(", "); - if (entry.Key is null) - output.Write($"[null] = {entry.Value}"); - else - output.Write($"[\"{entry.Key}\"] = {entry.Value}"); - i++; - } - output.Write(" })"); - } - finally - { - output.MarkNodeEnd(this); + if (i > 0) + output.Write(", "); + if (entry.Key is null) + output.Write($"[null] = {entry.Value}"); + else + output.Write($"[\"{entry.Key}\"] = {entry.Value}"); + i++; } + output.Write(" })"); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs index fdfb2bed6..7f4874a7d 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/SwitchInstruction.cs @@ -83,36 +83,28 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write("switch"); + if (IsLifted) + output.Write(".lifted"); + output.Write(' '); + Type?.WriteTo(output); + output.Write('('); + value.WriteTo(output, options); + output.Write(") "); + output.MarkFoldStart("{...}"); + output.WriteLine("{"); + output.Indent(); + foreach (var section in this.Sections) { - WriteILRange(output, options); - output.Write("switch"); - if (IsLifted) - output.Write(".lifted"); - output.Write(' '); - Type?.WriteTo(output); - output.Write('('); - value.WriteTo(output, options); - output.Write(") "); - output.MarkFoldStart("{...}"); - output.WriteLine("{"); - output.Indent(); - foreach (var section in this.Sections) - { - section.WriteTo(output, options); - output.WriteLine(); - } - output.Unindent(); - output.Write('}'); - output.MarkFoldEnd(); - } - finally - { - output.MarkNodeEnd(this); + section.WriteTo(output, options); + output.WriteLine(); } + output.Unindent(); + output.Write('}'); + output.MarkFoldEnd(); } protected override int GetChildCount() @@ -232,37 +224,29 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + if (IsCompilerGeneratedDefaultSection) + output.Write("generated."); + output.WriteLocalReference("case", this, isDefinition: true); + output.Write(' '); + if (HasNullLabel) { - WriteILRange(output, options); - if (IsCompilerGeneratedDefaultSection) - output.Write("generated."); - output.WriteLocalReference("case", this, isDefinition: true); - output.Write(' '); - if (HasNullLabel) - { - output.Write("null"); - if (!Labels.IsEmpty) - { - output.Write(", "); - output.Write(Labels.ToString()); - } - } - else + output.Write("null"); + if (!Labels.IsEmpty) { + output.Write(", "); output.Write(Labels.ToString()); } - output.Write(": "); - - body.WriteTo(output, options); } - finally + else { - output.MarkNodeEnd(this); + output.Write(Labels.ToString()); } + output.Write(": "); + + body.WriteTo(output, options); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs index f4d45c9d5..048a178f0 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/TryInstruction.cs @@ -68,23 +68,15 @@ namespace ICSharpCode.Decompiler.IL return clone; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(".try "); - TryBlock.WriteTo(output, options); - foreach (var handler in Handlers) - { - output.Write(' '); - handler.WriteTo(output, options); - } - } - finally + WriteILRange(output, options); + output.Write(".try "); + TryBlock.WriteTo(output, options); + foreach (var handler in Handlers) { - output.MarkNodeEnd(this); + output.Write(' '); + handler.WriteTo(output, options); } } @@ -172,29 +164,21 @@ namespace ICSharpCode.Decompiler.IL } } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write("catch "); + if (variable != null) { - WriteILRange(output, options); - output.Write("catch "); - if (variable != null) - { - output.WriteLocalReference(variable.Name, variable, isDefinition: true); - output.Write(" : "); - Disassembler.DisassemblerHelpers.WriteOperand(output, variable.Type); - } - output.Write(" when ("); - filter.WriteTo(output, options); - output.Write(')'); - output.Write(' '); - body.WriteTo(output, options); - } - finally - { - output.MarkNodeEnd(this); + output.WriteLocalReference(variable.Name, variable, isDefinition: true); + output.Write(" : "); + Disassembler.DisassemblerHelpers.WriteOperand(output, variable.Type); } + output.Write(" when ("); + filter.WriteTo(output, options); + output.Write(')'); + output.Write(' '); + body.WriteTo(output, options); } /// @@ -233,21 +217,13 @@ namespace ICSharpCode.Decompiler.IL return new TryFinally(TryBlock.Clone(), finallyBlock.Clone()).WithILRange(this); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(".try "); - TryBlock.WriteTo(output, options); - output.Write(" finally "); - finallyBlock.WriteTo(output, options); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(".try "); + TryBlock.WriteTo(output, options); + output.Write(" finally "); + finallyBlock.WriteTo(output, options); } public override StackType ResultType { @@ -338,21 +314,13 @@ namespace ICSharpCode.Decompiler.IL return new TryFault(TryBlock.Clone(), faultBlock.Clone()).WithILRange(this); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try - { - WriteILRange(output, options); - output.Write(".try "); - TryBlock.WriteTo(output, options); - output.Write(" fault "); - faultBlock.WriteTo(output, options); - } - finally - { - output.MarkNodeEnd(this); - } + WriteILRange(output, options); + output.Write(".try "); + TryBlock.WriteTo(output, options); + output.Write(" fault "); + faultBlock.WriteTo(output, options); } public override StackType ResultType { diff --git a/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs index 9cb0ef47d..b4bf7bdc6 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/UnaryInstruction.cs @@ -50,25 +50,17 @@ namespace ICSharpCode.Decompiler.IL Debug.Assert(IsLifted || ResultType == UnderlyingResultType); } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write(OpCode); + if (IsLifted) { - WriteILRange(output, options); - output.Write(OpCode); - if (IsLifted) - { - output.Write(".lifted"); - } - output.Write('('); - this.Argument.WriteTo(output, options); - output.Write(')'); - } - finally - { - output.MarkNodeEnd(this); + output.Write(".lifted"); } + output.Write('('); + this.Argument.WriteTo(output, options); + output.Write(')'); } } } diff --git a/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs b/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs index d0600df32..4ea93aacd 100644 --- a/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs +++ b/ICSharpCode.Decompiler/IL/Instructions/UsingInstruction.cs @@ -40,36 +40,28 @@ namespace ICSharpCode.Decompiler.IL public bool IsRefStruct { get; set; } - public override void WriteTo(ITextOutput output, ILAstWritingOptions options) + protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options) { - output.MarkNodeStart(this); - try + WriteILRange(output, options); + output.Write("using"); + if (IsAsync) { - WriteILRange(output, options); - output.Write("using"); - if (IsAsync) - { - output.Write(".async"); - } - if (IsRefStruct) - { - output.Write(".ref"); - } - output.Write(" ("); - Variable.WriteTo(output); - output.Write(" = "); - ResourceExpression.WriteTo(output, options); - output.WriteLine(") {"); - output.Indent(); - Body.WriteTo(output, options); - output.Unindent(); - output.WriteLine(); - output.Write("}"); + output.Write(".async"); } - finally + if (IsRefStruct) { - output.MarkNodeEnd(this); + output.Write(".ref"); } + output.Write(" ("); + Variable.WriteTo(output); + output.Write(" = "); + ResourceExpression.WriteTo(output, options); + output.WriteLine(") {"); + output.Indent(); + Body.WriteTo(output, options); + output.Unindent(); + output.WriteLine(); + output.Write("}"); } } }