| Name | Message | Date |
|---|---|---|
| 📄 Cfa.Cli.csproj | 6 days ago | |
| 📄 Colorizer.cs | 9 hours ago | |
| 📄 packages.lock.json | 6 days ago | |
| 📄 Program.cs | 8 days ago | |
| 📄 ScanCommand.cs | 9 hours ago |
📄
cli/src/Colorizer.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
using System.Collections.Generic; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Cfa.Cli; class Colorizer() : CSharpSyntaxWalker(SyntaxWalkerDepth.Token) { public static string ColorMember(ISymbol member) { if (member.ToString() is not string text) { return ""; } var tree = CSharpSyntaxTree.ParseText(text); var root = tree.GetCompilationUnitRoot(); var colorVisitor = new Colorizer(); root.Accept(colorVisitor); return colorVisitor.ToString(); } private StringBuilder sb = new(); private int accesses = 0; private Stack<int> generics = []; private IdentifierKind identifierKind = IdentifierKind.Top; public override void VisitTypeArgumentList(TypeArgumentListSyntax node) { generics.Push(accesses); accesses = 0; var previousIdentifierKind = identifierKind; identifierKind = IdentifierKind.TypeParameter; base.VisitTypeArgumentList(node); identifierKind = previousIdentifierKind; accesses = generics.Pop(); } public override void VisitArgumentList(ArgumentListSyntax node) { var previousIdentifierKind = identifierKind; identifierKind = IdentifierKind.Parameter; base.VisitArgumentList(node); identifierKind = previousIdentifierKind; } public override void VisitMemberAccessExpression(MemberAccessExpressionSyntax node) { accesses++; base.VisitMemberAccessExpression(node); accesses--; } public override void VisitQualifiedName(QualifiedNameSyntax node) { accesses++; base.VisitQualifiedName(node); accesses--; } public override void VisitToken(SyntaxToken token) { switch (token.Kind()) { case (SyntaxKind.DotToken) when identifierKind is not IdentifierKind.Top: break; case (SyntaxKind.LessThanToken or SyntaxKind.GreaterThanToken): sb.Append($"\e[38;2;218;112;214m{token}\e[0m"); break; case (SyntaxKind.OpenParenToken or SyntaxKind.CloseParenToken): sb.Append($"\e[38;2;255;215;0m{token}\e[0m"); break; case (SyntaxKind.IdentifierToken): switch (identifierKind) { case (IdentifierKind.Top) when accesses <= 1: sb.Append($"\e[38;2;210;168;255m{token}\e[0m"); break; case (IdentifierKind.Top): sb.Append($"\e[38;2;78;201;176m{token}\e[0m"); break; case (IdentifierKind.Parameter) when accesses <= 1: sb.Append($"\e[38;2;156;220;254m{token}\e[0m"); break; case (IdentifierKind.TypeParameter) when accesses <= 1: sb.Append($"\e[38;2;86;156;214m{token}\e[0m"); break; } break; case SyntaxKind.CommaToken: sb.Append(", "); break; case var k when (int)k is >= 8304 and <= 8319: sb.Append($"\e[38;2;255;123;114m{token}\e[0m"); break; default: sb.Append(token); break; } } public override string ToString() => sb.ToString(); enum IdentifierKind { Top, Parameter, TypeParameter, } }