fsprojects / fantomas

FSharp source code formatter
https://fsprojects.github.io/fantomas
Other
770 stars 194 forks source link

#ifdef #563

Open Smaug123 opened 4 years ago

Smaug123 commented 4 years ago

Issue created from fantomas-ui

This may be a known corollary of the #ifdef problems, but one more I ran across in our internal codebase.

It is perhaps reasonable to flag this as a place which might contain a syntax error under the appropriate #defines, but in this instance we were happy to assert that at least one of the #ifdefs would pass.

Code

module F =
  let a : string =
    #if FOO
    ""
    #endif
    #if BAR
    "a"
    #endif
  let baz : unit = ()

Error

Exception: Parsing failed with errors: [|tmp.fsx (9,3)-(9,6) parse error The block following this 'let' is unfinished. Every code block is an expression and must have a result. 'let' cannot be the final code element in a block. Consider giving this block an explicit result.|]
And options: { SourceFiles = [|"tmp.fsx"|]
  ConditionalCompilationDefines = []
  ErrorSeverityOptions = { WarnLevel = 3
                           GlobalWarnAsError = false
                           WarnOff = []
                           WarnOn = []
                           WarnAsError = []
                           WarnAsWarn = [] }
  IsInteractive = false
  LightSyntax = None
  CompilingFsLib = false
  IsExe = false } Stack Trace:    at Fantomas.CodeFormatterImpl.parse@61-2.Invoke(FSharpParseFileResults _arg2) in /build/.deps/fantomas/src/Fantomas/CodeFormatterImpl.fs:line 66
   at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvokeNoHijackCheck[a,b](AsyncActivation`1 ctxt, FSharpFunc`2 userCode, b result1) in E:\A\_work\130\s\src\fsharp\FSharp.Core\async.fs:line 416
   at <StartupCode$FSharp-Compiler-Service>.$Service.ParseFile@424-3.Invoke(AsyncActivation`1 ctxt)
   at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in E:\A\_work\130\s\src\fsharp\FSharp.Core\async.fs:line 109
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.FSharp.Control.AsyncResult`1.Commit() in E:\A\_work\130\s\src\fsharp\FSharp.Core\async.fs:line 349
   at Microsoft.FSharp.Control.AsyncPrimitives.RunSynchronouslyInCurrentThread[a](CancellationToken cancellationToken, FSharpAsync`1 computation) in E:\A\_work\130\s\src\fsharp\FSharp.Core\async.fs:line 870
   at Microsoft.FSharp.Control.AsyncPrimitives.RunSynchronously[T](CancellationToken cancellationToken, FSharpAsync`1 computation, FSharpOption`1 timeout) in E:\A\_work\130\s\src\fsharp\FSharp.Core\async.fs:line 890
   at Microsoft.FSharp.Control.FSharpAsync.RunSynchronously[T](FSharpAsync`1 computation, FSharpOption`1 timeout, FSharpOption`1 cancellationToken) in E:\A\_work\130\s\src\fsharp\FSharp.Core\async.fs:line 1153
   at Server.Result.attempt[a](FSharpFunc`2 f) in /build/src/Server/Server.fs:line 24

Options

Fantomas Next - 3.0.1-11/13/2019

Name Value
IndentOnTryWith false
IndentSpaceNum 4
KeepNewlineAfter false
PageWidth 120
ReorderOpenDeclaration false
SemicolonAtEndOfLine false
SpaceAfterComma false
SpaceAfterSemicolon false
SpaceAroundDelimiter false
SpaceBeforeArgument false
SpaceBeforeColon false
StrictMode false
nojaf commented 4 years ago

Fantomas will try to format this multiple times, I believe this fails in case you don't pass any defines to the compiler.

Then you end up with:

module F =
  let a : string =

  let baz : unit = ()

which looks like incorrect code to me so the behaviour seems correct at first glance. You miss at least one #else block I think.

Smaug123 commented 4 years ago

I agree, this is a bit of a grey area; it's possible to have an environment set up in such a way that the code will not compile. I guess this is a case where Fantomas could have done better, but perhaps it was unreasonable to expect it to.

nojaf commented 4 years ago

This seems like a nice case for .fantomasignore 😅.