/*
Copyright (C) 2014-2019 de4dot@gmail.com
This file is part of dnSpy
dnSpy is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
dnSpy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with dnSpy. If not, see .
*/
using System;
using dnSpy.Contracts.Text;
namespace dnSpy.Contracts.Decompiler {
///
/// Interface used by decompilers to write text
///
public interface IDecompilerOutput {
///
/// Gets the total number of written characters
///
int Length { get; }
///
/// This equals plus any indentation that must be written
/// before the next text.
///
int NextPosition { get; }
///
/// Increments the indentation level. Nothing is added to the output stream.
///
void IncreaseIndent();
///
/// Decrements the indentation level. Nothing is added to the output stream.
///
void DecreaseIndent();
///
/// Writes a new line without writing any indentation
///
void WriteLine();
///
/// Writes text and color. The text will be indented if needed.
///
/// Text
/// Color, eg.
void Write(string text, object color);
///
/// Writes text and color. The text will be indented if needed.
///
/// Text
/// Index in
/// Number of characters to write
/// Color, eg.
void Write(string text, int index, int length, object color);
///
/// Writes text, color and a reference. The text will be indented if needed.
///
/// Text
/// Reference
/// Flags
/// Color, eg.
void Write(string text, object? reference, DecompilerReferenceFlags flags, object color);
///
/// Writes text, color and a reference. The text will be indented if needed.
///
/// Text
/// Index in
/// Number of characters to write
/// Reference
/// Flags
/// Color, eg.
void Write(string text, int index, int length, object? reference, DecompilerReferenceFlags flags, object color);
///
/// Adds custom data to a list
///
/// Type of data to store
/// Key, eg.,
/// Data to add. If a span is needed, see
void AddCustomData(string id, TData data);
///
/// true if custom data added by is used
/// and isn't ignored. If this is false, doesn't
/// have to be called.
///
bool UsesCustomData { get; }
}
///
/// extension methods
///
public static class DecompilerOutputExtensions {
///
/// Adds debug info to the custom data collection, see also
///
/// Output
/// Debug info
public static void AddDebugInfo(this IDecompilerOutput output, MethodDebugInfo methodDebugInfo) {
if (methodDebugInfo is null)
throw new ArgumentNullException(nameof(methodDebugInfo));
output.AddCustomData(PredefinedCustomDataIds.DebugInfo, methodDebugInfo);
}
///
/// Adds a
///
/// Output
/// Data
public static void AddSpanReference(this IDecompilerOutput output, SpanReference spanReference) =>
output.AddCustomData(PredefinedCustomDataIds.SpanReference, spanReference);
///
/// Adds a
///
/// Output
/// Reference
/// Start position
/// End position
/// Reference id or null, eg.
public static void AddSpanReference(this IDecompilerOutput output, object reference, int start, int end, string? id) =>
output.AddCustomData(PredefinedCustomDataIds.SpanReference, new SpanReference(reference, TextSpan.FromBounds(start, end), id));
///
/// Adds a
///
/// Output
/// Range
public static void AddCodeBracesRange(this IDecompilerOutput output, CodeBracesRange range) =>
output.AddCustomData(PredefinedCustomDataIds.CodeBracesRange, range);
///
/// Adds a
///
/// Output
/// Start span
/// End span
/// Flags
public static void AddBracePair(this IDecompilerOutput output, TextSpan start, TextSpan end, CodeBracesRangeFlags flags) =>
output.AddCustomData(PredefinedCustomDataIds.CodeBracesRange, new CodeBracesRange(start, end, flags));
///
/// Adds a
///
/// Output
/// Position of the line that gets a line separator
public static void AddLineSeparator(this IDecompilerOutput output, int position) =>
output.AddCustomData(PredefinedCustomDataIds.LineSeparator, new LineSeparator(position));
///
/// Writes text and a new line
///
/// Output
/// Text
/// Color
public static void WriteLine(this IDecompilerOutput output, string text, object color) {
output.Write(text, color);
output.WriteLine();
}
///
/// Writes XML documentation
///
/// Output
/// XML documentation
public static void WriteXmlDoc(this IDecompilerOutput output, string xmlDocText) {
foreach (var info in SimpleXmlParser.Parse(xmlDocText))
output.Write(info.text, info.color);
}
}
}