Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse Exception When Using Preprocessor Directives #3143

Closed
4 tasks
1eyewonder opened this issue Dec 17, 2024 · 6 comments
Closed
4 tasks

Parse Exception When Using Preprocessor Directives #3143

1eyewonder opened this issue Dec 17, 2024 · 6 comments

Comments

@1eyewonder
Copy link

Issue created from fantomas-online

Code

#r "nuget: Expecto"

#if FABLE_COMPILER_PYTHON
open Fable.Pyxpecto
#endif
#if FABLE_COMPILER_JAVASCRIPT
open Fable.Mocha
#endif
#if !FABLE_COMPILER
open Expecto

[<Tests>] //needed for `dotnet test` to work
#endif
let allTests = testList "All Tests" [ ]

[<EntryPoint>]
let main argv =
#if FABLE_COMPILER_PYTHON
    Pyxpecto.runTests allTests
#endif
#if FABLE_COMPILER_JAVASCRIPT
    Mocha.runTests allTests
#endif
#if !FABLE_COMPILER
    Tests.runTestsWithCLIArgs [] argv allTests
#endif

Error

Fantomas.Core.ParseException: ParseException
  [{ Severity = Error
     SubCategory = "parse"
     Range = Some (26,0--26,6)
     ErrorNumber = Some 58
     Message =
      "Unexpected syntax or possible incorrect indentation: this token is offside of context started at position (17:1). Try indenting this further.
To continue using non-conforming indentation, pass the '--strict-indentation-' flag to the compiler, or set the language version to F# 7." };
   { Severity = Error
     SubCategory = "parse"
     Range = Some (26,0--26,6)
     ErrorNumber = Some 10
     Message =
      "Incomplete structured construct at or before this point in binding" }]
   at Fantomas.Core.CodeFormatterImpl.parse@39-6.Invoke(Unit unitVar) in /_//src/Fantomas.Core/CodeFormatterImpl.fs:line 47
   at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvoke[T,TResult](AsyncActivation`1 ctxt, TResult result1, FSharpFunc`2 part2) in D:\a\_work\1\s\src\FSharp.Core\async.fs:line 508
   at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in D:\a\_work\1\s\src\FSharp.Core\async.fs:line 112

Problem description

When working on a PR over in FsToolkit.ErrorHandling, I came across this parse exception. Here is the link to the actual code. We are currently working around this by utilizing the .fantomasignore file.

Extra information

  • The formatted result breaks my code.
  • The formatted result gives compiler warnings.
  • I or my company would be willing to help fix this.
  • I would like a release if this problem is solved.

Options

Fantomas main branch at Dec 17, 2024

Default Fantomas configuration

Did you know that you can ignore files when formatting by using a .fantomasignore file?
PS: It's unlikely that someone else will solve your specific issue, as it's something that you have a personal stake in.

@nojaf
Copy link
Contributor

nojaf commented Dec 18, 2024

Hello, do all combinations of defines lead to valid code here?
If so, more information on what happens can be found in our docs.

Are you interested in submitting a PR for this?

@1eyewonder
Copy link
Author

I see what you mean in regards to all paths needing to be correct i.e. the main function needs to have a return if none of the flags are true. Adding the one line allows fantomas to parse correctly.

#r "nuget: Expecto"

#if FABLE_COMPILER_PYTHON
open Fable.Pyxpecto
#endif
#if FABLE_COMPILER_JAVASCRIPT
open Fable.Mocha
#endif
#if !FABLE_COMPILER
open Expecto

[<Tests>] //needed for `dotnet test` to work
#endif
let allTests = testList "All Tests" []

[<EntryPoint>]
let main argv =
    printfn "Running tests" // added for sanity
#if FABLE_COMPILER_PYTHON
    Pyxpecto.runTests allTests
#endif
#if FABLE_COMPILER_JAVASCRIPT
    Mocha.runTests allTests
#endif
#if !FABLE_COMPILER
    Tests.runTestsWithCLIArgs [] argv allTests
#endif

I did go through the exercise of refactoring where I would consider all paths as valid and ended up coming up with the below code. Changing some of the #ifs to #elifs makes more sense (at least to me) since I don't believe we can have more than one compiler directive at a time. However, fantomas does encounter some issues with this approach.

#r "nuget: Expecto"

#if FABLE_COMPILER_PYTHON
open Fable.Pyxpecto
#elif FABLE_COMPILER_JAVASCRIPT
open Fable.Mocha
#elif FABLE_COMPILER
#else
open Expecto
[<Tests>] //needed for `dotnet test` to work
#endif
let allTests = testList "All Tests" [ ]

[<EntryPoint>]
let main argv =
#if FABLE_COMPILER_PYTHON
    Pyxpecto.runTests allTests
#elif FABLE_COMPILER_JAVASCRIPT
    Mocha.runTests allTests
#elif FABLE_COMPILER
#else
    Tests.runTestsWithCLIArgs [] argv allTests
#endif

After running fantomas, I get the following:

[20:30:46 ERR] Failed to format file: test.fsx : ParseException
  [{ Severity = Error
     SubCategory = "parse"
     Range = Some (5,1--5,5)
     ErrorNumber = Some 10
     Message =
      "Unexpected keyword 'elif' in directive. Expected identifier or other token." };
   { Severity = Error
     SubCategory = "parse"
     Range = Some (7,1--7,5)
     ErrorNumber = Some 10
     Message =
      "Unexpected keyword 'elif' in directive. Expected identifier or other token." };
   { Severity = Error
     SubCategory = "parse"
     Range = Some (18,1--18,5)
     ErrorNumber = Some 10
     Message =
      "Unexpected keyword 'elif' in directive. Expected identifier or other token." }]

Peeking through the code I think this may be the area to start looking in regards to supporting #elif if we think that is a desired feature. Just let me know how I can help if we see the #elif as a desired feature and I can try submitting a PR 😄

@1eyewonder
Copy link
Author

Well that would be why it doesn't work then 😅
I will go ahead and update my code accordingly then. Thanks for the help

@nojaf
Copy link
Contributor

nojaf commented Dec 19, 2024

Alright, anything actionable left for Fantomas here?

@1eyewonder
Copy link
Author

Nope! I feel silly but happy I learned this about F#. I didn't know it had different directive support than C#

@nojaf nojaf closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants