diff --git a/CHANGELOG.md b/CHANGELOG.md index 73ea5b2c1e..fca84bb41e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Fixed +* Process is reserved keyword. [#2996](https://github.com/fsprojects/fantomas/issues/2996) * Always yield list items on separate lines if a conditional is present. [#2972](https://github.com/fsprojects/fantomas/issues/2972) ## 6.3.0-alpha-003 - 2023-11-15 diff --git a/src/Fantomas.Core.Tests/FunctionDefinitionTests.fs b/src/Fantomas.Core.Tests/FunctionDefinitionTests.fs index 5b0dc1223d..193e84a83c 100644 --- a/src/Fantomas.Core.Tests/FunctionDefinitionTests.fs +++ b/src/Fantomas.Core.Tests/FunctionDefinitionTests.fs @@ -111,43 +111,31 @@ let ``should keep identifiers with + in double backticks`` () = """ [] -let ``double backticks with non-alphanum character, 776`` () = +[] +[] +[] +[] +[] +[] +[] +[] +[foo hoo`` () = ()">] +[] +[] +[] +[] +[] +let ``double backticks with non-alphanum character, 776`` (input) = formatSourceString - """ -let ``!foo hoo`` () = () -let ``@foo hoo`` () = () -let ``$foo hoo`` () = () -let ``%foo hoo`` () = () -let ``^foo hoo`` () = () -let ``&foo hoo`` () = () -let ``*foo hoo`` () = () -let ``foo hoo`` () = () -let ``=foo hoo`` () = () -let ``-foo hoo`` () = () -let ``!foo hoo`` () : unit = () -let ``@foo hoo`` = () -let ``$foo hoo`` : unit = () + $""" +%s{input} """ config |> prepend newline |> should equal - """ -let ``!foo hoo`` () = () -let ``@foo hoo`` () = () -let ``$foo hoo`` () = () -let ``%foo hoo`` () = () -let ``^foo hoo`` () = () -let ``&foo hoo`` () = () -let ``*foo hoo`` () = () -let ``foo hoo`` () = () -let ``=foo hoo`` () = () -let ``-foo hoo`` () = () -let ``!foo hoo`` () : unit = () -let ``@foo hoo`` = () -let ``$foo hoo``: unit = () + $""" +%s{input} """ [] diff --git a/src/Fantomas.Core.Tests/IdentTests.fs b/src/Fantomas.Core.Tests/IdentTests.fs index c83c7ff74d..01d5545813 100644 --- a/src/Fantomas.Core.Tests/IdentTests.fs +++ b/src/Fantomas.Core.Tests/IdentTests.fs @@ -80,3 +80,17 @@ let ``process`` = 1 """ let ``process`` = 1 """ + +[] +let ``allows processing when encountering reserved words`` () = + formatSourceString + """ +let process: IProcess = importAll "process" +""" + config + |> prepend newline + |> should + equal + """ +let process: IProcess = importAll "process" +""" diff --git a/src/Fantomas.Core/Utils.fs b/src/Fantomas.Core/Utils.fs index 320f31faea..9e17f4dd7e 100644 --- a/src/Fantomas.Core/Utils.fs +++ b/src/Fantomas.Core/Utils.fs @@ -5,6 +5,7 @@ open Microsoft.FSharp.Core.CompilerServices [] module String = + let startsWithOrdinal (prefix: string) (str: string) = str.StartsWith(prefix, StringComparison.Ordinal) diff --git a/src/Fantomas.Core/Validation.fs b/src/Fantomas.Core/Validation.fs index 01d78a9583..843b3b3205 100644 --- a/src/Fantomas.Core/Validation.fs +++ b/src/Fantomas.Core/Validation.fs @@ -5,24 +5,28 @@ open Fantomas.FCS.Text open Fantomas.FCS.Syntax open Fantomas.FCS.Parse -let private safeToIgnoreWarnings = +// See https://github.com/dotnet/fsharp/blob/2a25184293e39a635217670652b00680de04472a/src/Compiler/Driver/CompilerDiagnostics.fs#L214 +// and https://github.com/dotnet/fsharp/blob/b7e747921515ae7939c7cb6885513eb80ec7ca2f/src/Compiler/FSComp.txt +// for error codes +let safeToIgnoreWarnings = set - [ "This construct is deprecated: it is only for use in the F# library" - "Identifiers containing '@' are reserved for use in F# code generation" ] - -// Exception of type 'Fantomas.FCS.DiagnosticsLogger+LibraryUseOnly' was thrown. + [ 35 // Deprecated + 42 // LibraryUseOnly + 46 // ReservedKeyword + 1104 ] // lexhlpIdentifiersContainingAtSymbolReserved let noWarningOrErrorDiagnostics diagnostics = - let errors = - diagnostics - |> List.filter (fun e -> - match e.Severity with - | FSharpDiagnosticSeverity.Error -> true - | FSharpDiagnosticSeverity.Hidden - | FSharpDiagnosticSeverity.Info -> false - | FSharpDiagnosticSeverity.Warning -> not (safeToIgnoreWarnings.Contains(e.Message))) - - List.isEmpty errors + diagnostics + |> List.filter (fun e -> + match e.Severity with + | FSharpDiagnosticSeverity.Error -> true + | FSharpDiagnosticSeverity.Hidden + | FSharpDiagnosticSeverity.Info -> false + | FSharpDiagnosticSeverity.Warning -> + match e.ErrorNumber with + | None -> true + | Some errorNumber -> not (safeToIgnoreWarnings.Contains(errorNumber))) + |> List.isEmpty /// Check whether an input string is invalid in F# by looking for errors and warnings in the diagnostics. let isValidFSharpCode (isSignature: bool) (source: string) : Async = diff --git a/src/Fantomas.FCS/Parse.fs b/src/Fantomas.FCS/Parse.fs index 892f6640c6..30e01eb7f4 100644 --- a/src/Fantomas.FCS/Parse.fs +++ b/src/Fantomas.FCS/Parse.fs @@ -1049,12 +1049,15 @@ let parseFile let diagnostics = List.map (fun (p, severity) -> + // See https://github.com/dotnet/fsharp/blob/2a25184293e39a635217670652b00680de04472a/src/Compiler/Driver/CompilerDiagnostics.fs#L214 + // for the error codes let range, message, errorNumber = match p.Exception with | :? IndentationProblem as ip -> Some ip.Data1, ip.Data0, Some 58 | :? SyntaxError as se -> Some se.range, (getSyntaxErrorMessage se.Data0), Some 10 | :? LibraryUseOnly as luo -> Some luo.range, LibraryUseOnlyE().Format, Some 42 | :? DiagnosticWithText as dwt -> Some dwt.range, dwt.message, Some dwt.number + | :? ReservedKeyword as rkw -> Some rkw.Data1, rkw.Data0, Some 46 | _ -> None, p.Exception.Message, None { Severity = severity