/
GeneratedCodeAnalysisExtensions.cs
71 lines (64 loc) · 3.17 KB
/
GeneratedCodeAnalysisExtensions.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
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
namespace CodeCracker
{
public static class GeneratedCodeAnalysisExtensions
{
public static bool IsGenerated(this SyntaxNodeAnalysisContext context) => (context.SemanticModel?.SyntaxTree?.IsGenerated() ?? false) || (context.Node?.IsGenerated() ?? false);
public static bool IsGenerated(this SyntaxTreeAnalysisContext context) => context.Tree?.IsGenerated() ?? false;
public static bool IsGenerated(this SymbolAnalysisContext context)
{
if (context.Symbol == null) return false;
foreach (var syntaxReference in context.Symbol.DeclaringSyntaxReferences)
{
if (syntaxReference.SyntaxTree.IsGenerated()) return true;
var root = syntaxReference.SyntaxTree.GetRoot();
var node = root?.FindNode(syntaxReference.Span);
if (node.IsGenerated()) return true;
}
return false;
}
public static bool IsGenerated(this SyntaxNode node) => node.HasAttributeOnAncestorOrSelf("DebuggerNonUserCode", "GeneratedCode");
public static bool IsGenerated(this SyntaxTree tree) => (tree.FilePath?.IsOnGeneratedFile() ?? false) || tree.HasAutoGeneratedComment();
public static bool HasAutoGeneratedComment(this SyntaxTree tree)
{
var root = tree.GetRoot();
if (root == null) return false;
var isCSharp = root is CompilationUnitSyntax;
var firstToken = root.GetFirstToken();
SyntaxTriviaList trivia;
if (firstToken == default(SyntaxToken))
{
var token = isCSharp
? ((CompilationUnitSyntax)root).EndOfFileToken
: ((Microsoft.CodeAnalysis.VisualBasic.Syntax.CompilationUnitSyntax)root).EndOfFileToken;
if (!token.HasLeadingTrivia) return false;
trivia = token.LeadingTrivia;
}
else
{
if (!firstToken.HasLeadingTrivia) return false;
trivia = firstToken.LeadingTrivia;
}
if (isCSharp)
{
var commentLines = trivia.Where(t => t.IsKind(SyntaxKind.SingleLineCommentTrivia)).Take(2).ToList();
if (commentLines.Count != 2) return false;
return commentLines[1].ToString() == "// <auto-generated>";
}
else
{
var commentLines = trivia.Where(t => t.IsKind(Microsoft.CodeAnalysis.VisualBasic.SyntaxKind.CommentTrivia)).Take(2).ToList();
if (commentLines.Count != 2) return false;
return commentLines[1].ToString() == "' <auto-generated>";
}
}
public static bool IsOnGeneratedFile(this string filePath) =>
Regex.IsMatch(filePath, @"(\\service|\\TemporaryGeneratedFile_.*|\\assemblyinfo|\\assemblyattributes|\.(g\.i|g|designer|generated|assemblyattributes))\.(cs|vb)$",
RegexOptions.IgnoreCase);
}
}