Skip to content

Commit

Permalink
Improve trivia handling for SynModuleSigDecl. Fixes #2258. (#2259)
Browse files Browse the repository at this point in the history
  • Loading branch information
nojaf committed May 16, 2022
1 parent 6f2d87e commit d053c38
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 16 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [Unreleased]

### Fixed
* Idempotency problem with ParsedHashDirective in signature file. [#2258](https://github.com/fsprojects/fantomas/issues/2258)

## [5.0.0-alpha-007] - 2022-05-16

### Changed
Expand Down
87 changes: 87 additions & 0 deletions src/Fantomas.Core.Tests/HashDirectiveTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,90 @@ let ``don't print trivia of other hash directive, 1464`` () =
#r "nuget: Giraffe"
"""

[<Test>]
let ``trivia before hash directive in signature file, 2258`` () =
formatSourceString
true
"""
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Tokenization
open System
open System.Threading
open FSharp.Compiler
open FSharp.Compiler.Text
#nowarn "57"
/// Represents encoded information for the end-of-line continuation of lexing
[<Struct; CustomEquality; NoComparison>]
type FSharpTokenizerLexState =
{ PosBits: int64
OtherBits: int64 }
static member Initial: FSharpTokenizerLexState
member Equals: FSharpTokenizerLexState -> bool
/// Represents stable information for the state of the lexing engine at the end of a line
type FSharpTokenizerColorState =
| Token = 1
| IfDefSkip = 3
| String = 4
| Comment = 5
| StringInComment = 6
| VerbatimStringInComment = 7
| CamlOnly = 8
| VerbatimString = 9
| SingleLineComment = 10
| EndLineThenSkip = 11
| EndLineThenToken = 12
| TripleQuoteString = 13
| TripleQuoteStringInComment = 14
| InitialState = 0
"""
config
|> prepend newline
|> should
equal
"""
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Tokenization
open System
open System.Threading
open FSharp.Compiler
open FSharp.Compiler.Text
#nowarn "57"
/// Represents encoded information for the end-of-line continuation of lexing
[<Struct; CustomEquality; NoComparison>]
type FSharpTokenizerLexState =
{ PosBits: int64
OtherBits: int64 }
static member Initial: FSharpTokenizerLexState
member Equals: FSharpTokenizerLexState -> bool
/// Represents stable information for the state of the lexing engine at the end of a line
type FSharpTokenizerColorState =
| Token = 1
| IfDefSkip = 3
| String = 4
| Comment = 5
| StringInComment = 6
| VerbatimStringInComment = 7
| CamlOnly = 8
| VerbatimString = 9
| SingleLineComment = 10
| EndLineThenSkip = 11
| EndLineThenToken = 12
| TripleQuoteString = 13
| TripleQuoteStringInComment = 14
| InitialState = 0
"""
5 changes: 4 additions & 1 deletion src/Fantomas.Core/AstTransformer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,10 @@ module private Ast =
|> finalContinuation

Continuation.sequence continuations finalContinuation
| SynModuleSigDecl.Val (SynValSig.SynValSig _ as node, _) -> visitSynValSig node |> finalContinuation
| SynModuleSigDecl.Val (SynValSig.SynValSig _ as node, range) ->
[ yield mkNode SynModuleSigDecl_Val range
yield! visitSynValSig node ]
|> finalContinuation
| SynModuleSigDecl.Types (typeDefs, range) ->
mkNode SynModuleSigDecl_Types range
:: (List.collect visitSynTypeDefnSig typeDefs)
Expand Down
36 changes: 23 additions & 13 deletions src/Fantomas.Core/CodePrinter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ and genSigModuleOrNamespace
match mdl with
| SynModuleSigDecl.Types _ ->
sepNlnConsideringTriviaContentBeforeForMainNode SynModuleSigDecl_Types mdl.Range
| SynModuleSigDecl.Val _ -> sepNlnConsideringTriviaContentBeforeForMainNode SynValSig_ mdl.Range
| SynModuleSigDecl.Val _ -> sepNlnConsideringTriviaContentBeforeForMainNode SynModuleSigDecl_Val mdl.Range
| _ -> sepNone
+> sepNln

Expand Down Expand Up @@ -210,9 +210,11 @@ and genModuleDeclList astContext e =
| OpenL (xs, ys) ->
let expr = col sepNln xs (genModuleDecl astContext)

let r = List.head xs |> fun mdl -> mdl.Range
let r, triviaType =
List.head xs
|> fun mdl -> mdl.Range, synModuleDeclToFsAstType mdl
// SynModuleDecl.Open cannot have attributes
let sepNln = sepNlnConsideringTriviaContentBeforeForMainNode SynModuleDecl_Open r
let sepNln = sepNlnConsideringTriviaContentBeforeForMainNode triviaType r

collectItems ys (fun ysItems ->
ColMultilineItem(expr, sepNln) :: ysItems
Expand Down Expand Up @@ -267,13 +269,28 @@ and genSigModuleDeclList astContext (e: SynModuleSigDecl list) =
| SigOpenL (xs, ys) ->
let expr = col sepNln xs (genSigModuleDecl astContext)

let r = List.head xs |> fun mdl -> mdl.Range
let r, triviaType =
List.head xs
|> fun mdl -> mdl.Range, synModuleSigDeclToFsAstType mdl
// SynModuleSigDecl.Open cannot have attributes
let sepNln = sepNlnConsideringTriviaContentBeforeForMainNode SynModuleSigDecl_Open r
let sepNln = sepNlnConsideringTriviaContentBeforeForMainNode triviaType r

collectItems ys (fun ysItems ->
ColMultilineItem(expr, sepNln) :: ysItems
|> finalContinuation)

| SigHashDirectiveL (xs, ys) ->
let expr = col sepNln xs (genSigModuleDecl astContext)

let r = List.head xs |> fun mdl -> mdl.Range

let sepNln =
sepNlnConsideringTriviaContentBeforeForMainNode SynModuleSigDecl_HashDirective r

collectItems ys (fun ysItems ->
ColMultilineItem(expr, sepNln) :: ysItems
|> finalContinuation)

| s :: rest ->
let sepNln =
sepNlnConsideringTriviaContentBeforeForMainNode (synModuleSigDeclToFsAstType s) s.Range
Expand Down Expand Up @@ -434,14 +451,7 @@ and genSigModuleDecl astContext node =

colWithNlnWhenItemIsMultilineUsingConfig items
| md -> failwithf "Unexpected module signature declaration: %O" md
|> (match node with
| SynModuleSigDecl.Types _ -> genTriviaFor SynModuleSigDecl_Types node.Range
| SynModuleSigDecl.NestedModule _ -> genTriviaFor SynModuleSigDecl_NestedModule node.Range
| SynModuleSigDecl.Open (SynOpenDeclTarget.ModuleOrNamespace _, _) ->
genTriviaFor SynModuleSigDecl_Open node.Range
| SynModuleSigDecl.Open (SynOpenDeclTarget.Type _, _) -> genTriviaFor SynModuleSigDecl_OpenType node.Range
| SynModuleSigDecl.Exception _ -> genTriviaFor SynModuleSigDecl_Exception node.Range
| _ -> id)
|> genTriviaFor (synModuleSigDeclToFsAstType node) node.Range

and genIdent (ident: Ident) =
let width =
Expand Down
5 changes: 3 additions & 2 deletions src/Fantomas.Core/SourceTransformer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,12 @@ let rec synExprToFsAstType (expr: SynExpr) : FsAstType * Range =

let synModuleSigDeclToFsAstType =
function
| SynModuleSigDecl.Val _ -> SynValSig_
| SynModuleSigDecl.Val _ -> SynModuleSigDecl_Val
| SynModuleSigDecl.Exception _ -> SynModuleSigDecl_Exception
| SynModuleSigDecl.NestedModule _ -> SynModuleSigDecl_NestedModule
| SynModuleSigDecl.Types _ -> SynModuleSigDecl_Types
| SynModuleSigDecl.Open _ -> SynModuleSigDecl_Open
| SynModuleSigDecl.Open (SynOpenDeclTarget.ModuleOrNamespace _, _) -> SynModuleSigDecl_Open
| SynModuleSigDecl.Open (SynOpenDeclTarget.Type _, _) -> SynModuleSigDecl_OpenType
| SynModuleSigDecl.HashDirective _ -> SynModuleSigDecl_HashDirective
| SynModuleSigDecl.NamespaceFragment _ -> SynModuleSigDecl_NamespaceFragment
| SynModuleSigDecl.ModuleAbbrev _ -> SynModuleSigDecl_ModuleAbbrev
Expand Down
1 change: 1 addition & 0 deletions src/Fantomas.Core/TriviaTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ type FsAstType =
| SynModuleOrNamespaceSig_DeclaredNamespace
| SynModuleOrNamespaceSig_GlobalNamespace
| SynModuleOrNamespaceSig_NamedModule
| SynModuleSigDecl_Val
| SynModuleSigDecl_ModuleAbbrev
| SynModuleSigDecl_NestedModule
| SynModuleSigDecl_NestedModule_Module
Expand Down

0 comments on commit d053c38

Please sign in to comment.