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

Fable's JsInterop ? dynamic access operator causes formatting error #3135

Open
1 of 4 tasks
joprice opened this issue Nov 4, 2024 · 1 comment
Open
1 of 4 tasks

Comments

@joprice
Copy link
Contributor

joprice commented Nov 4, 2024

Issue created from fantomas-online

Code

Jest.expect(json)?oMatchSnapshot ()

Error

System.Exception: cannot determine if Expr AppLongIdentAndSingleParenArg
  Fantomas.Core.SyntaxOak+ExprAppLongIdentAndSingleParenArgNode is uppercase or lowercase
   at Microsoft.FSharp.Core.PrintfModule.PrintFormatToStringThenFail@1448.Invoke(String message)
   at Fantomas.Core.CodePrinter.sepSpaceBeforeParenInFuncInvocation(Expr functionExpr, Expr argExpr, Context ctx) in /_//src/Fantomas.Core/CodePrinter.fs:line 2549
   at Fantomas.Core.CodePrinter.genExpr@1036-197.Invoke(Context ctx)
   at Fantomas.Core.Context.op_PlusGreater(FSharpFunc`2 ctx, FSharpFunc`2 f, Context x) in /_//src/Fantomas.Core/Context.fs:line 430
   at Fantomas.Core.Context.shortExpressionWithFallback(FSharpFunc`2 shortExpression, FSharpFunc`2 fallbackExpression, Int32 maxWidth, FSharpOption`1 startColumn, Context ctx) in /_//src/Fantomas.Core/Context.fs:line 616
   at Fantomas.Core.Context.op_PlusGreater(FSharpFunc`2 ctx, FSharpFunc`2 f, Context x) in /_//src/Fantomas.Core/Context.fs:line 430
   at Fantomas.Core.Context.op_PlusGreater(FSharpFunc`2 ctx, FSharpFunc`2 f, Context x) in /_//src/Fantomas.Core/Context.fs:line 430
   at Fantomas.Core.Context.col[T](FSharpFunc`2 f', IEnumerable`1 c, FSharpFunc`2 f, Context ctx) in /_//src/Fantomas.Core/Context.fs:line 463
   at Fantomas.Core.CodePrinter.genFile@4066-4.Invoke(Context ctx)
   at Fantomas.Core.Context.op_PlusGreater(FSharpFunc`2 ctx, FSharpFunc`2 f, Context x) in /_//src/Fantomas.Core/Context.fs:line 430
   at Fantomas.Core.Context.op_PlusGreater(FSharpFunc`2 ctx, FSharpFunc`2 f, Context x) in /_//src/Fantomas.Core/Context.fs:line 430
   at Fantomas.Core.CodeFormatterImpl.formatAST(ParsedInput ast, FSharpOption`1 sourceText, FormatConfig config, FSharpOption`1 cursor) in /_//src/Fantomas.Core/CodeFormatterImpl.fs:line 74
   at Fantomas.Core.CodeFormatterImpl.formatDocument@89-3.Invoke(Unit unitVar) in /_//src/Fantomas.Core/CodeFormatterImpl.fs:line 89
   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 using the ? operator on the result of a tupled function call, a parse error is hit. A workaround is to call the first function without parens: (Jest.expect json)?oMatchSnapshot ()

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 11/04/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 Nov 5, 2024

Hello,

Thanks for reporting this problem!

You would need to extend

match expr with
| Expr.Ident ident -> upperOrLower ident.Text
| Expr.OptVar node -> lastFragmentInList node.Identifier
| Expr.Chain node ->
match List.tryLast node.Links with
| None
| Some(ChainLink.Dot _) -> LowercaseExpr
| Some(ChainLink.Identifier e)
| Some(ChainLink.Expr e) -> (|UppercaseExpr|LowercaseExpr|) e
| Some(ChainLink.AppParen appParen) -> (|UppercaseExpr|LowercaseExpr|) appParen.FunctionName
| Some(ChainLink.AppUnit appUnit) -> (|UppercaseExpr|LowercaseExpr|) appUnit.FunctionName
// Questionable
| Some(ChainLink.IndexExpr _) -> LowercaseExpr
| Expr.DotIndexedGet node -> (|UppercaseExpr|LowercaseExpr|) node.ObjectExpr
| Expr.TypeApp node -> (|UppercaseExpr|LowercaseExpr|) node.Identifier
| Expr.Dynamic node -> (|UppercaseExpr|LowercaseExpr|) node.FuncExpr
| Expr.AppSingleParenArg node -> (|UppercaseExpr|LowercaseExpr|) node.FunctionExpr
| Expr.Paren node -> (|UppercaseExpr|LowercaseExpr|) node.Expr
| Expr.App node -> (|UppercaseExpr|LowercaseExpr|) node.FunctionExpr
| _ -> failwithf "cannot determine if Expr %A is uppercase or lowercase" expr

with Expr.AppLongIdentAndSingleParenArg where you want to check the FunctionName I think.

Would you be interested in sending a PR for this?

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