Skip to content

Commit

Permalink
Remove getByLookup function in SourceTransformer.fs (fsprojects#1506)
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf authored Mar 6, 2021
1 parent 69fd7ea commit ba5b44e
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 84 deletions.
9 changes: 1 addition & 8 deletions src/Fantomas/CodeFormatterImpl.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ open Fantomas.FormatConfig
open Fantomas.SourceOrigin
open Fantomas.SourceParser
open Fantomas.CodePrinter
open System.IO

let private getSourceString (source: SourceOrigin) =
match source with
Expand Down Expand Up @@ -378,9 +377,6 @@ let isValidFSharpCode (checker: FSharpChecker) (parsingOptions: FSharpParsingOpt
}

let formatWith ast defines hashTokens formatContext config =
let moduleName =
Path.GetFileNameWithoutExtension formatContext.FileName

let sourceCodeOrEmptyString =
if String.IsNullOrWhiteSpace formatContext.Source then
String.Empty
Expand All @@ -392,10 +388,7 @@ let formatWith ast defines hashTokens formatContext config =
Context.Context.Create config defines formatContext.FileName hashTokens sourceCodeOrEmptyString (Some ast)

context
|> genParsedInput
{ ASTContext.Default with
TopLevelModuleName = moduleName }
ast
|> genParsedInput ASTContext.Default ast
|> Dbg.tee (fun ctx -> printfn "%A" ctx.WriterEvents)
|> Context.dump

Expand Down
37 changes: 24 additions & 13 deletions src/Fantomas/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ open Fantomas.TriviaContext

/// This type consists of contextual information which is important for formatting
type ASTContext =
{
/// Original file name without extension of the parsed AST
TopLevelModuleName: string
/// Current node is the first child of its parent
{ /// Current node is the first child of its parent
IsFirstChild: bool
/// Current node is a subnode deep down in an interface
InterfaceRange: Range option
Expand All @@ -35,8 +32,7 @@ type ASTContext =
/// Inside a SynPat of MatchClause
IsInsideMatchClausePattern: bool }
static member Default =
{ TopLevelModuleName = ""
IsFirstChild = false
{ IsFirstChild = false
InterfaceRange = None
IsCStylePattern = false
IsNakedRange = false
Expand Down Expand Up @@ -1688,8 +1684,22 @@ and genExpr astContext synExpr ctx =
+> genExpr astContext e

| Paren (_, ILEmbedded r, _, _) ->
// Just write out original code inside (# ... #)
fun ctx -> !- (defaultArg (lookup r ctx) "") ctx
fun ctx ->
let expr =
Map.tryFindOrEmptyList SynExpr_LibraryOnlyILAssembly ctx.TriviaMainNodes
|> List.choose
(fun tn ->
if RangeHelpers.rangeEq r tn.Range then
match tn.ContentItself with
| Some (EmbeddedIL eil) -> Some eil
| _ -> None
else
None)
|> List.tryHead
|> Option.map (!-)
|> Option.defaultValue sepNone

expr ctx
| Paren (lpr, e, rpr, pr) ->
match e with
| MultilineString _ ->
Expand Down Expand Up @@ -4086,9 +4096,6 @@ and genField astContext prefix (Field (ats, px, ao, isStatic, isMutable, t, so)
+> t
|> genTriviaFor Field_ range

and genTypeByLookup astContext (t: SynType) =
getByLookup t.Range (genType astContext false) t

and genType astContext outerBracket t =
let rec loop current =
match current with
Expand All @@ -4115,6 +4122,7 @@ and genType astContext outerBracket t =
// Do similar for tuples after an arrow
| TFun (t, TTuple ts) -> loop t +> sepArrow +> loopTTupleList ts
| TFuns ts -> col sepArrow ts loop
| TApp (TLongIdent ("nativeptr"), [ t ], true) when (astContext.IsCStylePattern) -> loop t -- "*"
| TApp (t, ts, isPostfix) ->
let postForm =
match ts with
Expand Down Expand Up @@ -4144,12 +4152,14 @@ and genType astContext outerBracket t =
| TWithGlobalConstraints (t, tcs) ->
loop t
+> colPre (!- " when ") wordAnd tcs (genTypeConstraint astContext)
| SynType.LongIdent (LongIdentWithDots.LongIdentWithDots ([ lid ], _)) when
(astContext.IsCStylePattern && lid.idText = "[]") -> !- "[]"
| TLongIdent s ->
ifElseCtx
(fun ctx ->
not ctx.Config.StrictMode
&& astContext.IsCStylePattern)
(genTypeByLookup astContext t)
(!-(if s = "unit" then "void" else s))
(!-s)
|> genTriviaFor Ident_ current.Range
| TAnonRecord (isStruct, fields) ->
Expand Down Expand Up @@ -4656,12 +4666,13 @@ and genPat astContext pat =
// We lookup sources to get extern types since it has quite many exceptions compared to normal F# types
ifElse
astContext.IsCStylePattern
(genTypeByLookup astContext t
(genType astContext false t
+> sepSpace
+> genPat astContext p)
(genPat astContext p
+> sepColon
+> atCurrentColumnIndent (genType astContext false t))

| PatNamed (ao, PatNullary PatWild, s) ->
opt sepSpace ao genAccess
+> infixOperatorFromTrivia pat.Range s
Expand Down
13 changes: 2 additions & 11 deletions src/Fantomas/Context.fs
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ type internal Context =
BreakOn: string -> bool
/// The original source string to query as a last resort
Content: string
/// Positions of new lines in the original source string
Positions: int []
TriviaMainNodes: Map<FsAstType, TriviaNode list>
TriviaTokenNodes: Map<FsTokenType, TriviaNode list>
RecordBraceStart: int list
Expand All @@ -175,7 +173,6 @@ type internal Context =
BreakLines = true
BreakOn = (fun _ -> false)
Content = ""
Positions = [||]
TriviaMainNodes = Map.empty
TriviaTokenNodes = Map.empty
RecordBraceStart = []
Expand All @@ -191,12 +188,6 @@ type internal Context =
=
let content = String.normalizeNewLine content

let positions =
content.Split('\n')
|> Seq.map (fun s -> String.length s + 1)
|> Seq.scan (+) 0
|> Seq.toArray

let tokens =
TokenParser.tokenize defines hashTokens content

Expand Down Expand Up @@ -234,7 +225,6 @@ type internal Context =
{ Context.Default with
Config = config
Content = content
Positions = positions
TriviaMainNodes = triviaByNodes
TriviaTokenNodes = triviaByTokenNames
FileName = fileName }
Expand Down Expand Up @@ -1146,7 +1136,8 @@ let internal printTriviaContent (c: TriviaContent) (ctx: Context) =
| StringContent _
| IdentOperatorAsWord _
| IdentBetweenTicks _
| CharContent _ -> sepNone // don't print here but somewhere in CodePrinter
| CharContent _
| EmbeddedIL _ -> sepNone // don't print here but somewhere in CodePrinter
| Directive (s)
| Comment (LineCommentOnSingleLine s) ->
(ifElse addNewline sepNln sepNone)
Expand Down
43 changes: 0 additions & 43 deletions src/Fantomas/SourceParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,6 @@ let MaxLength = 512
[<Literal>]
let private MangledGlobalName : string = "`global`"

/// Get source string content based on range value
let lookup (r: Range) (c: Context) =
if r.EndLine < c.Positions.Length then
let start =
c.Positions.[r.StartLine - 1] + r.StartColumn

let startLength =
c.Positions.[r.StartLine]
- c.Positions.[r.StartLine - 1]

let finish =
c.Positions.[r.EndLine - 1] + r.EndColumn - 1

let finishLength =
c.Positions.[r.EndLine]
- c.Positions.[r.EndLine - 1]

let content = c.Content
// Any line with more than 512 characters isn't reliable for querying
if start > finish
|| startLength >= MaxLength
|| finishLength >= MaxLength then
Debug.WriteLine("Can't lookup between start = {0} and finish = {1}", start, finish)
None
else
let s = content.[start..finish]
Debug.WriteLine("Content: {0} at start = {1}, finish = {2}", s, start, finish)

if s.Contains("\\\n") then
// Terrible hack to compensate the offset made by F# compiler
let last =
content.[c.Positions.[r.EndLine - 1]..finish]

let offset =
min (last.Length - last.TrimStart(' ').Length) (content.Length - finish - 1)

Debug.WriteLine("Content after patch: {0} with offset = {1}", s, offset)
Some content.[start..finish + offset]
else
Some s
else
None

let (|Ident|) (s: Ident) =
let ident = s.idText

Expand Down
9 changes: 0 additions & 9 deletions src/Fantomas/SourceTransformer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ let hasParenInPat =
| PatParen _ -> true
| _ -> false

let getByLookup range f x =
fun ctx ->
if ctx.Config.StrictMode then
f x ctx
else
match lookup range ctx with
| Some x' -> str x' ctx
| None -> f x ctx

// A few active patterns for printing purpose

let rec (|DoExprAttributesL|_|) =
Expand Down
44 changes: 44 additions & 0 deletions src/Fantomas/TokenParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,33 @@ let private collectComment (commentTokens: Token list) =
|> List.map (snd >> getContentFromTokens)
|> String.concat "\n"

let private (|EmbeddedILTokens|_|) (tokens: Token list) =
match tokens with
| { TokenInfo = { TokenName = "LPAREN"
CharClass = FSharpTokenCharKind.Delimiter } } :: { TokenInfo = { TokenName = "HASH"
CharClass = FSharpTokenCharKind.Delimiter } } :: { TokenInfo = { TokenName = "WHITESPACE"
CharClass = FSharpTokenCharKind.WhiteSpace } } :: rest ->
let embeddedTokens =
tokens
|> List.takeWhile
(fun t ->
not (
t.TokenInfo.CharClass = FSharpTokenCharKind.Delimiter
&& t.TokenInfo.TokenName = "RPAREN"
))

let lastTokens =
embeddedTokens.[(embeddedTokens.Length - 2)..]

match lastTokens with
| [ { TokenInfo = { TokenName = "WHITESPACE"
CharClass = FSharpTokenCharKind.WhiteSpace } };
{ TokenInfo = { TokenName = "HASH"
CharClass = FSharpTokenCharKind.Delimiter } } ] ->
Some(List.take (embeddedTokens.Length + 1) tokens, rest)
| _ -> None
| _ -> None

let rec private getTriviaFromTokensThemSelves
(mkRange: MkRange)
(allTokens: Token list)
Expand Down Expand Up @@ -876,6 +903,23 @@ let rec private getTriviaFromTokensThemSelves

getTriviaFromTokensThemSelves mkRange allTokens rest info

| EmbeddedILTokens (embeddedTokens, rest) ->
let content =
embeddedTokens
|> List.map (fun t -> t.Content)
|> String.concat String.Empty

let range =
let startT = embeddedTokens.Head
let endT = List.last embeddedTokens
// There is a one off problem in the range of SynExpr_LibraryOnlyILAssembly
mkRange (startT.LineNumber, startT.TokenInfo.LeftColumn) (endT.LineNumber, endT.TokenInfo.RightColumn + 1)

let info =
Trivia.Create(EmbeddedIL(content)) range
|> List.prependItem foundTrivia

getTriviaFromTokensThemSelves mkRange allTokens rest info
| _ :: rest -> getTriviaFromTokensThemSelves mkRange allTokens rest foundTrivia

| [] -> foundTrivia
Expand Down
9 changes: 9 additions & 0 deletions src/Fantomas/Trivia.fs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,15 @@ let private addTriviaToTriviaNode
&& t.Range.StartLine = range.StartLine)
|> updateTriviaNode (fun tn -> tn.ContentItself <- Some iNode) triviaNodes

| { Item = EmbeddedIL _ as eil
Range = range } ->
triviaNodes
|> List.tryFind
(fun t ->
match t.Type with
| MainNode (SynExpr_LibraryOnlyILAssembly) -> RangeHelpers.rangeEq t.Range range
| _ -> false)
|> updateTriviaNode (fun tn -> tn.ContentItself <- Some eil) triviaNodes
| _ -> triviaNodes

let private triviaNodeIsNotEmpty (triviaNode: TriviaNodeAssigner) =
Expand Down
1 change: 1 addition & 0 deletions src/Fantomas/TriviaTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type TriviaContent =
| Newline
| Directive of directive: string
| CharContent of string
| EmbeddedIL of string

type Trivia =
{ Item: TriviaContent
Expand Down

0 comments on commit ba5b44e

Please sign in to comment.