Created
April 12, 2018 20:07
-
-
Save praeclarum/79470aa146f3fccadff0ac4cc7c89fa2 to your computer and use it in GitHub Desktop.
Formats C# code using roslyn syntax and semantics
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
let getRefInfo (x : SyntaxNode) (ident : SyntaxToken) (isO : bool) = | |
let si = semantics.GetSymbolInfo (x) | |
if si.Symbol <> null then | |
Some (ident, si.Symbol, true, isO) | |
else None | |
let getDefInfo (x : SyntaxNode) (ident : SyntaxToken) (isO : bool) = | |
let s = semantics.GetDeclaredSymbol (x) | |
if s <> null then | |
Some (ident, s, false, isO) | |
else None | |
let f : uint16[] = Array.zeroCreate text.Length | |
let rec paintNode (x : SyntaxNode) = | |
cancellationToken.ThrowIfCancellationRequested () | |
// printfn "PAINT NODE %O" (x.GetType()) | |
for c in x.ChildNodesAndTokens() do | |
if c.IsToken then paintToken (c.AsToken()) | |
else paintNode (c.AsNode()) | |
let tkos = | |
let refInfo = | |
match x with | |
| :? CSharp.Syntax.IdentifierNameSyntax as y -> | |
//printfn "IDENT `%O` (%O) (%O)" x.Identifier s k | |
getRefInfo x y.Identifier false | |
| :? CSharp.Syntax.GenericNameSyntax as y -> | |
//printfn "IDENT `%O` (%O) (%O)" x.Identifier s k | |
getRefInfo x y.Identifier false | |
| :? CSharp.Syntax.PredefinedTypeSyntax as y -> | |
getRefInfo x y.Keyword false | |
| :? CSharp.Syntax.BinaryExpressionSyntax as y -> | |
getRefInfo x y.OperatorToken false | |
| :? CSharp.Syntax.PostfixUnaryExpressionSyntax as y -> | |
getRefInfo x y.OperatorToken false | |
| :? CSharp.Syntax.PrefixUnaryExpressionSyntax as y -> | |
getRefInfo x y.OperatorToken false | |
| _ -> | |
//Debug.WriteLine (sprintf "SYM `%O` (%O)" x (x.GetType())) | |
None | |
if Option.isSome refInfo then refInfo | |
else | |
match x with | |
| :? CSharp.Syntax.ClassDeclarationSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.StructDeclarationSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.EnumDeclarationSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.EnumMemberDeclarationSyntax as y -> | |
getDefInfo x y.Identifier true | |
| :? CSharp.Syntax.MethodDeclarationSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.ConstructorDeclarationSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.PropertyDeclarationSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.AccessorDeclarationSyntax as y -> | |
getDefInfo x y.Keyword false | |
| :? CSharp.Syntax.ParameterSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.VariableDeclaratorSyntax as y -> | |
getDefInfo x y.Identifier false | |
| :? CSharp.Syntax.TypeParameterSyntax as y -> | |
getDefInfo x y.Identifier false | |
| _ -> | |
//Debug.WriteLine (sprintf "DSYM `%O` (%O)" x (x.GetType())) | |
None | |
match tkos with | |
| None -> () | |
| Some (t, k, r, ef) -> | |
let code = if t.Text = "var" then FormatCode.Keyword | |
else getFormatCodeForSymbol k r ef | |
paint t code | |
and paint (x : SyntaxToken) (code : FormatCode) = | |
let span = x.Span | |
// printfn "PAINT TOKEN %O %A %d %d" x kind i len | |
for i = span.Start to (span.End-1) do | |
f.[i] <- uint16 code | |
and paintToken (x : SyntaxToken) = | |
let kind : CSharp.SyntaxKind = LanguagePrimitives.EnumOfValue (uint16 x.RawKind) | |
// https://github.com/dotnet/roslyn/blob/master/src/Compilers/CSharp/Portable/Syntax/SyntaxKind.cs | |
let code = | |
match x.RawKind with | |
| 8508 -> | |
FormatCode.Identifier | |
| 8509 -> FormatCode.Number | |
| 8510 -> FormatCode.String // Char | |
| 8482 | 8483 | 8484 | 8517 -> FormatCode.String // Interpolated String | |
| 8511 -> FormatCode.String | |
| 8513 -> FormatCode.String // XML Text | |
| x when 8300 <= x && x <= 8485 -> FormatCode.Keyword | |
| _ -> | |
//let kind : CSharp.SyntaxKind = LanguagePrimitives.EnumOfValue (uint16 x.RawKind) | |
//printfn "BAD %A" kind | |
FormatCode.Punctuation | |
paint x code | |
for t in x.GetAllTrivia () do | |
let code = | |
match t.Kind() with | |
| SyntaxKind.MultiLineDocumentationCommentTrivia | |
| SyntaxKind.DocumentationCommentExteriorTrivia | |
| SyntaxKind.SingleLineDocumentationCommentTrivia -> | |
FormatCode.DocumentationComment | |
| SyntaxKind.MultiLineCommentTrivia | |
| SyntaxKind.SingleLineCommentTrivia -> | |
FormatCode.Comment | |
| SyntaxKind.RegionDirectiveTrivia | |
| SyntaxKind.EndRegionDirectiveTrivia | |
| SyntaxKind.PragmaWarningDirectiveTrivia | |
| SyntaxKind.PragmaChecksumDirectiveTrivia | |
| SyntaxKind.ErrorDirectiveTrivia | |
| SyntaxKind.IfDirectiveTrivia | |
| SyntaxKind.DefineDirectiveTrivia | |
| SyntaxKind.ElifDirectiveTrivia | |
| SyntaxKind.ElseDirectiveTrivia | |
| SyntaxKind.EndIfDirectiveTrivia -> | |
FormatCode.Preprocessor | |
| SyntaxKind.DisabledTextTrivia -> | |
FormatCode.DisabledCode | |
| kind -> | |
//printfn "BAD TRIVIA %A" kind | |
FormatCode.Text | |
if code <> FormatCode.Text then | |
let span = t.FullSpan | |
for i = span.Start to (span.End-1) do | |
f.[i] <- uint16 code | |
paintNode (syntax.GetRoot()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment