Created
September 29, 2015 08:53
-
-
Save nzgeek/9c24abfe6623626aeff1 to your computer and use it in GitHub Desktop.
Debug helper extensions for Roslyn code analyzers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Diagnostics; | |
| using System.Text; | |
| using Microsoft.CodeAnalysis; | |
| using Microsoft.CodeAnalysis.CSharp; | |
| namespace MyCodeAnalysis | |
| { | |
| /// <summary> | |
| /// Extension methods that help with debugging. | |
| /// </summary> | |
| static class DebugExtensions | |
| { | |
| /// <summary> | |
| /// Writes a debug trace entry with information about the syntax node and its location. | |
| /// </summary> | |
| /// <param name="node">The syntax node to log information about.</param> | |
| /// <param name="context">An optional string giving context about the node.</param> | |
| /// <remarks>A debug trace entry is only written if the code is compiled in the Debug configuration.</remarks> | |
| public static void DebugLog(this SyntaxNode node, string context = null) | |
| { | |
| #if DEBUG | |
| var location = node?.GetLocation(); | |
| var syntaxKind = node?.Kind().ToString(); | |
| DebugLog(context, node, syntaxKind, location); | |
| #endif | |
| } | |
| /// <summary> | |
| /// Writes a debug trace entry with information about the syntax node or token and its location. | |
| /// </summary> | |
| /// <param name="nodeOrToken">The syntax node or token to log information about.</param> | |
| /// <param name="context">An optional string giving context about the node or token.</param> | |
| /// <remarks>A debug trace entry is only written if the code is compiled in the Debug configuration.</remarks> | |
| public static void DebugLog(this SyntaxNodeOrToken nodeOrToken, string context = null) | |
| { | |
| #if DEBUG | |
| var location = nodeOrToken.HasValue() ? nodeOrToken.GetLocation() : null; | |
| var syntaxKind = nodeOrToken.HasValue() ? nodeOrToken.Kind().ToString() : null; | |
| DebugLog(context, nodeOrToken, syntaxKind, location); | |
| #endif | |
| } | |
| /// <summary> | |
| /// Writes a debug trace entry with information about the syntax token and its location. | |
| /// </summary> | |
| /// <param name="token">The syntax token to log information about.</param> | |
| /// <param name="context">An optional string giving context about the token.</param> | |
| /// <remarks>A debug trace entry is only written if the code is compiled in the Debug configuration.</remarks> | |
| public static void DebugLog(this SyntaxToken token, string context = null) | |
| { | |
| #if DEBUG | |
| var syntaxItem = token.HasValue() ? (object)token : null; | |
| var syntaxKind = token.HasValue() ? token.Kind().ToString() : null; | |
| var location = token.HasValue() ? token.GetLocation() : null; | |
| DebugLog(context, syntaxItem, syntaxKind, location); | |
| #endif | |
| } | |
| /// <summary> | |
| /// Writes a debug trace entry with information about the syntax trivia and its location. | |
| /// </summary> | |
| /// <param name="trivia">The syntax trivia to log information about.</param> | |
| /// <param name="context">An optional string giving context about the trivia.</param> | |
| /// <remarks>A debug trace entry is only written if the code is compiled in the Debug configuration.</remarks> | |
| public static void DebugLog(this SyntaxTrivia trivia, string context = null) | |
| { | |
| #if DEBUG | |
| var syntaxItem = trivia.HasValue() ? (object)trivia : null; | |
| var syntaxKind = trivia.HasValue() ? trivia.Kind().ToString() : null; | |
| var location = trivia.HasValue() ? trivia.GetLocation() : null; | |
| DebugLog(context, syntaxItem, syntaxKind, location); | |
| #endif | |
| } | |
| /// <summary> | |
| /// Writes a debug trace entry with information about a syntax item and its location. | |
| /// </summary> | |
| /// <param name="context">An optional string giving context about the syntax item.</param> | |
| /// <param name="syntaxItem">The syntax item that information is being logged about.</param> | |
| /// <param name="syntaxKind">A string indicating the type of syntax item.</param> | |
| /// <param name="location">The location that the syntax item appears in the file.</param> | |
| private static void DebugLog(string context, object syntaxItem, string syntaxKind, Location location) | |
| { | |
| if (string.IsNullOrEmpty(context) && syntaxItem == null) | |
| return; | |
| var logMessage = new StringBuilder(); | |
| // Add the context to the log entry, if one was provided. | |
| if (!string.IsNullOrEmpty(context)) | |
| { | |
| logMessage.Append(context); | |
| logMessage.Append(' '); | |
| } | |
| // If no syntax item was provided, we can't say much about it. | |
| if (syntaxItem == null) | |
| { | |
| logMessage.Append("<nothing>"); | |
| } | |
| else | |
| { | |
| // Start the position information with the kind of syntax item. | |
| logMessage.Append('['); | |
| logMessage.Append(syntaxKind ?? syntaxItem.GetType().Name); | |
| logMessage.Append('@'); | |
| // The location could be unknown, or it could be a line/column position. | |
| if (location == null) | |
| { | |
| logMessage.Append("???"); | |
| } | |
| else | |
| { | |
| // Line/column are 0-based. Make them 1-based so they match the position in the Visual Studio | |
| // status bar. | |
| var startPosition = location.GetLineSpan().StartLinePosition; | |
| logMessage.Append(startPosition.Line + 1); | |
| logMessage.Append(','); | |
| logMessage.Append(startPosition.Character + 1); | |
| } | |
| logMessage.Append("] "); | |
| // Add the node text (first line only). | |
| var itemParts = syntaxItem.ToString().Split('\r', '\n'); | |
| logMessage.Append(itemParts[0]); | |
| // If it spans over multiple lines, only add the first line followed by an ellipsis. | |
| if (itemParts.Length > 1) | |
| logMessage.Append(" ..."); | |
| } | |
| Debug.WriteLine(logMessage.ToString()); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment