/* 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); } } }