forked from elastic/elasticsearch-net
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SyntaxNodeExtensions.cs
117 lines (100 loc) · 4.77 KB
/
SyntaxNodeExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace DocGenerator
{
public static class SyntaxNodeExtensions
{
private static readonly Regex SingleLineHideComment = new Regex(@"\/\/\s*hide", RegexOptions.Compiled);
private static readonly Regex SingleLineJsonComment = new Regex(@"\/\/\s*json", RegexOptions.Compiled);
/// <summary>
/// Determines if the node should be hidden i.e. not included in the documentation,
/// based on the precedence of a //hide single line comment
/// </summary>
public static bool ShouldBeHidden(this SyntaxNode node) =>
node.HasLeadingTrivia && ShouldBeHidden(node, node.GetLeadingTrivia());
public static bool ShouldBeHidden(this SyntaxNode node, SyntaxTriviaList leadingTrivia) =>
leadingTrivia != default(SyntaxTriviaList) &&
SingleLineHideComment.IsMatch(node.GetLeadingTrivia().ToFullString());
/// <summary>
/// Determines if the node should be json serialized based on the precedence of
/// a //json single line comment
/// </summary>
public static bool ShouldBeConvertedToJson(this SyntaxNode node) =>
node.HasLeadingTrivia && ShouldBeConvertedToJson(node, node.GetLeadingTrivia());
/// <summary>
/// Determines if the node should be json serialized based on the precedence of
/// a //json single line comment
/// </summary>
public static bool ShouldBeConvertedToJson(this SyntaxNode node, SyntaxTriviaList leadingTrivia)
{
if (leadingTrivia == default(SyntaxTriviaList))
return false;
var singleLineCommentIndex = leadingTrivia.IndexOf(SyntaxKind.SingleLineCommentTrivia);
if (singleLineCommentIndex == -1)
return false;
// all trivia after the single line should be whitespace or end of line
if (!leadingTrivia
.SkipWhile((l, i) => i < singleLineCommentIndex)
.Any(l => l.IsKind(SyntaxKind.EndOfLineTrivia) || l.IsKind(SyntaxKind.WhitespaceTrivia)))
{
return false;
}
return SingleLineJsonComment.IsMatch(leadingTrivia.ElementAt(singleLineCommentIndex).ToFullString());
}
/// <summary>
/// Determines if the node is preceded by any multiline documentation.
/// </summary>
/// <param name="node">The node.</param>
public static bool HasMultiLineDocumentationCommentTrivia(this SyntaxNode node) =>
node.HasLeadingTrivia &&
node.GetLeadingTrivia().Any(c => c.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia));
/// <summary>
/// Try to get the json representation of the first anonymous object expression descendent
/// node.
/// </summary>
/// <param name="node"></param>
/// <param name="json"></param>
/// <returns></returns>
public static bool TryGetJsonForSyntaxNode(this SyntaxNode node, out string json)
{
json = null;
// find the first anonymous object expression
var creationExpressionSyntax = node.DescendantNodes()
.OfType<AnonymousObjectCreationExpressionSyntax>()
.FirstOrDefault();
return creationExpressionSyntax != null &&
creationExpressionSyntax.ToFullString().TryGetJsonForAnonymousType(out json);
}
/// <summary>
/// Gets the starting line of the node
/// </summary>
/// <param name="node">The node.</param>
/// <returns></returns>
public static int StartingLine(this SyntaxNode node) =>
node.SyntaxTree.GetLineSpan(node.Span).StartLinePosition.Line;
public static SyntaxNode WithLeadingEndOfLineTrivia(this SyntaxNode node)
{
var leadingTrivia = node.GetLeadingTrivia();
var triviaToRemove = leadingTrivia.Reverse().SkipWhile(t => t.IsKind(SyntaxKind.EndOfLineTrivia));
foreach (var syntaxTrivia in triviaToRemove)
{
node = node.ReplaceTrivia(syntaxTrivia, default(SyntaxTrivia));
}
return node;
}
/// <summary>
/// Gets the text representation of a syntax node without #pragma directives
/// </summary>
/// <param name="node">The node.</param>
/// <returns></returns>
public static string ToFullStringWithoutPragmaWarningDirectiveTrivia(this SyntaxNode node)
{
var pragma = node.DescendantTrivia(s => true, true).Where(t => t.IsKind(SyntaxKind.PragmaWarningDirectiveTrivia));
return node.ReplaceTrivia(pragma, (s, r) => default(SyntaxTrivia)).ToFullString();
}
}
}