forked from fsprojects/fantomas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TriviaContext.fs
88 lines (74 loc) · 3.36 KB
/
TriviaContext.fs
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
module internal Fantomas.TriviaContext
open Fantomas
open Fantomas.Context
open Fantomas.TriviaTypes
open FSharp.Compiler.Range
open FSharp.Compiler.SyntaxTree
let node (range: range) (s: string) =
enterNode range +> (!-s) +> leaveNode range
let tok (range: range) (s: string) =
enterNodeToken range +> (!-s) +> leaveNodeToken range
let tokN (range: range) (tokenName: string) f =
enterNodeTokenByName range tokenName +> f +> leaveNodeTokenByName range tokenName
let firstNewlineOrComment (es: SynExpr list) (ctx: Context) =
es
|> List.tryHead
|> Option.bind (fun e -> TriviaHelpers.findByRange ctx.Trivia e.Range)
|> fun cb ->
match cb with
| Some ({ ContentBefore = (TriviaContent.Newline|TriviaContent.Comment _) as head ::rest } as tn) ->
let updatedTriviaNodes =
ctx.Trivia
|> List.map (fun t ->
if t = tn then
{ tn with ContentBefore = rest }
else t
)
let ctx' = { ctx with Trivia = updatedTriviaNodes }
printTriviaContent head ctx'
| _ -> sepNone ctx
let triviaAfterArrow (range: range) (ctx: Context) =
let hasCommentAfterArrow =
findTriviaTokenFromName range ctx.Trivia "RARROW"
|> Option.bind (fun t ->
t.ContentAfter
|> List.tryFind (function | Comment(LineCommentAfterSourceCode(_)) -> true | _ -> false)
)
|> Option.isSome
((tokN range "RARROW" sepArrow) +> ifElse hasCommentAfterArrow sepNln sepNone) ctx
let ``else if / elif`` (rangeOfIfThenElse: range) (ctx: Context) =
let keywords =
ctx.Trivia
|> TriviaHelpers.``keyword tokens inside range`` ["ELSE";"IF";"ELIF"] rangeOfIfThenElse
|> List.map (fun (tok, t) -> (tok.TokenName, t))
let resultExpr =
match keywords with
| ("ELSE", elseTrivia)::("IF", ifTrivia)::_ ->
let commentAfterElseKeyword = TriviaHelpers.``has line comment after`` elseTrivia
let commentAfterIfKeyword = TriviaHelpers.``has line comment after`` ifTrivia
let triviaBeforeIfKeyword =
ctx.Trivia
|> List.filter (fun t ->
match t.Type with
| MainNode("SynExpr.IfThenElse") ->
RangeHelpers.``range contains`` rangeOfIfThenElse t.Range
&& (RangeHelpers.``range after`` elseTrivia.Range t.Range)
| _ -> false
)
|> List.tryHead
tokN rangeOfIfThenElse "ELSE" (!- "else") +>
ifElse commentAfterElseKeyword sepNln sepSpace +>
opt sepNone triviaBeforeIfKeyword printContentBefore +>
tokN rangeOfIfThenElse "IF" (!- "if ") +>
ifElse commentAfterIfKeyword (indent +> sepNln) sepNone
| ("ELIF",elifTok)::_
| [("ELIF",elifTok)] ->
let commentAfterElIfKeyword = TriviaHelpers.``has line comment after`` elifTok
tokN rangeOfIfThenElse "ELIF" (!- "elif ")
+> ifElse commentAfterElIfKeyword (indent +> sepNln) sepNone
| [] ->
// formatting from AST
!- "else if "
| _ ->
failwith "Unexpected scenario when formatting else if / elif, please open an issue via https://jindraivanek.gitlab.io/fantomas-ui"
resultExpr ctx