From 0caefea8bbb187586387a9e544c89de83f62a468 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Tue, 3 Jun 2025 16:18:53 +0000 Subject: [PATCH 01/11] adaptations for sdk 9.0 and 10.0 --- Directory.Build.props | 2 +- Directory.Packages.props | 2 +- build.fsx | 4 + global.json | 2 +- src/Fantomas.Benchmarks/packages.lock.json | 10 +- src/Fantomas.Client.Tests/packages.lock.json | 8 +- src/Fantomas.Client/packages.lock.json | 6 +- .../ASTTransformerTests.fs | 4 +- .../AutoPropertiesTests.fs | 2 +- src/Fantomas.Core.Tests/CommentTests.fs | 5 + src/Fantomas.Core.Tests/HashDirectiveTests.fs | 3 +- src/Fantomas.Core.Tests/SynLongIdentTests.fs | 4 +- src/Fantomas.Core.Tests/packages.lock.json | 10 +- src/Fantomas.Core/ASTTransformer.fs | 47 +++--- src/Fantomas.Core/Trivia.fs | 43 +++--- src/Fantomas.Core/packages.lock.json | 8 +- src/Fantomas.FCS/Fantomas.FCS.fsproj | 16 +- src/Fantomas.FCS/Parse.fs | 137 +++++------------- src/Fantomas.FCS/packages.lock.json | 6 +- src/Fantomas.Tests/packages.lock.json | 14 +- src/Fantomas/packages.lock.json | 12 +- 21 files changed, 154 insertions(+), 191 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 26e34508ab..1d03c11ff1 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ Some common use cases include: - e668b90e3c087e5fba8a855e502af60bf35be45e + 20ff6a94300b5f2f5498d3d8ad1a44abaabc5c22 diff --git a/Directory.Packages.props b/Directory.Packages.props index 084fea47dc..878be9ff50 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,7 +4,7 @@ true - + diff --git a/build.fsx b/build.fsx index 63c8458d3a..6c4a2f0e08 100644 --- a/build.fsx +++ b/build.fsx @@ -301,6 +301,10 @@ pipeline "Init" { "src/Compiler/SyntaxTree/SyntaxTree.fs" "src/Compiler/SyntaxTree/SyntaxTreeOps.fsi" "src/Compiler/SyntaxTree/SyntaxTreeOps.fs" + "src/Compiler/SyntaxTree/WarnScopes.fsi" + "src/Compiler/SyntaxTree/WarnScopes.fs" + "src/Compiler/SyntaxTree/LexerStore.fsi" + "src/Compiler/SyntaxTree/LexerStore.fs" "src/Compiler/SyntaxTree/ParseHelpers.fsi" "src/Compiler/SyntaxTree/ParseHelpers.fs" "src/Compiler/SyntaxTree/LexHelpers.fsi" diff --git a/global.json b/global.json index 6f6aff9de6..d3dbe09378 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.400", + "version": "9.0.300", "rollForward": "latestPatch" } } \ No newline at end of file diff --git a/src/Fantomas.Benchmarks/packages.lock.json b/src/Fantomas.Benchmarks/packages.lock.json index cc618a9806..664a872c78 100644 --- a/src/Fantomas.Benchmarks/packages.lock.json +++ b/src/Fantomas.Benchmarks/packages.lock.json @@ -28,9 +28,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "G-Research.FSharp.Analyzers": { "type": "Direct", @@ -272,14 +272,14 @@ "fantomas.core": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "Fantomas.FCS": "[1.0.0, )" } }, "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "System.Collections.Immutable": "[8.0.0, )", "System.Diagnostics.DiagnosticSource": "[8.0.1, )", "System.Memory": "[4.6.0, )", diff --git a/src/Fantomas.Client.Tests/packages.lock.json b/src/Fantomas.Client.Tests/packages.lock.json index 6bbec117ff..54e3169b0b 100644 --- a/src/Fantomas.Client.Tests/packages.lock.json +++ b/src/Fantomas.Client.Tests/packages.lock.json @@ -16,9 +16,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "G-Research.FSharp.Analyzers": { "type": "Direct", @@ -137,7 +137,7 @@ "fantomas.client": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "SemanticVersioning": "[2.0.2, )", "StreamJsonRpc": "[2.20.20, )" } diff --git a/src/Fantomas.Client/packages.lock.json b/src/Fantomas.Client/packages.lock.json index 65f0ab5696..c1c97d0b32 100644 --- a/src/Fantomas.Client/packages.lock.json +++ b/src/Fantomas.Client/packages.lock.json @@ -22,9 +22,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "G-Research.FSharp.Analyzers": { "type": "Direct", diff --git a/src/Fantomas.Core.Tests/ASTTransformerTests.fs b/src/Fantomas.Core.Tests/ASTTransformerTests.fs index 498f9c86c5..41a5b7c9e0 100644 --- a/src/Fantomas.Core.Tests/ASTTransformerTests.fs +++ b/src/Fantomas.Core.Tests/ASTTransformerTests.fs @@ -40,7 +40,6 @@ let ``avoid stack-overflow in long array/list, 2485`` () = true, QualifiedNameOfFile(Ident("", Range.Zero)), [], - [], [ SynModuleOrNamespace( [], false, @@ -53,8 +52,7 @@ let ``avoid stack-overflow in long array/list, 2485`` () = { LeadingKeyword = SynModuleOrNamespaceLeadingKeyword.None } ) ], (false, false), - { ConditionalDirectives = [] - CodeComments = [] }, + ParsedInputTrivia.Empty, Set.empty ) ) diff --git a/src/Fantomas.Core.Tests/AutoPropertiesTests.fs b/src/Fantomas.Core.Tests/AutoPropertiesTests.fs index ab6a962df9..8600920912 100644 --- a/src/Fantomas.Core.Tests/AutoPropertiesTests.fs +++ b/src/Fantomas.Core.Tests/AutoPropertiesTests.fs @@ -74,7 +74,7 @@ type X = member internal Y: int with public get, private set """ -[] +[] let ``abstract member with public get, private set`` () = formatSignatureString """ diff --git a/src/Fantomas.Core.Tests/CommentTests.fs b/src/Fantomas.Core.Tests/CommentTests.fs index e3285e3e3c..228d01bb09 100644 --- a/src/Fantomas.Core.Tests/CommentTests.fs +++ b/src/Fantomas.Core.Tests/CommentTests.fs @@ -5,6 +5,11 @@ open FsUnit open Fantomas.Core.Tests.TestHelpers open Fantomas.Core +[] +let ``should keep sticky-to-the-left comments after #if directivesXXX`` () = + formatSourceString "#if DEBUG // debug only\n#endif\n" config + |> should equal "#if DEBUG // debug only\n#endif\n" + [] let ``should keep sticky-to-the-left comments after nowarn directives`` () = formatSourceString """#nowarn "51" // address-of operator can occur in the code""" config diff --git a/src/Fantomas.Core.Tests/HashDirectiveTests.fs b/src/Fantomas.Core.Tests/HashDirectiveTests.fs index 233b10aee6..0edfeb5d08 100644 --- a/src/Fantomas.Core.Tests/HashDirectiveTests.fs +++ b/src/Fantomas.Core.Tests/HashDirectiveTests.fs @@ -248,6 +248,7 @@ let ``#help without string`` () = #help List.map """ +// As of F# 10.0, warn directives are treated as trivia like #if, so argruments are not formatted [] let ``#nowarn with integer`` () = formatSourceString @@ -259,5 +260,5 @@ let ``#nowarn with integer`` () = |> should equal """ -#nowarn 1182 +#nowarn 1182 """ diff --git a/src/Fantomas.Core.Tests/SynLongIdentTests.fs b/src/Fantomas.Core.Tests/SynLongIdentTests.fs index eed7c2d0e5..c10079c6c1 100644 --- a/src/Fantomas.Core.Tests/SynLongIdentTests.fs +++ b/src/Fantomas.Core.Tests/SynLongIdentTests.fs @@ -352,7 +352,6 @@ let ``backticks can be added from AST only scenarios`` () = true, QualifiedNameOfFile testIdent, [], - [], [ SynModuleOrNamespace( [ testIdent ], false, @@ -377,8 +376,7 @@ let ``backticks can be added from AST only scenarios`` () = { LeadingKeyword = SynModuleOrNamespaceLeadingKeyword.None } ) ], (true, false), - { ConditionalDirectives = [] - CodeComments = [] }, + ParsedInputTrivia.Empty, Set.empty ) ) diff --git a/src/Fantomas.Core.Tests/packages.lock.json b/src/Fantomas.Core.Tests/packages.lock.json index 50a2903a96..87f141e46c 100644 --- a/src/Fantomas.Core.Tests/packages.lock.json +++ b/src/Fantomas.Core.Tests/packages.lock.json @@ -19,9 +19,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "FsUnit": { "type": "Direct", @@ -138,14 +138,14 @@ "fantomas.core": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "Fantomas.FCS": "[1.0.0, )" } }, "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "System.Collections.Immutable": "[8.0.0, )", "System.Diagnostics.DiagnosticSource": "[8.0.1, )", "System.Memory": "[4.6.0, )", diff --git a/src/Fantomas.Core/ASTTransformer.fs b/src/Fantomas.Core/ASTTransformer.fs index 58450725c3..292d3b7984 100644 --- a/src/Fantomas.Core/ASTTransformer.fs +++ b/src/Fantomas.Core/ASTTransformer.fs @@ -966,22 +966,22 @@ let mkExpr (creationAide: CreationAide) (e: SynExpr) : Expr = | SynExpr.AddressOf(false, e, _, StartRange 2 (ampersandToken, _range)) -> ExprSingleNode(stn "&&" ampersandToken, false, false, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturn((true, _), e, StartRange 5 (yieldKeyword, _range)) -> + | SynExpr.YieldOrReturn((true, _), e, StartRange 5 (yieldKeyword, _range), _) -> ExprSingleNode(stn "yield" yieldKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturn((false, _), e, StartRange 6 (returnKeyword, _range)) -> + | SynExpr.YieldOrReturn((false, _), e, StartRange 6 (returnKeyword, _range), _) -> ExprSingleNode(stn "return" returnKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturnFrom((true, _), e, StartRange 6 (yieldBangKeyword, _range)) -> + | SynExpr.YieldOrReturnFrom((true, _), e, StartRange 6 (yieldBangKeyword, _range), _) -> ExprSingleNode(stn "yield!" yieldBangKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturnFrom((false, _), e, StartRange 7 (returnBangKeyword, _range)) -> + | SynExpr.YieldOrReturnFrom((false, _), e, StartRange 7 (returnBangKeyword, _range), _) -> ExprSingleNode(stn "return!" returnBangKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single | SynExpr.Do(e, StartRange 2 (doKeyword, _range)) -> ExprSingleNode(stn "do" doKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.DoBang(e, StartRange 3 (doBangKeyword, _range)) -> + | SynExpr.DoBang(e, StartRange 3 (doBangKeyword, _range), _) -> ExprSingleNode(stn "do!" doBangKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single | SynExpr.Fixed(e, StartRange 5 (fixedKeyword, _range)) -> @@ -1029,9 +1029,7 @@ let mkExpr (creationAide: CreationAide) (e: SynExpr) : Expr = let fieldNodes = recordFields |> List.choose (function - | SynExprRecordField((fieldName, _), Some mEq, Some expr, _) -> - let m = unionRanges fieldName.Range expr.Range - + | SynExprRecordField((fieldName, _), Some mEq, Some expr, m, _) -> Some( RecordFieldNode(mkSynLongIdent creationAide fieldName, stn "=" mEq, mkExpr creationAide expr, m) ) @@ -1144,7 +1142,7 @@ let mkExpr (creationAide: CreationAide) (e: SynExpr) : Expr = _, pat, e1, - SynExpr.YieldOrReturn((true, _), e2, _), + SynExpr.YieldOrReturn((true, _), e2, _, _), StartRange 3 (mFor, _)) -> ExprForEachNode( stn "for" mFor, @@ -2809,7 +2807,7 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) = let memberDefinitionRange = md.Range match md with - | SynMemberDefn.ImplicitInherit(t, e, _, StartRange 7 (mInherit, _)) -> + | SynMemberDefn.ImplicitInherit(t, e, _, StartRange 7 (mInherit, _), _) -> mkInheritConstructor creationAide t e mInherit memberDefinitionRange |> MemberDefn.ImplicitInherit @@ -2870,9 +2868,12 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) = ) |> MemberDefn.ExplicitCtor | SynMemberDefn.Member(memberDefn, _) -> mkBinding creationAide memberDefn |> MemberDefn.Member - | SynMemberDefn.Inherit(baseType, _, StartRange 7 (mInherit, _)) -> - MemberDefnInheritNode(stn "inherit" mInherit, mkType creationAide baseType, memberDefinitionRange) - |> MemberDefn.Inherit + | SynMemberDefn.Inherit(baseTypeOpt, _, StartRange 7 (mInherit, _), _) -> + match baseTypeOpt with + | Some baseType -> + MemberDefnInheritNode(stn "inherit" mInherit, mkType creationAide baseType, memberDefinitionRange) + |> MemberDefn.Inherit + | None -> failwith "successful parse shouldn't have any unfinished inherit" | SynMemberDefn.ValField(f, _) -> mkSynField creationAide f |> MemberDefn.ValField | SynMemberDefn.LetBindings( bindings = [ SynBinding(trivia = { LeadingKeyword = SynLeadingKeyword.Extern _ }) as binding ]) -> @@ -3598,25 +3599,27 @@ let mkSigFile let mds = List.map (mkModuleOrNamespaceSig creationAide) contents Oak(phds, mds, m) -let includeTrivia - (baseRange: range) - (comments: CommentTrivia list) - (conditionDirectives: ConditionalDirectiveTrivia list) - : range = +let includeTrivia (baseRange: range) (trivia: ParsedInputTrivia) : range = let ranges = [ yield! List.map (function | CommentTrivia.LineComment m | CommentTrivia.BlockComment m -> m) - comments + trivia.CodeComments yield! List.map (function | ConditionalDirectiveTrivia.If(range = range) | ConditionalDirectiveTrivia.Else(range = range) | ConditionalDirectiveTrivia.EndIf(range = range) -> range) - conditionDirectives ] + trivia.ConditionalDirectives + yield! + List.map + (function + | WarnDirectiveTrivia.Nowarn range + | WarnDirectiveTrivia.Warnon range -> range) + trivia.WarnDirectives ] (baseRange, ranges) ||> List.fold (fun acc triviaRange -> @@ -3668,7 +3671,7 @@ let mkFullTreeRange ast = | Some lastModule -> mkSynModuleOrNamespaceFullRange lastModule let astRange = unionRanges startPos endPos - includeTrivia astRange trivia.CodeComments trivia.ConditionalDirectives + includeTrivia astRange trivia | ParsedInput.SigFile(ParsedSigFileInput(hashDirectives = directives; contents = modules; trivia = trivia)) -> let startPos = @@ -3688,7 +3691,7 @@ let mkFullTreeRange ast = | Some lastModule -> mkSynModuleOrNamespaceSigFullRange lastModule let astRange = unionRanges startPos endPos - includeTrivia astRange trivia.CodeComments trivia.ConditionalDirectives + includeTrivia astRange trivia let mkOak (sourceText: ISourceText option) (ast: ParsedInput) = let creationAide = { SourceText = sourceText } diff --git a/src/Fantomas.Core/Trivia.fs b/src/Fantomas.Core/Trivia.fs index 2c963cb350..4d243ee753 100644 --- a/src/Fantomas.Core/Trivia.fs +++ b/src/Fantomas.Core/Trivia.fs @@ -136,15 +136,21 @@ type ConditionalDirectiveTrivia with | ConditionalDirectiveTrivia.Else m | ConditionalDirectiveTrivia.EndIf m -> m -let internal collectTriviaFromDirectives +type WarnDirectiveTrivia with + + member x.Range = + match x with + | WarnDirectiveTrivia.Nowarn m + | WarnDirectiveTrivia.Warnon m -> m + +let internal collectTriviaFromDirectiveRanges (source: ISourceText) - (directives: ConditionalDirectiveTrivia list) + (directiveRanges: range list) (codeRange: range) : TriviaNode list = - directives - |> List.filter (fun cdt -> RangeHelpers.rangeContainsRange codeRange cdt.Range) - |> List.map (fun cdt -> - let m = cdt.Range + directiveRanges + |> List.filter (RangeHelpers.rangeContainsRange codeRange) + |> List.map (fun m -> let text = (source.GetSubTextFromRange m).TrimEnd() let content = Directive text TriviaNode(content, m)) @@ -315,27 +321,24 @@ let addToTree (tree: Oak) (trivia: TriviaNode seq) = let enrichTree (config: FormatConfig) (sourceText: ISourceText) (ast: ParsedInput) (tree: Oak) : Oak = let fullTreeRange = tree.Range - let directives, codeComments = + let parsedTrivia = match ast with - | ParsedInput.ImplFile(ParsedImplFileInput( - trivia = { ConditionalDirectives = directives - CodeComments = codeComments })) -> directives, codeComments - | ParsedInput.SigFile(ParsedSigFileInput( - trivia = { ConditionalDirectives = directives - CodeComments = codeComments })) -> directives, codeComments + | ParsedInput.ImplFile(ParsedImplFileInput(trivia = t)) + | ParsedInput.SigFile(ParsedSigFileInput(trivia = t)) -> t let trivia = let newlines = - collectTriviaFromBlankLines config sourceText tree codeComments fullTreeRange + collectTriviaFromBlankLines config sourceText tree parsedTrivia.CodeComments fullTreeRange let comments = - match ast with - | ParsedInput.ImplFile(ParsedImplFileInput(trivia = trivia)) -> - collectTriviaFromCodeComments sourceText trivia.CodeComments fullTreeRange - | ParsedInput.SigFile(ParsedSigFileInput(trivia = trivia)) -> - collectTriviaFromCodeComments sourceText trivia.CodeComments fullTreeRange + collectTriviaFromCodeComments sourceText parsedTrivia.CodeComments fullTreeRange + + let directiveRanges = + (parsedTrivia.ConditionalDirectives |> List.map _.Range) + @ (parsedTrivia.WarnDirectives |> List.map _.Range) - let directives = collectTriviaFromDirectives sourceText directives fullTreeRange + let directives = + collectTriviaFromDirectiveRanges sourceText directiveRanges fullTreeRange [| yield! comments; yield! newlines; yield! directives |] |> Array.sortBy (fun n -> n.Range.Start.Line, n.Range.Start.Column) diff --git a/src/Fantomas.Core/packages.lock.json b/src/Fantomas.Core/packages.lock.json index 423ac63843..b816c9716a 100644 --- a/src/Fantomas.Core/packages.lock.json +++ b/src/Fantomas.Core/packages.lock.json @@ -22,9 +22,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "G-Research.FSharp.Analyzers": { "type": "Direct", @@ -127,7 +127,7 @@ "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "System.Collections.Immutable": "[8.0.0, )", "System.Diagnostics.DiagnosticSource": "[8.0.1, )", "System.Memory": "[4.6.0, )", diff --git a/src/Fantomas.FCS/Fantomas.FCS.fsproj b/src/Fantomas.FCS/Fantomas.FCS.fsproj index dc2b8f3d4a..26de30e34b 100644 --- a/src/Fantomas.FCS/Fantomas.FCS.fsproj +++ b/src/Fantomas.FCS/Fantomas.FCS.fsproj @@ -220,11 +220,11 @@ SyntaxTree\pplex.fsl - --module Fantomas.FCS.PPParser --open Fantomas.FCS --open Fantomas.FCS.Syntax --open Fantomas.FCS.ParseHelpers --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char + --module Fantomas.FCS.PPParser --open Fantomas.FCS --open Fantomas.FCS.Syntax --open Fantomas.FCS.ParseHelpers --open Fantomas.FCS.LexerStore --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char SyntaxTree\pppars.fsy - --module Fantomas.FCS.Lexer --open Fantomas.FCS.Lexhelp --open Internal.Utilities.Text.Lexing --open Fantomas.FCS.Parser --open Fantomas.FCS.Text --open Fantomas.FCS.ParseHelpers --internal --unicode --lexlib Internal.Utilities.Text.Lexing + --module Fantomas.FCS.Lexer --open Fantomas.FCS.Lexhelp --open Internal.Utilities.Text.Lexing --open Fantomas.FCS.Parser --open Fantomas.FCS.Text --open Fantomas.FCS.ParseHelpers --open Fantomas.FCS.LexerStore --internal --unicode --lexlib Internal.Utilities.Text.Lexing SyntaxTree\lex.fsl @@ -273,6 +273,18 @@ SyntaxTree\SyntaxTreeOps.fs + + SyntaxTree\WarnScopes.fsi + + + SyntaxTree\WarnScopes.fs + + + SyntaxTree\LexerStore.fsi + + + SyntaxTree\LexerStore.fs + SyntaxTree\ParseHelpers.fsi diff --git a/src/Fantomas.FCS/Parse.fs b/src/Fantomas.FCS/Parse.fs index e95dcea013..f12385f1ae 100644 --- a/src/Fantomas.FCS/Parse.fs +++ b/src/Fantomas.FCS/Parse.fs @@ -11,6 +11,7 @@ open Fantomas.FCS open Fantomas.FCS.AbstractIL.IL open Fantomas.FCS.DiagnosticsLogger open Fantomas.FCS.Features +open Fantomas.FCS.LexerStore open Fantomas.FCS.Lexhelp open Fantomas.FCS.Text open Fantomas.FCS.Text.Position @@ -153,27 +154,16 @@ let QualFileNameOfImpls filename specs = | [ SynModuleOrNamespace(kind = kind; range = m) ] when not kind.IsModule -> QualFileNameOfFilename m filename | _ -> QualFileNameOfFilename (mkRange filename pos0 pos0) filename -let GetScopedPragmasForInput input = - match input with - | ParsedInput.SigFile(ParsedSigFileInput(scopedPragmas = pragmas)) -> pragmas - | ParsedInput.ImplFile(ParsedImplFileInput(scopedPragmas = pragmas)) -> pragmas +let collectCodeComments (lexbuf: UnicodeLexing.Lexbuf) = + let tripleSlashComments = XmlDocStore.ReportInvalidXmlDocPositions lexbuf -let collectCodeComments (lexbuf: UnicodeLexing.Lexbuf) (tripleSlashComments: range list) = - [ yield! LexbufCommentStore.GetComments(lexbuf) - yield! (List.map CommentTrivia.LineComment tripleSlashComments) ] + [ yield! CommentStore.GetComments(lexbuf) + yield! List.map CommentTrivia.LineComment tripleSlashComments ] |> List.sortBy (function | CommentTrivia.LineComment r | CommentTrivia.BlockComment r -> r.StartLine, r.StartColumn) -let PostParseModuleImpls - ( - defaultNamespace, - filename, - isLastCompiland, - ParsedImplFile(hashDirectives, impls), - lexbuf: UnicodeLexing.Lexbuf, - tripleSlashComments: range list - ) = +let PostParseModuleImpls (defaultNamespace, filename, isLastCompiland, ParsedImplFile(hashDirectives, impls), lexbuf) = match impls |> List.rev @@ -191,23 +181,13 @@ let PostParseModuleImpls let qualName = QualFileNameOfImpls filename impls let isScript = IsScript filename - let scopedPragmas = [] - let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf) - let codeComments = collectCodeComments lexbuf tripleSlashComments + let trivia = + { ConditionalDirectives = IfdefStore.GetTrivia(lexbuf) + WarnDirectives = WarnScopes.getDirectiveTrivia (lexbuf) + CodeComments = collectCodeComments lexbuf } ParsedInput.ImplFile( - ParsedImplFileInput( - filename, - isScript, - qualName, - scopedPragmas, - hashDirectives, - impls, - isLastCompiland, - { ConditionalDirectives = conditionalDirectives - CodeComments = codeComments }, - Set.empty - ) + ParsedImplFileInput(filename, isScript, qualName, hashDirectives, impls, isLastCompiland, trivia, Set.empty) ) let PostParseModuleSpec (_i, defaultNamespace, _isLastCompiland, filename, intf) = @@ -273,14 +253,8 @@ let PostParseModuleSpec (_i, defaultNamespace, _isLastCompiland, filename, intf) SynModuleOrNamespaceSig(lid, isRecursive, kind, decls, xmlDoc, attributes, None, range, trivia) let PostParseModuleSpecs - ( - defaultNamespace, - filename, - isLastCompiland, - ParsedSigFile(hashDirectives, specs), - lexbuf: UnicodeLexing.Lexbuf, - tripleSlashComments: range list - ) = + (defaultNamespace, filename, isLastCompiland, ParsedSigFile(hashDirectives, specs), lexbuf: UnicodeLexing.Lexbuf) + = match specs |> List.rev @@ -296,23 +270,13 @@ let PostParseModuleSpecs |> List.mapi (fun i x -> PostParseModuleSpec(i, defaultNamespace, isLastCompiland, filename, x)) let qualName = QualFileNameOfSpecs filename specs - let scopedPragmas = [] - - let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf) - let codeComments = collectCodeComments lexbuf tripleSlashComments - - ParsedInput.SigFile( - ParsedSigFileInput( - filename, - qualName, - scopedPragmas, - hashDirectives, - specs, - { ConditionalDirectives = conditionalDirectives - CodeComments = codeComments }, - Set.empty - ) - ) + + let trivia = + { ConditionalDirectives = IfdefStore.GetTrivia(lexbuf) + WarnDirectives = WarnScopes.getDirectiveTrivia (lexbuf) + CodeComments = collectCodeComments lexbuf } + + ParsedInput.SigFile(ParsedSigFileInput(filename, qualName, hashDirectives, specs, trivia, Set.empty)) let ParseInput ( @@ -337,38 +301,24 @@ let ParseInput use _ = UseDiagnosticsLogger delayLogger use _ = UseBuildPhase BuildPhase.Parse - let mutable scopedPragmas = [] - try - let input = - if mlCompatSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then - if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then - errorR (Error(FSComp.SR.buildInvalidSourceFileExtensionML filename, rangeStartup)) - else - mlCompatWarning (FSComp.SR.buildCompilingExtensionIsForML ()) rangeStartup - - // Call the appropriate parser - for signature files or implementation files - if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then - let impl = Parser.implementationFile lexer lexbuf - - let tripleSlashComments = - LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf) - - PostParseModuleImpls(defaultNamespace, filename, isLastCompiland, impl, lexbuf, tripleSlashComments) - elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then - let intfs = Parser.signatureFile lexer lexbuf - - let tripleSlashComments = - LexbufLocalXmlDocStore.ReportInvalidXmlDocPositions(lexbuf) - - PostParseModuleSpecs(defaultNamespace, filename, isLastCompiland, intfs, lexbuf, tripleSlashComments) - else if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then - error (Error(FSComp.SR.buildInvalidSourceFileExtensionUpdated filename, rangeStartup)) + if mlCompatSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then + if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then + errorR (Error(FSComp.SR.buildInvalidSourceFileExtensionML filename, rangeStartup)) else - error (Error(FSComp.SR.buildInvalidSourceFileExtension filename, rangeStartup)) - - scopedPragmas <- GetScopedPragmasForInput input - input + mlCompatWarning (FSComp.SR.buildCompilingExtensionIsForML ()) rangeStartup + + // Call the appropriate parser - for signature files or implementation files + if FSharpImplFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then + let impl = Parser.implementationFile lexer lexbuf + PostParseModuleImpls(defaultNamespace, filename, isLastCompiland, impl, lexbuf) + elif FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then + let intfs = Parser.signatureFile lexer lexbuf + PostParseModuleSpecs(defaultNamespace, filename, isLastCompiland, intfs, lexbuf) + else if lexbuf.SupportsFeature LanguageFeature.MLCompatRevisions then + error (Error(FSComp.SR.buildInvalidSourceFileExtensionUpdated filename, rangeStartup)) + else + error (Error(FSComp.SR.buildInvalidSourceFileExtension filename, rangeStartup)) finally // OK, now commit the errors, since the ScopedPragmas will (hopefully) have been scraped let filteringErrorLogger = errorLogger // TODO: does this matter? //GetErrorLoggerFilteringByScopedPragmas(false, scopedPragmas, diagnosticOptions, errorLogger) @@ -379,16 +329,7 @@ let EmptyParsedInput (filename, isLastCompiland) = if FSharpSigFileSuffixes |> List.exists (FileSystemUtils.checkSuffix lower) then ParsedInput.SigFile( - ParsedSigFileInput( - filename, - QualFileNameOfImpls filename [], - [], - [], - [], - { ConditionalDirectives = [] - CodeComments = [] }, - Set.empty - ) + ParsedSigFileInput(filename, QualFileNameOfImpls filename [], [], [], ParsedInputTrivia.Empty, Set.empty) ) else ParsedInput.ImplFile( @@ -398,10 +339,8 @@ let EmptyParsedInput (filename, isLastCompiland) = QualFileNameOfImpls filename [], [], [], - [], isLastCompiland, - { ConditionalDirectives = [] - CodeComments = [] }, + ParsedInputTrivia.Empty, Set.empty ) ) diff --git a/src/Fantomas.FCS/packages.lock.json b/src/Fantomas.FCS/packages.lock.json index 9482e407e7..5aaf2aa316 100644 --- a/src/Fantomas.FCS/packages.lock.json +++ b/src/Fantomas.FCS/packages.lock.json @@ -22,9 +22,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "FsLexYacc": { "type": "Direct", diff --git a/src/Fantomas.Tests/packages.lock.json b/src/Fantomas.Tests/packages.lock.json index 7c8f686ebd..c69c2a15ac 100644 --- a/src/Fantomas.Tests/packages.lock.json +++ b/src/Fantomas.Tests/packages.lock.json @@ -19,9 +19,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "FsUnit": { "type": "Direct", @@ -213,7 +213,7 @@ "type": "Project", "dependencies": { "Argu": "[6.2.4, )", - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "Fantomas.Client": "[1.0.0, )", "Fantomas.Core": "[1.0.0, )", "Ignore": "[0.2.1, )", @@ -230,7 +230,7 @@ "fantomas.client": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "SemanticVersioning": "[2.0.2, )", "StreamJsonRpc": "[2.20.20, )" } @@ -238,14 +238,14 @@ "fantomas.core": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "Fantomas.FCS": "[1.0.0, )" } }, "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "System.Collections.Immutable": "[8.0.0, )", "System.Diagnostics.DiagnosticSource": "[8.0.1, )", "System.Memory": "[4.6.0, )", diff --git a/src/Fantomas/packages.lock.json b/src/Fantomas/packages.lock.json index a69893af5b..86e7420ce4 100644 --- a/src/Fantomas/packages.lock.json +++ b/src/Fantomas/packages.lock.json @@ -38,9 +38,9 @@ }, "FSharp.Core": { "type": "Direct", - "requested": "[8.0.100, )", - "resolved": "8.0.100", - "contentHash": "ZOVZ/o+jI3ormTZOa28Wh0tSRoyle1f7lKFcUN61sPiXI7eDZu8eSveFybgTeyIEyW0ujjp31cp7GOglDgsNEg==" + "requested": "[9.0.300, )", + "resolved": "9.0.300", + "contentHash": "TVt2J7RCE1KCS2IaONF+p8/KIZ1eHNbW+7qmKF6hGoD4tXl+o07ja1mPtFjMqRa5uHMFaTrGTPn/m945WnDLiQ==" }, "G-Research.FSharp.Analyzers": { "type": "Direct", @@ -278,7 +278,7 @@ "fantomas.client": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "SemanticVersioning": "[2.0.2, )", "StreamJsonRpc": "[2.20.20, )" } @@ -286,14 +286,14 @@ "fantomas.core": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "Fantomas.FCS": "[1.0.0, )" } }, "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[8.0.100, )", + "FSharp.Core": "[9.0.300, )", "System.Collections.Immutable": "[8.0.0, )", "System.Diagnostics.DiagnosticSource": "[8.0.1, )", "System.Memory": "[4.6.0, )", From 421673728687c7c113b29fb17cb3d9e3ae872697 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Wed, 4 Jun 2025 11:57:33 +0000 Subject: [PATCH 02/11] review follow-up --- src/Fantomas.Core.Tests/CommentTests.fs | 2 +- src/Fantomas.Core/ASTTransformer.fs | 32 ++++++++++++++----------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Fantomas.Core.Tests/CommentTests.fs b/src/Fantomas.Core.Tests/CommentTests.fs index 228d01bb09..55e064344f 100644 --- a/src/Fantomas.Core.Tests/CommentTests.fs +++ b/src/Fantomas.Core.Tests/CommentTests.fs @@ -6,7 +6,7 @@ open Fantomas.Core.Tests.TestHelpers open Fantomas.Core [] -let ``should keep sticky-to-the-left comments after #if directivesXXX`` () = +let ``should keep sticky-to-the-left comments after #if directives`` () = formatSourceString "#if DEBUG // debug only\n#endif\n" config |> should equal "#if DEBUG // debug only\n#endif\n" diff --git a/src/Fantomas.Core/ASTTransformer.fs b/src/Fantomas.Core/ASTTransformer.fs index 292d3b7984..8916c767d8 100644 --- a/src/Fantomas.Core/ASTTransformer.fs +++ b/src/Fantomas.Core/ASTTransformer.fs @@ -966,23 +966,23 @@ let mkExpr (creationAide: CreationAide) (e: SynExpr) : Expr = | SynExpr.AddressOf(false, e, _, StartRange 2 (ampersandToken, _range)) -> ExprSingleNode(stn "&&" ampersandToken, false, false, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturn((true, _), e, StartRange 5 (yieldKeyword, _range), _) -> - ExprSingleNode(stn "yield" yieldKeyword, true, true, mkExpr creationAide e, exprRange) + | SynExpr.YieldOrReturn((true, _), e, _range, trivia) -> + ExprSingleNode(stn "yield" trivia.YieldOrReturnKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturn((false, _), e, StartRange 6 (returnKeyword, _range), _) -> - ExprSingleNode(stn "return" returnKeyword, true, true, mkExpr creationAide e, exprRange) + | SynExpr.YieldOrReturn((false, _), e, _range, trivia) -> + ExprSingleNode(stn "return" trivia.YieldOrReturnKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturnFrom((true, _), e, StartRange 6 (yieldBangKeyword, _range), _) -> - ExprSingleNode(stn "yield!" yieldBangKeyword, true, true, mkExpr creationAide e, exprRange) + | SynExpr.YieldOrReturnFrom((true, _), e, _range, trivia) -> + ExprSingleNode(stn "yield!" trivia.YieldOrReturnFromKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.YieldOrReturnFrom((false, _), e, StartRange 7 (returnBangKeyword, _range), _) -> - ExprSingleNode(stn "return!" returnBangKeyword, true, true, mkExpr creationAide e, exprRange) + | SynExpr.YieldOrReturnFrom((false, _), e, _range, trivia) -> + ExprSingleNode(stn "return!" trivia.YieldOrReturnFromKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single | SynExpr.Do(e, StartRange 2 (doKeyword, _range)) -> ExprSingleNode(stn "do" doKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single - | SynExpr.DoBang(e, StartRange 3 (doBangKeyword, _range), _) -> - ExprSingleNode(stn "do!" doBangKeyword, true, true, mkExpr creationAide e, exprRange) + | SynExpr.DoBang(e, _range, trivia) -> + ExprSingleNode(stn "do!" trivia.DoBangKeyword, true, true, mkExpr creationAide e, exprRange) |> Expr.Single | SynExpr.Fixed(e, StartRange 5 (fixedKeyword, _range)) -> ExprSingleNode(stn "fixed" fixedKeyword, true, false, mkExpr creationAide e, exprRange) @@ -2807,8 +2807,8 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) = let memberDefinitionRange = md.Range match md with - | SynMemberDefn.ImplicitInherit(t, e, _, StartRange 7 (mInherit, _), _) -> - mkInheritConstructor creationAide t e mInherit memberDefinitionRange + | SynMemberDefn.ImplicitInherit(t, e, _, _, trivia) -> + mkInheritConstructor creationAide t e trivia.InheritKeyword memberDefinitionRange |> MemberDefn.ImplicitInherit // Transforms: `member this.Y with get() = "meh"` into `member this.Y = "meh"` @@ -2868,10 +2868,14 @@ let mkMemberDefn (creationAide: CreationAide) (md: SynMemberDefn) = ) |> MemberDefn.ExplicitCtor | SynMemberDefn.Member(memberDefn, _) -> mkBinding creationAide memberDefn |> MemberDefn.Member - | SynMemberDefn.Inherit(baseTypeOpt, _, StartRange 7 (mInherit, _), _) -> + | SynMemberDefn.Inherit(baseTypeOpt, _, _isInline, trivia) -> match baseTypeOpt with | Some baseType -> - MemberDefnInheritNode(stn "inherit" mInherit, mkType creationAide baseType, memberDefinitionRange) + MemberDefnInheritNode( + stn "inherit" trivia.InheritKeyword, + mkType creationAide baseType, + memberDefinitionRange + ) |> MemberDefn.Inherit | None -> failwith "successful parse shouldn't have any unfinished inherit" | SynMemberDefn.ValField(f, _) -> mkSynField creationAide f |> MemberDefn.ValField From 10b59bb1f47d0dd7a07bb02326e27aac76aca928 Mon Sep 17 00:00:00 2001 From: Martin521 <29605222+Martin521@users.noreply.github.com> Date: Wed, 4 Jun 2025 15:39:48 +0000 Subject: [PATCH 03/11] update dockerfile also to sdk 9 --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index bda0692f15..63fd6d08db 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:8.0.400 +FROM mcr.microsoft.com/dotnet/sdk:9.0.300 # Avoid warnings by switching to noninteractive ENV DEBIAN_FRONTEND=noninteractive From c68f23ce30fcbcf5d9dca6519c1415384fee2e28 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 06:24:51 +0100 Subject: [PATCH 04/11] Update to dotnet 10 --- .devcontainer/Dockerfile | 2 +- global.json | 2 +- .../Fantomas.Benchmarks.fsproj | 2 +- src/Fantomas.Benchmarks/packages.lock.json | 113 +----------------- .../Fantomas.Client.Tests.fsproj | 2 +- src/Fantomas.Client.Tests/packages.lock.json | 23 +--- .../Fantomas.Core.Tests.fsproj | 2 +- src/Fantomas.Core.Tests/packages.lock.json | 56 +-------- src/Fantomas.Tests/Fantomas.Tests.fsproj | 2 +- src/Fantomas.Tests/packages.lock.json | 67 +---------- src/Fantomas/Fantomas.fsproj | 2 +- src/Fantomas/packages.lock.json | 57 +-------- 12 files changed, 29 insertions(+), 301 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 63fd6d08db..6e3cd0f5b4 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/dotnet/sdk:9.0.300 +FROM mcr.microsoft.com/dotnet/sdk:10.0.100 # Avoid warnings by switching to noninteractive ENV DEBIAN_FRONTEND=noninteractive diff --git a/global.json b/global.json index d3dbe09378..971b5004e2 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "9.0.300", + "version": "10.0.100", "rollForward": "latestPatch" } } \ No newline at end of file diff --git a/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj b/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj index 5152fe51d8..88a3ddcbda 100644 --- a/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj +++ b/src/Fantomas.Benchmarks/Fantomas.Benchmarks.fsproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 false diff --git a/src/Fantomas.Benchmarks/packages.lock.json b/src/Fantomas.Benchmarks/packages.lock.json index 664a872c78..fbe63b1d49 100644 --- a/src/Fantomas.Benchmarks/packages.lock.json +++ b/src/Fantomas.Benchmarks/packages.lock.json @@ -1,7 +1,7 @@ { "version": 2, "dependencies": { - "net8.0": { + "net10.0": { "BenchmarkDotNet": { "type": "Direct", "requested": "[0.14.0, )", @@ -79,13 +79,7 @@ "resolved": "4.1.0", "contentHash": "bNzTyxP3iD5FPFHfVDl15Y6/wSoI7e3MeV0lOaj9igbIKTjgrmuw6LoVJ06jUNFA7+KaDC/OIsStWl/FQJz6sQ==", "dependencies": { - "Microsoft.CodeAnalysis.Analyzers": "3.3.3", - "System.Collections.Immutable": "5.0.0", - "System.Memory": "4.5.4", - "System.Reflection.Metadata": "5.0.0", - "System.Runtime.CompilerServices.Unsafe": "5.0.0", - "System.Text.Encoding.CodePages": "4.5.1", - "System.Threading.Tasks.Extensions": "4.5.4" + "Microsoft.CodeAnalysis.Analyzers": "3.3.3" } }, "Microsoft.CodeAnalysis.CSharp": { @@ -110,19 +104,13 @@ "resolved": "2.2.332302", "contentHash": "Hp84ivxSKIMTBzYSATxmUsm3YSXHWivcwiRRbsydGmqujMUK8BAueLN0ssAVEOkOBmh0vjUBhrq7YcroT7VCug==", "dependencies": { - "Microsoft.Diagnostics.NETCore.Client": "0.2.251802", - "System.Collections.Immutable": "5.0.0", - "System.Runtime.CompilerServices.Unsafe": "5.0.0" + "Microsoft.Diagnostics.NETCore.Client": "0.2.251802" } }, "Microsoft.Diagnostics.Tracing.TraceEvent": { "type": "Transitive", "resolved": "3.1.8", - "contentHash": "kl3UMrZKSeSEYZ8rt/GjLUQToREjgQABqfg6PzQBmSlYHTZOKE9ePEOS2xptROQ9SVvngg3QGX51TIT11iZ0wA==", - "dependencies": { - "Microsoft.Win32.Registry": "4.4.0", - "System.Runtime.CompilerServices.Unsafe": "5.0.0" - } + "contentHash": "kl3UMrZKSeSEYZ8rt/GjLUQToREjgQABqfg6PzQBmSlYHTZOKE9ePEOS2xptROQ9SVvngg3QGX51TIT11iZ0wA==" }, "Microsoft.DotNet.PlatformAbstractions": { "type": "Transitive", @@ -186,31 +174,13 @@ "Microsoft.Extensions.Primitives": { "type": "Transitive", "resolved": "2.1.1", - "contentHash": "scJ1GZNIxMmjpENh0UZ8XCQ6vzr/LzeF9WvEA51Ix2OQGAs9WPgPu8ABVUdvpKPLuor/t05gm6menJK3PwqOXg==", - "dependencies": { - "System.Memory": "4.5.1", - "System.Runtime.CompilerServices.Unsafe": "4.5.1" - } + "contentHash": "scJ1GZNIxMmjpENh0UZ8XCQ6vzr/LzeF9WvEA51Ix2OQGAs9WPgPu8ABVUdvpKPLuor/t05gm6menJK3PwqOXg==" }, "Microsoft.NETCore.Platforms": { "type": "Transitive", "resolved": "5.0.0", "contentHash": "VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==" }, - "Microsoft.NETCore.Targets": { - "type": "Transitive", - "resolved": "1.1.3", - "contentHash": "3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==" - }, - "Microsoft.Win32.Registry": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", - "dependencies": { - "System.Security.AccessControl": "5.0.0", - "System.Security.Principal.Windows": "5.0.0" - } - }, "Perfolizer": { "type": "Transitive", "resolved": "0.3.17", @@ -227,48 +197,9 @@ "contentHash": "MF1CHaRcC+MLFdnDthv4/bKWBZnlnSpkGqa87pKukQefgEdwtb9zFW6zs0GjPp73qtpYYg4q6PEKbzJbxCpKfw==", "dependencies": { "Microsoft.NETCore.Platforms": "5.0.0", - "Microsoft.Win32.Registry": "5.0.0", "System.CodeDom": "5.0.0" } }, - "System.Reflection.Metadata": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "5NecZgXktdGg34rh1OenY1rFNDCI8xSjFr+Z4OU4cU06AQHUdRnIIEeWENu3Wl4YowbzkymAIMvi3WyK9U53pQ==" - }, - "System.Runtime.CompilerServices.Unsafe": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "ZD9TMpsmYJLrxbbmdvhwt9YEgG5WntEnZ/d1eH8JBX9LBp+Ju8BSBhUGbZMNVHHomWo2KVImJhTDl2hIgw/6MA==" - }, - "System.Security.AccessControl": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "dagJ1mHZO3Ani8GH0PHpPEe/oYO+rVdbQjvjJkBRNQkX4t0r1iaeGn8+/ybkSLEan3/slM0t59SVdHzuHf2jmw==", - "dependencies": { - "Microsoft.NETCore.Platforms": "5.0.0", - "System.Security.Principal.Windows": "5.0.0" - } - }, - "System.Security.Principal.Windows": { - "type": "Transitive", - "resolved": "5.0.0", - "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" - }, - "System.Text.Encoding.CodePages": { - "type": "Transitive", - "resolved": "4.5.1", - "contentHash": "4J2JQXbftjPMppIHJ7IC+VXQ9XfEagN92vZZNoG12i+zReYlim5dMoXFC1Zzg7tsnKDM7JPo5bYfFK4Jheq44w==", - "dependencies": { - "Microsoft.NETCore.Platforms": "2.1.2", - "System.Runtime.CompilerServices.Unsafe": "4.5.2" - } - }, - "System.Threading.Tasks.Extensions": { - "type": "Transitive", - "resolved": "4.5.4", - "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==" - }, "fantomas.core": { "type": "Project", "dependencies": { @@ -279,39 +210,7 @@ "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[9.0.300, )", - "System.Collections.Immutable": "[8.0.0, )", - "System.Diagnostics.DiagnosticSource": "[8.0.1, )", - "System.Memory": "[4.6.0, )", - "System.Runtime": "[4.3.1, )" - } - }, - "System.Collections.Immutable": { - "type": "CentralTransitive", - "requested": "[8.0.0, )", - "resolved": "8.0.0", - "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==" - }, - "System.Diagnostics.DiagnosticSource": { - "type": "CentralTransitive", - "requested": "[8.0.1, )", - "resolved": "8.0.1", - "contentHash": "vaoWjvkG1aenR2XdjaVivlCV9fADfgyhW5bZtXT23qaEea0lWiUljdQuze4E31vKM7ZWJaSUsbYIKE3rnzfZUg==" - }, - "System.Memory": { - "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg==" - }, - "System.Runtime": { - "type": "CentralTransitive", - "requested": "[4.3.1, )", - "resolved": "4.3.1", - "contentHash": "abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", - "Microsoft.NETCore.Targets": "1.1.3" + "FSharp.Core": "[9.0.300, )" } } } diff --git a/src/Fantomas.Client.Tests/Fantomas.Client.Tests.fsproj b/src/Fantomas.Client.Tests/Fantomas.Client.Tests.fsproj index 3fe6e272c0..b1ea8b9214 100644 --- a/src/Fantomas.Client.Tests/Fantomas.Client.Tests.fsproj +++ b/src/Fantomas.Client.Tests/Fantomas.Client.Tests.fsproj @@ -2,7 +2,7 @@ FS0988 - net8.0 + net10.0 false false Major diff --git a/src/Fantomas.Client.Tests/packages.lock.json b/src/Fantomas.Client.Tests/packages.lock.json index 54e3169b0b..674a0fdb3a 100644 --- a/src/Fantomas.Client.Tests/packages.lock.json +++ b/src/Fantomas.Client.Tests/packages.lock.json @@ -1,7 +1,7 @@ { "version": 2, "dependencies": { - "net8.0": { + "net10.0": { "CliWrap": { "type": "Direct", "requested": "[3.6.7, )", @@ -81,10 +81,7 @@ "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", - "dependencies": { - "System.Reflection.Metadata": "1.6.0" - } + "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==" }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", @@ -120,20 +117,9 @@ "contentHash": "r4G7uHHfoo8LCilPOdtf2C+Q5ymHOAXtciT4ZtB2xRlAvv4gPkWBYNAijFblStv3+uidp81j5DP11jMZl4BfJw==", "dependencies": { "Microsoft.VisualStudio.Threading": "17.10.48", - "Microsoft.VisualStudio.Validation": "17.8.8", - "System.IO.Pipelines": "8.0.0" + "Microsoft.VisualStudio.Validation": "17.8.8" } }, - "System.IO.Pipelines": { - "type": "Transitive", - "resolved": "8.0.0", - "contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==" - }, - "System.Reflection.Metadata": { - "type": "Transitive", - "resolved": "1.6.0", - "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" - }, "fantomas.client": { "type": "Project", "dependencies": { @@ -165,8 +151,7 @@ "Microsoft.VisualStudio.Threading.Analyzers": "17.10.48", "Microsoft.VisualStudio.Validation": "17.8.8", "Nerdbank.Streams": "2.11.74", - "Newtonsoft.Json": "13.0.1", - "System.IO.Pipelines": "8.0.0" + "Newtonsoft.Json": "13.0.1" } } } diff --git a/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj b/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj index 6f606dc0ce..433285415b 100644 --- a/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj +++ b/src/Fantomas.Core.Tests/Fantomas.Core.Tests.fsproj @@ -1,7 +1,7 @@ FS0988 - net8.0 + net10.0 FS0025 false Major diff --git a/src/Fantomas.Core.Tests/packages.lock.json b/src/Fantomas.Core.Tests/packages.lock.json index 87f141e46c..c4fa425dd9 100644 --- a/src/Fantomas.Core.Tests/packages.lock.json +++ b/src/Fantomas.Core.Tests/packages.lock.json @@ -1,7 +1,7 @@ { "version": 2, "dependencies": { - "net8.0": { + "net10.0": { "FsCheck": { "type": "Direct", "requested": "[2.16.5, )", @@ -81,23 +81,10 @@ "resolved": "17.12.0", "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA==" }, - "Microsoft.NETCore.Platforms": { - "type": "Transitive", - "resolved": "1.1.1", - "contentHash": "TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==" - }, - "Microsoft.NETCore.Targets": { - "type": "Transitive", - "resolved": "1.1.3", - "contentHash": "3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==" - }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", - "dependencies": { - "System.Reflection.Metadata": "1.6.0" - } + "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==" }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", @@ -108,11 +95,6 @@ "Newtonsoft.Json": "13.0.1" } }, - "System.Reflection.Metadata": { - "type": "Transitive", - "resolved": "1.6.0", - "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" - }, "TestableIO.System.IO.Abstractions": { "type": "Transitive", "resolved": "21.1.3", @@ -145,11 +127,7 @@ "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[9.0.300, )", - "System.Collections.Immutable": "[8.0.0, )", - "System.Diagnostics.DiagnosticSource": "[8.0.1, )", - "System.Memory": "[4.6.0, )", - "System.Runtime": "[4.3.1, )" + "FSharp.Core": "[9.0.300, )" } }, "Newtonsoft.Json": { @@ -157,34 +135,6 @@ "requested": "[13.0.3, )", "resolved": "13.0.3", "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" - }, - "System.Collections.Immutable": { - "type": "CentralTransitive", - "requested": "[8.0.0, )", - "resolved": "8.0.0", - "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==" - }, - "System.Diagnostics.DiagnosticSource": { - "type": "CentralTransitive", - "requested": "[8.0.1, )", - "resolved": "8.0.1", - "contentHash": "vaoWjvkG1aenR2XdjaVivlCV9fADfgyhW5bZtXT23qaEea0lWiUljdQuze4E31vKM7ZWJaSUsbYIKE3rnzfZUg==" - }, - "System.Memory": { - "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg==" - }, - "System.Runtime": { - "type": "CentralTransitive", - "requested": "[4.3.1, )", - "resolved": "4.3.1", - "contentHash": "abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", - "Microsoft.NETCore.Targets": "1.1.3" - } } } } diff --git a/src/Fantomas.Tests/Fantomas.Tests.fsproj b/src/Fantomas.Tests/Fantomas.Tests.fsproj index 8243c389c8..502ee6f1a0 100644 --- a/src/Fantomas.Tests/Fantomas.Tests.fsproj +++ b/src/Fantomas.Tests/Fantomas.Tests.fsproj @@ -1,7 +1,7 @@  - net8.0 + net10.0 false false FS0988 diff --git a/src/Fantomas.Tests/packages.lock.json b/src/Fantomas.Tests/packages.lock.json index c69c2a15ac..6019930d87 100644 --- a/src/Fantomas.Tests/packages.lock.json +++ b/src/Fantomas.Tests/packages.lock.json @@ -1,7 +1,7 @@ { "version": 2, "dependencies": { - "net8.0": { + "net10.0": { "FsCheck": { "type": "Direct", "requested": "[2.16.5, )", @@ -108,23 +108,10 @@ "resolved": "17.6.3", "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" }, - "Microsoft.NETCore.Platforms": { - "type": "Transitive", - "resolved": "1.1.1", - "contentHash": "TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==" - }, - "Microsoft.NETCore.Targets": { - "type": "Transitive", - "resolved": "1.1.3", - "contentHash": "3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==" - }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", "resolved": "17.12.0", - "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==", - "dependencies": { - "System.Reflection.Metadata": "1.6.0" - } + "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==" }, "Microsoft.TestPlatform.TestHost": { "type": "Transitive", @@ -160,8 +147,7 @@ "contentHash": "r4G7uHHfoo8LCilPOdtf2C+Q5ymHOAXtciT4ZtB2xRlAvv4gPkWBYNAijFblStv3+uidp81j5DP11jMZl4BfJw==", "dependencies": { "Microsoft.VisualStudio.Threading": "17.10.48", - "Microsoft.VisualStudio.Validation": "17.8.8", - "System.IO.Pipelines": "8.0.0" + "Microsoft.VisualStudio.Validation": "17.8.8" } }, "System.Configuration.ConfigurationManager": { @@ -172,16 +158,6 @@ "System.Security.Cryptography.ProtectedData": "4.4.0" } }, - "System.IO.Pipelines": { - "type": "Transitive", - "resolved": "8.0.0", - "contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==" - }, - "System.Reflection.Metadata": { - "type": "Transitive", - "resolved": "1.6.0", - "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" - }, "System.Security.Cryptography.ProtectedData": { "type": "Transitive", "resolved": "4.4.0", @@ -245,11 +221,7 @@ "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[9.0.300, )", - "System.Collections.Immutable": "[8.0.0, )", - "System.Diagnostics.DiagnosticSource": "[8.0.1, )", - "System.Memory": "[4.6.0, )", - "System.Runtime": "[4.3.1, )" + "FSharp.Core": "[9.0.300, )" } }, "Argu": { @@ -327,22 +299,9 @@ "Microsoft.VisualStudio.Threading.Analyzers": "17.10.48", "Microsoft.VisualStudio.Validation": "17.8.8", "Nerdbank.Streams": "2.11.74", - "Newtonsoft.Json": "13.0.1", - "System.IO.Pipelines": "8.0.0" + "Newtonsoft.Json": "13.0.1" } }, - "System.Collections.Immutable": { - "type": "CentralTransitive", - "requested": "[8.0.0, )", - "resolved": "8.0.0", - "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==" - }, - "System.Diagnostics.DiagnosticSource": { - "type": "CentralTransitive", - "requested": "[8.0.1, )", - "resolved": "8.0.1", - "contentHash": "vaoWjvkG1aenR2XdjaVivlCV9fADfgyhW5bZtXT23qaEea0lWiUljdQuze4E31vKM7ZWJaSUsbYIKE3rnzfZUg==" - }, "System.IO.Abstractions": { "type": "CentralTransitive", "requested": "[21.1.3, )", @@ -353,22 +312,6 @@ "TestableIO.System.IO.Abstractions.Wrappers": "21.1.3" } }, - "System.Memory": { - "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg==" - }, - "System.Runtime": { - "type": "CentralTransitive", - "requested": "[4.3.1, )", - "resolved": "4.3.1", - "contentHash": "abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", - "Microsoft.NETCore.Targets": "1.1.3" - } - }, "Thoth.Json.Net": { "type": "CentralTransitive", "requested": "[12.0.0, )", diff --git a/src/Fantomas/Fantomas.fsproj b/src/Fantomas/Fantomas.fsproj index 08a87ac2bd..cb1f9b3788 100644 --- a/src/Fantomas/Fantomas.fsproj +++ b/src/Fantomas/Fantomas.fsproj @@ -1,7 +1,7 @@ Exe - net8.0 + net10.0 en diff --git a/src/Fantomas/packages.lock.json b/src/Fantomas/packages.lock.json index 86e7420ce4..48c198f8dc 100644 --- a/src/Fantomas/packages.lock.json +++ b/src/Fantomas/packages.lock.json @@ -1,7 +1,7 @@ { "version": 2, "dependencies": { - "net8.0": { + "net10.0": { "Argu": { "type": "Direct", "requested": "[6.2.4, )", @@ -107,8 +107,7 @@ "Microsoft.VisualStudio.Threading.Analyzers": "17.10.48", "Microsoft.VisualStudio.Validation": "17.8.8", "Nerdbank.Streams": "2.11.74", - "Newtonsoft.Json": "13.0.1", - "System.IO.Pipelines": "8.0.0" + "Newtonsoft.Json": "13.0.1" } }, "System.IO.Abstractions": { @@ -164,16 +163,6 @@ "resolved": "17.6.3", "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" }, - "Microsoft.NETCore.Platforms": { - "type": "Transitive", - "resolved": "1.1.1", - "contentHash": "TMBuzAHpTenGbGgk0SMTwyEkyijY/Eae4ZGsFNYJvAr/LDn1ku3Etp3FPxChmDp5HHF3kzJuoaa08N0xjqAJfQ==" - }, - "Microsoft.NETCore.Targets": { - "type": "Transitive", - "resolved": "1.1.3", - "contentHash": "3Wrmi0kJDzClwAC+iBdUBpEKmEle8FQNsCs77fkiOIw/9oYA07bL1EZNX0kQ2OMN3xpwvl0vAtOCYY3ndDNlhQ==" - }, "Microsoft.SourceLink.AzureRepos.Git": { "type": "Transitive", "resolved": "1.1.1", @@ -240,8 +229,7 @@ "contentHash": "r4G7uHHfoo8LCilPOdtf2C+Q5ymHOAXtciT4ZtB2xRlAvv4gPkWBYNAijFblStv3+uidp81j5DP11jMZl4BfJw==", "dependencies": { "Microsoft.VisualStudio.Threading": "17.10.48", - "Microsoft.VisualStudio.Validation": "17.8.8", - "System.IO.Pipelines": "8.0.0" + "Microsoft.VisualStudio.Validation": "17.8.8" } }, "System.Configuration.ConfigurationManager": { @@ -252,11 +240,6 @@ "System.Security.Cryptography.ProtectedData": "4.4.0" } }, - "System.IO.Pipelines": { - "type": "Transitive", - "resolved": "8.0.0", - "contentHash": "FHNOatmUq0sqJOkTx+UF/9YK1f180cnW5FVqnQMvYUN0elp6wFzbtPSiqbo1/ru8ICp43JM1i7kKkk6GsNGHlA==" - }, "System.Security.Cryptography.ProtectedData": { "type": "Transitive", "resolved": "4.4.0", @@ -293,11 +276,7 @@ "fantomas.fcs": { "type": "Project", "dependencies": { - "FSharp.Core": "[9.0.300, )", - "System.Collections.Immutable": "[8.0.0, )", - "System.Diagnostics.DiagnosticSource": "[8.0.1, )", - "System.Memory": "[4.6.0, )", - "System.Runtime": "[4.3.1, )" + "FSharp.Core": "[9.0.300, )" } }, "Newtonsoft.Json": { @@ -311,34 +290,6 @@ "requested": "[2.0.2, )", "resolved": "2.0.2", "contentHash": "4EQgYdNZ92SyaO7YFk6olVnebF5V+jrHyMUjvPq89tLeMo8NSfgDF+6Zwq/lgh9j/0yfQp9Lkm0ZA0rUATCZFA==" - }, - "System.Collections.Immutable": { - "type": "CentralTransitive", - "requested": "[8.0.0, )", - "resolved": "8.0.0", - "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==" - }, - "System.Diagnostics.DiagnosticSource": { - "type": "CentralTransitive", - "requested": "[8.0.1, )", - "resolved": "8.0.1", - "contentHash": "vaoWjvkG1aenR2XdjaVivlCV9fADfgyhW5bZtXT23qaEea0lWiUljdQuze4E31vKM7ZWJaSUsbYIKE3rnzfZUg==" - }, - "System.Memory": { - "type": "CentralTransitive", - "requested": "[4.6.0, )", - "resolved": "4.6.0", - "contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg==" - }, - "System.Runtime": { - "type": "CentralTransitive", - "requested": "[4.3.1, )", - "resolved": "4.3.1", - "contentHash": "abhfv1dTK6NXOmu4bgHIONxHyEqFjW8HwXPmpY9gmll+ix9UNo4XDcmzJn6oLooftxNssVHdJC1pGT9jkSynQg==", - "dependencies": { - "Microsoft.NETCore.Platforms": "1.1.1", - "Microsoft.NETCore.Targets": "1.1.3" - } } } } From b3db7ec73703bfb7fc70425234a3b02007ce3277 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 06:29:57 +0100 Subject: [PATCH 05/11] Don't print formatted code --- src/Fantomas.Core.Tests/CodeFormatterTests.fs | 1 - src/Fantomas.Core.Tests/TestHelpers.fs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Fantomas.Core.Tests/CodeFormatterTests.fs b/src/Fantomas.Core.Tests/CodeFormatterTests.fs index f44801cc39..89e0f862cf 100644 --- a/src/Fantomas.Core.Tests/CodeFormatterTests.fs +++ b/src/Fantomas.Core.Tests/CodeFormatterTests.fs @@ -4,7 +4,6 @@ open Fantomas.Core.SyntaxOak open NUnit.Framework open Fantomas.FCS.Text open Fantomas.Core -open Fantomas.Core.SyntaxOak open Fantomas.Core.Tests.TestHelpers [] diff --git a/src/Fantomas.Core.Tests/TestHelpers.fs b/src/Fantomas.Core.Tests/TestHelpers.fs index 616b5e2d8e..76c88a3d35 100644 --- a/src/Fantomas.Core.Tests/TestHelpers.fs +++ b/src/Fantomas.Core.Tests/TestHelpers.fs @@ -31,7 +31,7 @@ let formatFSharpString isFsiFile (s: string) config = if formattedCode <> secondFormattedCode then failwith $"The formatted result was not idempotent.\n%s{formattedCode}\n%s{secondFormattedCode}" - printfn "formatted code:\n%s\n" formattedCode + // printfn "formatted code:\n%s\n" formattedCode return formattedCode } From 13b26a70ed6144d21522edc0e528f2e24c47fb5f Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 06:44:53 +0100 Subject: [PATCH 06/11] Fix parsing errors using anonymous records and code quotations (#18603) --- Directory.Build.props | 2 +- src/Fantomas.Core.Tests/QuotationTests.fs | 16 ++++++++++++++++ src/Fantomas.Core/ASTTransformer.fs | 5 +++-- src/Fantomas.Core/Trivia.fs | 15 +++++++++------ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 1d03c11ff1..7289a2d9f9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ Some common use cases include: - 20ff6a94300b5f2f5498d3d8ad1a44abaabc5c22 + a1a156d3b64814ad28d53cc51848f423b0c5bad3 diff --git a/src/Fantomas.Core.Tests/QuotationTests.fs b/src/Fantomas.Core.Tests/QuotationTests.fs index 39f40f8a02..7e6d84f67a 100644 --- a/src/Fantomas.Core.Tests/QuotationTests.fs +++ b/src/Fantomas.Core.Tests/QuotationTests.fs @@ -170,3 +170,19 @@ test Pop = null } } @> """ + +[] +let ``quotation in anonymous record`` () = + formatSourceString + """ +{| A= <@ 1 + 1 @>|} +{| A = <@@ 1 + 1 @@>|} +""" + { config with IndentSize = 2 } + |> prepend newline + |> should + equal + """ +{| A = <@ 1 + 1 @> |} +{| A = <@@ 1 + 1 @@> |} +""" diff --git a/src/Fantomas.Core/ASTTransformer.fs b/src/Fantomas.Core/ASTTransformer.fs index 8916c767d8..5c41e2b3ef 100644 --- a/src/Fantomas.Core/ASTTransformer.fs +++ b/src/Fantomas.Core/ASTTransformer.fs @@ -3618,11 +3618,12 @@ let includeTrivia (baseRange: range) (trivia: ParsedInputTrivia) : range = | ConditionalDirectiveTrivia.Else(range = range) | ConditionalDirectiveTrivia.EndIf(range = range) -> range) trivia.ConditionalDirectives + yield! List.map (function - | WarnDirectiveTrivia.Nowarn range - | WarnDirectiveTrivia.Warnon range -> range) + | WarnDirectiveTrivia.Nowarn(_, range) + | WarnDirectiveTrivia.Warnon(_, range) -> range) trivia.WarnDirectives ] (baseRange, ranges) diff --git a/src/Fantomas.Core/Trivia.fs b/src/Fantomas.Core/Trivia.fs index 4d243ee753..efa9dcf169 100644 --- a/src/Fantomas.Core/Trivia.fs +++ b/src/Fantomas.Core/Trivia.fs @@ -136,12 +136,12 @@ type ConditionalDirectiveTrivia with | ConditionalDirectiveTrivia.Else m | ConditionalDirectiveTrivia.EndIf m -> m -type WarnDirectiveTrivia with +// type WarnDirectiveTrivia with - member x.Range = - match x with - | WarnDirectiveTrivia.Nowarn m - | WarnDirectiveTrivia.Warnon m -> m +// member x.Range = +// match x with +// | WarnDirectiveTrivia.Nowarn m +// | WarnDirectiveTrivia.Warnon m -> m let internal collectTriviaFromDirectiveRanges (source: ISourceText) @@ -335,7 +335,10 @@ let enrichTree (config: FormatConfig) (sourceText: ISourceText) (ast: ParsedInpu let directiveRanges = (parsedTrivia.ConditionalDirectives |> List.map _.Range) - @ (parsedTrivia.WarnDirectives |> List.map _.Range) + @ (parsedTrivia.WarnDirectives + |> List.map (function + | WarnDirectiveTrivia.Nowarn(_, m) + | WarnDirectiveTrivia.Warnon(_, m) -> m)) let directives = collectTriviaFromDirectiveRanges sourceText directiveRanges fullTreeRange From 736b616d6f69460884e3e4e2e96b16414733b3bc Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 06:47:26 +0100 Subject: [PATCH 07/11] Fix warn scopes trivia for fantomas #18637 --- Directory.Build.props | 2 +- src/Fantomas.Core/ASTTransformer.fs | 4 ++-- src/Fantomas.Core/Trivia.fs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 7289a2d9f9..175c26f631 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ Some common use cases include: - a1a156d3b64814ad28d53cc51848f423b0c5bad3 + a3e51909bdeca89357a97e516503e20fd7254f45 diff --git a/src/Fantomas.Core/ASTTransformer.fs b/src/Fantomas.Core/ASTTransformer.fs index 5c41e2b3ef..fc642da385 100644 --- a/src/Fantomas.Core/ASTTransformer.fs +++ b/src/Fantomas.Core/ASTTransformer.fs @@ -3622,8 +3622,8 @@ let includeTrivia (baseRange: range) (trivia: ParsedInputTrivia) : range = yield! List.map (function - | WarnDirectiveTrivia.Nowarn(_, range) - | WarnDirectiveTrivia.Warnon(_, range) -> range) + | WarnDirectiveTrivia.Nowarn(range) + | WarnDirectiveTrivia.Warnon(range) -> range) trivia.WarnDirectives ] (baseRange, ranges) diff --git a/src/Fantomas.Core/Trivia.fs b/src/Fantomas.Core/Trivia.fs index efa9dcf169..3c8712a931 100644 --- a/src/Fantomas.Core/Trivia.fs +++ b/src/Fantomas.Core/Trivia.fs @@ -337,8 +337,8 @@ let enrichTree (config: FormatConfig) (sourceText: ISourceText) (ast: ParsedInpu (parsedTrivia.ConditionalDirectives |> List.map _.Range) @ (parsedTrivia.WarnDirectives |> List.map (function - | WarnDirectiveTrivia.Nowarn(_, m) - | WarnDirectiveTrivia.Warnon(_, m) -> m)) + | WarnDirectiveTrivia.Nowarn(m) + | WarnDirectiveTrivia.Warnon(m) -> m)) let directives = collectTriviaFromDirectiveRanges sourceText directiveRanges fullTreeRange From 599c6d5ecc50ebdad4d6b4cc4a10ff7f2fbcd412 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 07:27:31 +0100 Subject: [PATCH 08/11] Mark Range.Zero as obsolete in favor of Range.range0 #18664 --- Directory.Build.props | 2 +- .../ASTTransformerTests.fs | 14 ++--- .../CodePrinterHelperFunctionsTests.fs | 4 +- src/Fantomas.Core.Tests/SynLongIdentTests.fs | 10 ++-- src/Fantomas.Core/ASTTransformer.fs | 20 +++---- src/Fantomas.Core/CodePrinter.fs | 12 ++-- src/Fantomas.Core/RangeHelpers.fs | 3 + src/Fantomas.Core/RangeHelpers.fsi | 3 + src/Fantomas.Core/Selection.fs | 2 +- src/Fantomas.Core/SyntaxOak.fs | 58 ++++++++++++++++++- 10 files changed, 94 insertions(+), 34 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 175c26f631..9487c38e23 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ Some common use cases include: - a3e51909bdeca89357a97e516503e20fd7254f45 + ee71c6a065bdf57409b16a6bbbfcc3afa2fbef89 diff --git a/src/Fantomas.Core.Tests/ASTTransformerTests.fs b/src/Fantomas.Core.Tests/ASTTransformerTests.fs index 41a5b7c9e0..2cb7409581 100644 --- a/src/Fantomas.Core.Tests/ASTTransformerTests.fs +++ b/src/Fantomas.Core.Tests/ASTTransformerTests.fs @@ -11,8 +11,8 @@ open Fantomas.Core let ``avoid stack-overflow in long array/list, 2485`` () = let mkStringExpr () = SynExpr.Const( - SynConst.String((System.Guid.NewGuid().ToString("N"), SynStringKind.Regular, Range.Zero)), - Range.Zero + SynConst.String((System.Guid.NewGuid().ToString("N"), SynStringKind.Regular, Range.range0)), + Range.range0 ) let longArrayExpr: SynExpr = @@ -27,28 +27,28 @@ let ``avoid stack-overflow in long array/list, 2485`` () = true, mkStringExpr (), childExpr, - Range.Zero, + Range.range0, SynExprSequentialTrivia.Zero )) - SynExpr.ArrayOrListComputed(true, mkArray 0 (mkStringExpr ()), Range.Zero) + SynExpr.ArrayOrListComputed(true, mkArray 0 (mkStringExpr ()), Range.range0) let ast = ParsedInput.ImplFile( ParsedImplFileInput( "filename.fsx", true, - QualifiedNameOfFile(Ident("", Range.Zero)), + QualifiedNameOfFile(Ident("", Range.range0)), [], [ SynModuleOrNamespace( [], false, SynModuleOrNamespaceKind.AnonModule, - [ SynModuleDecl.Expr(longArrayExpr, Range.Zero) ], + [ SynModuleDecl.Expr(longArrayExpr, Range.range0) ], PreXmlDoc.Empty, [], None, - Range.Zero, + Range.range0, { LeadingKeyword = SynModuleOrNamespaceLeadingKeyword.None } ) ], (false, false), diff --git a/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs b/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs index 82d131e21a..5e28a189ab 100644 --- a/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs +++ b/src/Fantomas.Core.Tests/CodePrinterHelperFunctionsTests.fs @@ -209,7 +209,7 @@ let a = // Let's create a dummy Oak // In practise, a FCS Syntax tree will be transformed to an Oak - let zeroRange = Fantomas.FCS.Text.Range.Zero + let zeroRange = Fantomas.FCS.Text.Range.range0 let stn text = SingleTextNode(text, zeroRange) let tree = @@ -321,7 +321,7 @@ let b = 2 """ // Imagine that we always want to print a new line between let bindings. - let zeroRange = Fantomas.FCS.Text.Range.Zero + let zeroRange = Fantomas.FCS.Text.Range.range0 let stn text = SingleTextNode(text, zeroRange) let mkBinding name body = diff --git a/src/Fantomas.Core.Tests/SynLongIdentTests.fs b/src/Fantomas.Core.Tests/SynLongIdentTests.fs index c10079c6c1..ef99c6e95a 100644 --- a/src/Fantomas.Core.Tests/SynLongIdentTests.fs +++ b/src/Fantomas.Core.Tests/SynLongIdentTests.fs @@ -344,7 +344,7 @@ let path = [] let ``backticks can be added from AST only scenarios`` () = let tree = - let testIdent = Ident("Test", Range.Zero) + let testIdent = Ident("Test", Range.range0) ParsedInput.ImplFile( ParsedImplFileInput( @@ -360,19 +360,19 @@ let ``backticks can be added from AST only scenarios`` () = SynExpr.LongIdent( false, SynLongIdent( - [ Ident("new", Range.Zero) ], + [ Ident("new", Range.range0) ], [], [ Some(IdentTrivia.OriginalNotation "``new``") ] ), None, - Range.Zero + Range.range0 ), - Range.Zero + Range.range0 ) ], PreXmlDoc.Empty, [], None, - Range.Zero, + Range.range0, { LeadingKeyword = SynModuleOrNamespaceLeadingKeyword.None } ) ], (true, false), diff --git a/src/Fantomas.Core/ASTTransformer.fs b/src/Fantomas.Core/ASTTransformer.fs index fc642da385..cc06be3ffc 100644 --- a/src/Fantomas.Core/ASTTransformer.fs +++ b/src/Fantomas.Core/ASTTransformer.fs @@ -1276,7 +1276,7 @@ let mkExpr (creationAide: CreationAide) (e: SynExpr) : Expr = ExprNamedComputationNode( mkExpr creationAide expr, stn "{" mOpen, - Expr.Ident(stn "" Range.Zero), + Expr.Ident(stn "" Range.range0), stn "}" mClose, m ) @@ -1810,7 +1810,7 @@ let mkPat (creationAide: CreationAide) (p: SynPat) = | None -> unionRanges ident.idRange pat.Range | Some prefix -> unionRanges prefix.Range pat.Range - let eqNode = stn "=" (Option.defaultValue Range.Zero eq) + let eqNode = stn "=" (Option.defaultValue Range.range0 eq) PatRecordField(prefix, mkIdent ident, eqNode, mkPat creationAide pat, range)) PatRecordNode(stn "{" o, fields, stn "}" c, patternRange) |> Pattern.Record @@ -3222,7 +3222,7 @@ let mkModuleOrNamespace | SynModuleOrNamespaceLeadingKeyword.Namespace mNamespace -> match kind with | SynModuleOrNamespaceKind.GlobalNamespace -> - Some(MultipleTextsNode([ stn "namespace" mNamespace; stn "global" Range.Zero ], mNamespace)) + Some(MultipleTextsNode([ stn "namespace" mNamespace; stn "global" Range.range0 ], mNamespace)) | _ -> Some(MultipleTextsNode([ stn "namespace" mNamespace ], mNamespace)) | SynModuleOrNamespaceLeadingKeyword.None -> None @@ -3547,7 +3547,7 @@ let mkModuleOrNamespaceSig | SynModuleOrNamespaceLeadingKeyword.Namespace mNamespace -> match kind with | SynModuleOrNamespaceKind.GlobalNamespace -> - Some(MultipleTextsNode([ stn "namespace" mNamespace; stn "global" Range.Zero ], mNamespace)) + Some(MultipleTextsNode([ stn "namespace" mNamespace; stn "global" Range.range0 ], mNamespace)) | _ -> Some(MultipleTextsNode([ stn "namespace" mNamespace ], mNamespace)) | SynModuleOrNamespaceLeadingKeyword.None -> None @@ -3639,7 +3639,7 @@ let mkSynModuleOrNamespaceFullRange (mn: SynModuleOrNamespace) = match mn with | SynModuleOrNamespace(kind = SynModuleOrNamespaceKind.AnonModule; decls = decls) -> match List.tryHead decls, List.tryLast decls with - | None, None -> Range.Zero + | None, None -> RangeHelpers.absoluteZeroRange | Some d, None | None, Some d -> d.Range | Some s, Some e -> unionRanges s.Range e.Range @@ -3649,7 +3649,7 @@ let mkSynModuleOrNamespaceSigFullRange (mn: SynModuleOrNamespaceSig) = match mn with | SynModuleOrNamespaceSig(kind = SynModuleOrNamespaceKind.AnonModule; decls = decls) -> match List.tryHead decls, List.tryLast decls with - | None, None -> Range.Zero + | None, None -> RangeHelpers.absoluteZeroRange | Some d, None | None, Some d -> d.Range | Some s, Some e -> unionRanges s.Range e.Range @@ -3665,13 +3665,13 @@ let mkFullTreeRange ast = | [] -> match modules with | m :: _ -> mkSynModuleOrNamespaceFullRange m - | _ -> Range.Zero + | _ -> RangeHelpers.absoluteZeroRange let endPos = match List.tryLast modules with | None -> match List.tryLast directives with - | None -> Range.Zero + | None -> RangeHelpers.absoluteZeroRange | Some(ParsedHashDirective(range = r)) -> r | Some lastModule -> mkSynModuleOrNamespaceFullRange lastModule @@ -3685,13 +3685,13 @@ let mkFullTreeRange ast = | [] -> match modules with | m :: _ -> mkSynModuleOrNamespaceSigFullRange m - | _ -> Range.Zero + | _ -> RangeHelpers.absoluteZeroRange let endPos = match List.tryLast modules with | None -> match List.tryLast directives with - | None -> Range.Zero + | None -> RangeHelpers.absoluteZeroRange | Some(ParsedHashDirective(range = r)) -> r | Some lastModule -> mkSynModuleOrNamespaceSigFullRange lastModule diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 4d46481517..ffe7117d83 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -1049,9 +1049,9 @@ let genExpr (e: Expr) = let parenExpr = mkExprParenNode node.OpeningParen - (Expr.Null(SingleTextNode("", Fantomas.FCS.Text.Range.Zero))) + (Expr.Null(SingleTextNode("", Fantomas.FCS.Text.Range.range0))) node.ClosingParen - Fantomas.FCS.Text.Range.Zero + Fantomas.FCS.Text.Range.range0 sepSpaceBeforeParenInFuncInvocation node.FunctionName parenExpr | _ -> sepSpace @@ -1886,16 +1886,16 @@ let genTupleExpr (node: ExprTupleNode) = | IsLambdaOrIfThenElse e -> let parenNode = mkExprParenNode - (SingleTextNode("(", Fantomas.FCS.Text.Range.Zero)) + (SingleTextNode("(", Fantomas.FCS.Text.Range.range0)) e - (SingleTextNode(")", Fantomas.FCS.Text.Range.Zero)) - Fantomas.FCS.Text.Range.Zero + (SingleTextNode(")", Fantomas.FCS.Text.Range.range0)) + Fantomas.FCS.Text.Range.range0 ExprInfixAppNode( exprInfixAppNode.LeftHandSide, exprInfixAppNode.Operator, parenNode, - Fantomas.FCS.Text.range.Zero + Fantomas.FCS.Text.Range.range0 ) |> Expr.InfixApp | _ -> expr diff --git a/src/Fantomas.Core/RangeHelpers.fs b/src/Fantomas.Core/RangeHelpers.fs index 16f3863cd6..bacfae40bc 100644 --- a/src/Fantomas.Core/RangeHelpers.fs +++ b/src/Fantomas.Core/RangeHelpers.fs @@ -27,6 +27,9 @@ module RangeHelpers = startRange, endRange + let absoluteZeroRange = + Range.mkRange Range.range0.FileName (Position.mkPos 0 0) (Position.mkPos 0 0) + module RangePatterns = let (|StartEndRange|) (size: int) (range: range) = let o, c = RangeHelpers.mkStartEndRange size range diff --git a/src/Fantomas.Core/RangeHelpers.fsi b/src/Fantomas.Core/RangeHelpers.fsi index 36033b7534..7e156375e7 100644 --- a/src/Fantomas.Core/RangeHelpers.fsi +++ b/src/Fantomas.Core/RangeHelpers.fsi @@ -8,6 +8,9 @@ module RangeHelpers = val rangeContainsRange: a: Range -> b: Range -> bool val rangeEq: (range -> range -> bool) val isAdjacentTo: r1: Range -> r2: Range -> bool + /// Range.range0 starts at line 1, column 0 + /// This range starts at line 0, column 0 + val absoluteZeroRange: Range module RangePatterns = val (|StartEndRange|): size: int -> range: range -> range * range * range diff --git a/src/Fantomas.Core/Selection.fs b/src/Fantomas.Core/Selection.fs index 66d4ad3400..25f68136a8 100644 --- a/src/Fantomas.Core/Selection.fs +++ b/src/Fantomas.Core/Selection.fs @@ -95,7 +95,7 @@ let mkExtractableOakFromModule (md: ModuleDecl) (t: System.Type) = TreeForSelection.RequiresExtraction(Oak([], [ ModuleOrNamespaceNode(None, [ md ], m) ], m), t) let dummyUnit: Expr = - UnitNode(SingleTextNode("(", Range.Zero), SingleTextNode(")", Range.Zero), Range.Zero) + UnitNode(SingleTextNode("(", Range.range0), SingleTextNode(")", Range.range0), Range.range0) |> Constant.Unit |> Expr.Constant diff --git a/src/Fantomas.Core/SyntaxOak.fs b/src/Fantomas.Core/SyntaxOak.fs index c15dc6f0da..79e0c4a557 100644 --- a/src/Fantomas.Core/SyntaxOak.fs +++ b/src/Fantomas.Core/SyntaxOak.fs @@ -1,6 +1,7 @@ module rec Fantomas.Core.SyntaxOak open System.Collections.Generic +open System.Text open Fantomas.FCS.Text type TriviaContent = @@ -15,6 +16,18 @@ type TriviaNode(content: TriviaContent, range: range) = member val Content = content member val Range = range + override x.ToString() = + let rangeStr = $"range: %A{x.Range}" + + match x.Content with + | CommentOnSingleLine s -> $"CommentOnSingleLine(%s{rangeStr}, \"%s{s}\")" + | LineCommentAfterSourceCode s -> $"LineCommentAfterSourceCode(%s{rangeStr}, \"%s{s}\")" + | BlockComment(s, before, after) -> + $"BlockComment(%s{rangeStr}, \"%s{s}\", newlineBefore: %b{before}, newlineAfter: %b{after})" + | Newline -> $"Newline(%s{rangeStr})" + | Directive s -> $"Directive(%s{rangeStr}, \"%s{s}\")" + | Cursor -> $"Cursor(%s{rangeStr})" + [] type Node = abstract ContentBefore: TriviaNode seq @@ -63,6 +76,47 @@ type NodeBase(range: range) = member _.AddCursor cursor = potentialCursor <- Some cursor member _.TryGetCursor = potentialCursor + member private x.AppendToStringWithIndent(sb: StringBuilder, depth: int) = + let indent = String.replicate depth " " + let contentIndent = String.replicate (depth + 1) " " + + sb.Append(indent).Append(x.GetType().Name).Append("(").Append(x.Range) |> ignore + + let hasContentBefore = not (Seq.isEmpty x.ContentBefore) + let hasChildren = not (Array.isEmpty x.Children) + let hasContentAfter = not (Seq.isEmpty x.ContentAfter) + let hasContent = hasContentBefore || hasChildren || hasContentAfter + + if hasContent then + sb.AppendLine() |> ignore + + if hasContentBefore then + for tn in x.ContentBefore do + sb.Append(contentIndent).Append(tn.ToString()).AppendLine() |> ignore + + if hasChildren then + for n in x.Children do + match n with + | :? NodeBase as nb -> + nb.AppendToStringWithIndent(sb, depth + 1) + sb.AppendLine() |> ignore + | _ -> sb.Append(contentIndent).Append(n.ToString()).AppendLine() |> ignore + + if hasContentAfter then + for tn in x.ContentAfter do + sb.Append(contentIndent).Append(tn.ToString()).AppendLine() |> ignore + + sb.Append(indent).Append(")") |> ignore + else + sb.Append(")") |> ignore + + member private x.ToStringWithIndent(depth: int) = + let sb = StringBuilder() + x.AppendToStringWithIndent(sb, depth) + sb.ToString() + + override x.ToString() = x.ToStringWithIndent(0) + interface Node with member x.ContentBefore = x.ContentBefore member x.HasContentBefore = x.HasContentBefore @@ -91,7 +145,7 @@ let nodeRange (n: Node) = n.Range let combineRanges (ranges: range seq) = if Seq.isEmpty ranges then - Range.Zero + Range.range0 else Seq.reduce Range.unionRanges ranges @@ -111,7 +165,7 @@ type IdentListNode(content: IdentifierOrDot list, range) = inherit NodeBase(range) member val IsEmpty = content.IsEmpty member val Content = content - static member Empty = IdentListNode(List.empty, Range.Zero) + static member Empty = IdentListNode(List.empty, Range.range0) override x.Children = x.Content From c888913296deea2d6ad1f6f4d397b9b5175830d1 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 07:45:24 +0100 Subject: [PATCH 09/11] Allow typed bindings(and!) in CE without parentheses #18682 --- Directory.Build.props | 2 +- .../ComputationExpressionTests.fs | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 9487c38e23..5b652b0638 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ Some common use cases include: - ee71c6a065bdf57409b16a6bbbfcc3afa2fbef89 + e7abd441a96d555549bfc6e6f84cd3feb897e478 diff --git a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs index 1b7912be90..42c926327e 100644 --- a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs +++ b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs @@ -2467,3 +2467,65 @@ A() {} """ A() { } """ + +[] +let ``typed let bang expression`` () = + formatSourceString + """ +async { + let! { Name = name }: Person = asyncPerson() + return name +} +""" + config + |> prepend newline + |> should + equal + """ +async { + let! { Name = name }: Person = asyncPerson () + return name +} +""" + +[] +let ``unwrap union case in computation expression`` () = + formatSourceString + """ +async { + let! Union value = asyncOption() + () +} +""" + config + |> prepend newline + |> should + equal + """ +async { + let! Union value = asyncOption () + () +} +""" + +[] +let ``typed and bang expression`` () = + formatSourceString + """ +async { + let! x: int = doX() + and! y: int = doY() + return x + y +} +""" + config + |> prepend newline + |> should + equal + """ +async { + let! x: int = doX () + and! y: int = doY () + return x + y +} +""" From 2aa9efd1a72c8c2d1ece4fcd7975fcbbddcb23e8 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 08:57:30 +0100 Subject: [PATCH 10/11] Use Synbinding to model and! #18805 --- Directory.Build.props | 2 +- docs/docs/contributors/Transforming.md | 9 +++++ .../ComputationExpressionTests.fs | 5 +++ src/Fantomas.Core/ASTTransformer.fs | 35 ++++++++++++------- src/Fantomas.Core/CodePrinter.fs | 12 ++----- src/Fantomas.Core/SyntaxOak.fs | 16 +-------- src/Fantomas.Core/Trivia.fs | 1 - 7 files changed, 41 insertions(+), 39 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 67ddff7f00..2db80d1750 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ Some common use cases include: - e7abd441a96d555549bfc6e6f84cd3feb897e478 + 8680acde3363052f114d73b0fe21bb3f4cf82b28 diff --git a/docs/docs/contributors/Transforming.md b/docs/docs/contributors/Transforming.md index 0b96378684..b4ecfddde0 100644 --- a/docs/docs/contributors/Transforming.md +++ b/docs/docs/contributors/Transforming.md @@ -74,6 +74,15 @@ let a = Depending on the defines `[]` or `["DEBUG"]`, the AST will be different. The tree will also be created based on a single code path. +You can use your locally installed F# compiler to parse a file and view the AST via: + +```shell +# Tip: figure out the location of your installed sdk +whereis dotnet +# Invoke the parser +dotnet '/Users/nojaf/Library/Application Support/dnvm/dn/sdk/10.0.100/FSharp/fsc.dll' --parseonly --ast foo.fs +``` + ### Transform untyped AST to Oak The untyped syntax tree from the F# compiler is used as an intermediate representation of source code in the process of transforming a text file to binary. diff --git a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs index 42c926327e..db7038620c 100644 --- a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs +++ b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs @@ -1360,6 +1360,11 @@ let loginHandler = """ [] +[] let ``all keywords`` () = formatSourceString """ diff --git a/src/Fantomas.Core/ASTTransformer.fs b/src/Fantomas.Core/ASTTransformer.fs index ef999ef55a..dc39d12700 100644 --- a/src/Fantomas.Core/ASTTransformer.fs +++ b/src/Fantomas.Core/ASTTransformer.fs @@ -349,18 +349,29 @@ let rec collectComputationExpressionStatements let andBangs = andBangs - |> List.map - (fun - (SynExprAndBang(_, - _, - _, - ap, - ae, - m, - { AndBangKeyword = mAnd - EqualsRange = mEq })) -> - ExprAndBang(stn "and!" mAnd, mkPat creationAide ap, stn "=" mEq, mkExpr creationAide ae, m) - |> ComputationExpressionStatement.AndBangStatement) + |> List.map (fun binding -> + let bindingNode = mkBinding creationAide binding + // let SynBinding(trivia = { LeadingKeyword = lk }) = binding is "and" and not "and!" + + BindingNode( + bindingNode.XmlDoc, + bindingNode.Attributes, + MultipleTextsNode( + [ stn "and!" bindingNode.LeadingKeyword.Range ], + bindingNode.LeadingKeyword.Range + ), + bindingNode.IsMutable, + bindingNode.Inline, + bindingNode.Accessibility, + bindingNode.FunctionName, + bindingNode.GenericTypeParameters, + bindingNode.Parameters, + bindingNode.ReturnType, + bindingNode.Equals, + bindingNode.Expr, + bindingNode.Range + ) + |> ComputationExpressionStatement.AndBangStatement) collectComputationExpressionStatements creationAide body (fun bodyStatements -> [ letOrUseBang; yield! andBangs; yield! bodyStatements ] |> finalContinuation) diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index cdeda4f1be..31337f5436 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -663,15 +663,7 @@ let genExpr (e: Expr) = ColMultilineItem(expr, sepNlnUnlessContentBefore node) | ComputationExpressionStatement.AndBangStatement node -> - let expr = - genSingleTextNode node.LeadingKeyword - +> sepSpace - +> genPat node.Pattern - +> sepSpace - +> genSingleTextNode node.Equals - +> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidthUnlessStroustrup genExpr node.Expression - |> genNode node - + let expr = genBinding node ColMultilineItem(expr, sepNlnUnlessContentBefore node) | ComputationExpressionStatement.OtherStatement e -> ColMultilineItem(genExpr e, sepNlnUnlessContentBefore (Expr.Node e))) @@ -2831,7 +2823,7 @@ let genBinding (b: BindingNode) (ctx: Context) : Context = let isRecursiveLetOrUseFunction = match b.LeadingKeyword.Content with - | [ singleText ] -> singleText.Text = "and" + | [ singleText ] -> singleText.Text = "and" || singleText.Text = "and!" | _ -> false let binding = diff --git a/src/Fantomas.Core/SyntaxOak.fs b/src/Fantomas.Core/SyntaxOak.fs index 79e0c4a557..27074f18e8 100644 --- a/src/Fantomas.Core/SyntaxOak.fs +++ b/src/Fantomas.Core/SyntaxOak.fs @@ -1070,25 +1070,11 @@ type ExprLetOrUseBangNode(leadingKeyword: SingleTextNode, pat: Pattern, equals: member val Equals = equals member val Expression = expr -type ExprAndBang(leadingKeyword: SingleTextNode, pat: Pattern, equals: SingleTextNode, expr: Expr, range) = - inherit NodeBase(range) - - override val Children: Node array = - [| yield leadingKeyword - yield Pattern.Node pat - yield equals - yield Expr.Node expr |] - - member val LeadingKeyword = leadingKeyword - member val Pattern = pat - member val Equals = equals - member val Expression = expr - [] type ComputationExpressionStatement = | LetOrUseStatement of ExprLetOrUseNode | LetOrUseBangStatement of ExprLetOrUseBangNode - | AndBangStatement of ExprAndBang + | AndBangStatement of BindingNode | OtherStatement of Expr static member Node(ces: ComputationExpressionStatement) : Node = diff --git a/src/Fantomas.Core/Trivia.fs b/src/Fantomas.Core/Trivia.fs index 9e0c24057a..eb1faafbd4 100644 --- a/src/Fantomas.Core/Trivia.fs +++ b/src/Fantomas.Core/Trivia.fs @@ -188,7 +188,6 @@ let rec visitLastChildNode (node: Node) : Node = | :? ExprLambdaNode | :? ExprLetOrUseNode | :? ExprLetOrUseBangNode - | :? ExprAndBang | :? BindingNode | :? TypeDefnEnumNode | :? TypeDefnUnionNode From e95be8919a360b27556bbab9a73401cd93e7ad1c Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 14 Nov 2025 13:39:22 +0100 Subject: [PATCH 11/11] Update FCS to Remove LetOrUseKeyword from SynExprLetOrUseTrivia #19090 --- Directory.Build.props | 2 +- build.fsx | 4 +- .../ComputationExpressionTests.fs | 4 +- src/Fantomas.Core/ASTTransformer.fs | 77 ++++--------------- src/Fantomas.Core/CodePrinter.fs | 64 ++++----------- src/Fantomas.Core/SyntaxOak.fs | 29 ++----- src/Fantomas.FCS/Fantomas.FCS.fsproj | 6 ++ 7 files changed, 50 insertions(+), 136 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 2db80d1750..cb27543393 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ Some common use cases include: - 8680acde3363052f114d73b0fe21bb3f4cf82b28 + 44c58e9663ebcb52f0eebd618af50852a831a50d diff --git a/build.fsx b/build.fsx index d05a14437d..11246e57c0 100644 --- a/build.fsx +++ b/build.fsx @@ -210,7 +210,7 @@ let downloadCompilerFile commitHash relativePath = let fs = file.Create() let fileName = Path.GetFileName(relativePath) let url = - $"https://raw.githubusercontent.com/dotnet/fsharp/{commitHash}/{relativePath}" + $"https://raw.githubusercontent.com/nojaf/fsharp/{commitHash}/{relativePath}" let! response = Http.AsyncRequestStream( url, @@ -233,6 +233,8 @@ pipeline "Init" { "src/Compiler/Utilities/NullnessShims.fs" "src/Compiler/Utilities/Activity.fsi" "src/Compiler/Utilities/Activity.fs" + "src/Compiler/Utilities/Caches.fsi" + "src/Compiler/Utilities/Caches.fs" "src/Compiler/Utilities/sformat.fsi" "src/Compiler/Utilities/sformat.fs" "src/Compiler/Utilities/sr.fsi" diff --git a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs index db7038620c..aeaff8d4ec 100644 --- a/src/Fantomas.Core.Tests/ComputationExpressionTests.fs +++ b/src/Fantomas.Core.Tests/ComputationExpressionTests.fs @@ -1647,7 +1647,9 @@ let private removeSubscription (log : ILogger) (req : HttpRequest) = return sendText "Subscription removed" } """ - { config with SpaceBeforeColon = true } + { config with + SpaceBeforeColon = true + MaxValueBindingWidth = 120 } |> prepend newline |> should equal diff --git a/src/Fantomas.Core/ASTTransformer.fs b/src/Fantomas.Core/ASTTransformer.fs index dc39d12700..a7db1b7842 100644 --- a/src/Fantomas.Core/ASTTransformer.fs +++ b/src/Fantomas.Core/ASTTransformer.fs @@ -298,10 +298,10 @@ let mkTuple (creationAide: CreationAide) (exprs: SynExpr list) (commas: range li /// Recursive and use properties have to be determined at this point let rec (|LetOrUses|_|) = function - | SynExpr.LetOrUse(_, _, xs, LetOrUses(ys, e), _, trivia) -> + | SynExpr.LetOrUse(bindings = xs; body = LetOrUses(ys, e); trivia = trivia) -> let xs' = List.mapWithLast (fun b -> b, None) (fun b -> b, trivia.InKeyword) xs Some(xs' @ ys, e) - | SynExpr.LetOrUse(_, _, xs, e, _, trivia) -> + | SynExpr.LetOrUse(bindings = xs; body = e; trivia = trivia) -> let xs' = List.mapWithLast (fun b -> b, None) (fun b -> b, trivia.InKeyword) xs Some(xs', e) | _ -> None @@ -324,57 +324,10 @@ let rec collectComputationExpressionStatements | Some mIn -> Some(stn "in" mIn), unionRanges b.Range mIn ExprLetOrUseNode(b, inNode, m) - |> ComputationExpressionStatement.LetOrUseStatement) + |> ComputationExpressionStatement.BindingStatement) collectComputationExpressionStatements creationAide body (fun bodyStatements -> [ yield! bindings; yield! bodyStatements ] |> finalContinuation) - | SynExpr.LetOrUseBang(_, - isUse, - _, - pat, - expr, - andBangs, - body, - StartRange 4 (mLeading, _m), - { EqualsRange = Some mEq }) -> - let letOrUseBang = - ExprLetOrUseBangNode( - stn (if isUse then "use!" else "let!") mLeading, - mkPat creationAide pat, - stn "=" mEq, - mkExpr creationAide expr, - unionRanges mLeading expr.Range - ) - |> ComputationExpressionStatement.LetOrUseBangStatement - - let andBangs = - andBangs - |> List.map (fun binding -> - let bindingNode = mkBinding creationAide binding - // let SynBinding(trivia = { LeadingKeyword = lk }) = binding is "and" and not "and!" - - BindingNode( - bindingNode.XmlDoc, - bindingNode.Attributes, - MultipleTextsNode( - [ stn "and!" bindingNode.LeadingKeyword.Range ], - bindingNode.LeadingKeyword.Range - ), - bindingNode.IsMutable, - bindingNode.Inline, - bindingNode.Accessibility, - bindingNode.FunctionName, - bindingNode.GenericTypeParameters, - bindingNode.Parameters, - bindingNode.ReturnType, - bindingNode.Equals, - bindingNode.Expr, - bindingNode.Range - ) - |> ComputationExpressionStatement.AndBangStatement) - - collectComputationExpressionStatements creationAide body (fun bodyStatements -> - [ letOrUseBang; yield! andBangs; yield! bodyStatements ] |> finalContinuation) | SynExpr.Sequential(expr1 = e1; expr2 = e2; trivia = trivia) -> let continuations : ((ComputationExpressionStatement list -> ComputationExpressionStatement list) @@ -1192,7 +1145,6 @@ let mkExpr (creationAide: CreationAide) (e: SynExpr) : Expr = |> Expr.Computation | SynExpr.LetOrUse _ - | SynExpr.LetOrUseBang _ | SynExpr.Sequential _ -> ExprCompExprBodyNode(collectComputationExpressionStatements creationAide e id, exprRange) |> Expr.CompExprBody @@ -1767,14 +1719,14 @@ let mkPat (creationAide: CreationAide) (p: SynPat) = let pairs = nps - |> List.choose (fun (ident, eq, pat) -> + |> List.choose (fun (NamePatPairField(fieldName = fieldName; equalsRange = eq; pat = pat)) -> eq |> Option.map (fun eq -> - NamePatPair( - mkIdent ident, + NamePatPairNode( + mkSynLongIdent creationAide fieldName, stn "=" eq, mkPat creationAide pat, - unionRanges ident.idRange pat.Range + unionRanges fieldName.Range pat.Range ))) PatNamePatPairsNode( @@ -1813,16 +1765,10 @@ let mkPat (creationAide: CreationAide) (p: SynPat) = | SynPat.Record(fields, StartEndRange 1 (o, _, c)) -> let fields = fields - |> List.map (fun ((lid, ident), eq, pat) -> - let prefix = if lid.IsEmpty then None else Some(mkLongIdent lid) - - let range = - match prefix with - | None -> unionRanges ident.idRange pat.Range - | Some prefix -> unionRanges prefix.Range pat.Range - + |> List.map (fun (NamePatPairField(fieldName = fieldName; equalsRange = eq; pat = pat) as np) -> + let range = np.Range // TODO: might be wrong unionRanges prefix.Range pat.Range let eqNode = stn "=" (Option.defaultValue Range.range0 eq) - PatRecordField(prefix, mkIdent ident, eqNode, mkPat creationAide pat, range)) + NamePatPairNode(mkSynLongIdent creationAide fieldName, eqNode, mkPat creationAide pat, range)) PatRecordNode(stn "{" o, fields, stn "}" c, patternRange) |> Pattern.Record | SynPat.Const(c, r) -> mkConstant creationAide c r |> Pattern.Const @@ -2410,9 +2356,12 @@ let mkSynLeadingKeyword (lk: SynLeadingKeyword) = match lk with | SynLeadingKeyword.Let letRange -> mtn [ "let", letRange ] + | SynLeadingKeyword.LetBang letBangRange -> mtn [ "let!", letBangRange ] | SynLeadingKeyword.LetRec(letRange, recRange) -> mtn [ "let", letRange; "rec", recRange ] | SynLeadingKeyword.And andRange -> mtn [ "and", andRange ] + | SynLeadingKeyword.AndBang andBangRange -> mtn [ "and!", andBangRange ] | SynLeadingKeyword.Use useRange -> mtn [ "use", useRange ] + | SynLeadingKeyword.UseBang useBangRange -> mtn [ "use!", useBangRange ] | SynLeadingKeyword.UseRec(useRange, recRange) -> mtn [ "use", useRange; "rec", recRange ] | SynLeadingKeyword.Extern externRange -> mtn [ "extern", externRange ] | SynLeadingKeyword.Member memberRange -> mtn [ "member", memberRange ] diff --git a/src/Fantomas.Core/CodePrinter.fs b/src/Fantomas.Core/CodePrinter.fs index 31337f5436..dd54fb589a 100644 --- a/src/Fantomas.Core/CodePrinter.fs +++ b/src/Fantomas.Core/CodePrinter.fs @@ -644,26 +644,12 @@ let genExpr (e: Expr) = let genStatements = node.Statements |> List.map (function - | ComputationExpressionStatement.LetOrUseStatement node -> + | ComputationExpressionStatement.BindingStatement node -> let expr = genBinding node.Binding +> optSingle (fun inNode -> sepSpace +> genSingleTextNode inNode) node.In |> genNode node - ColMultilineItem(expr, sepNlnUnlessContentBefore node) - | ComputationExpressionStatement.LetOrUseBangStatement node -> - let expr = - genSingleTextNode node.LeadingKeyword - +> sepSpace - +> genPat node.Pattern - +> sepSpace - +> genSingleTextNode node.Equals - +> sepSpaceOrIndentAndNlnIfExpressionExceedsPageWidthUnlessStroustrup genExpr node.Expression - |> genNode node - - ColMultilineItem(expr, sepNlnUnlessContentBefore node) - | ComputationExpressionStatement.AndBangStatement node -> - let expr = genBinding node ColMultilineItem(expr, sepNlnUnlessContentBefore node) | ComputationExpressionStatement.OtherStatement e -> ColMultilineItem(genExpr e, sepNlnUnlessContentBefore (Expr.Node e))) @@ -671,7 +657,7 @@ let genExpr (e: Expr) = |> genNode node match node.Statements with - | [ ComputationExpressionStatement.LetOrUseStatement letOrUseNode + | [ ComputationExpressionStatement.BindingStatement letOrUseNode ComputationExpressionStatement.OtherStatement inExpr ] when letOrUseNode.In.IsSome -> let short = (genBinding letOrUseNode.Binding @@ -2232,7 +2218,7 @@ let genExprInMultilineInfixExpr (e: Expr) = node.Statements |> List.mapWithLast (function - | ComputationExpressionStatement.LetOrUseStatement _ -> true + | ComputationExpressionStatement.BindingStatement _ -> true | _ -> false) (function | ComputationExpressionStatement.OtherStatement _ -> true @@ -2247,7 +2233,7 @@ let genExprInMultilineInfixExpr (e: Expr) = ComputationExpressionStatement.Node (fun ces -> match ces with - | ComputationExpressionStatement.LetOrUseStatement letOrUseNode -> + | ComputationExpressionStatement.BindingStatement letOrUseNode -> let genIn = match letOrUseNode.In with | None -> !-"in" @@ -2618,6 +2604,14 @@ let genTuplePat (node: PatTupleNode) = atCurrentColumn (expressionFitsOnRestOfLine short (atCurrentColumn (genTuplePatLong node))) |> genNode node +let genNamePatPair (node: NamePatPairNode) = + genIdentListNode node.FieldName + +> sepSpace + +> genSingleTextNode node.Equals + +> sepSpace + +> genPat node.Pattern + |> genNode node + let genPat (p: Pattern) = match p with | Pattern.OptionalVal n -> genSingleTextNode n @@ -2646,18 +2640,11 @@ let genPat (p: Pattern) = | Pattern.As node | Pattern.ListCons node -> genPatLeftMiddleRight node | Pattern.NamePatPairs node -> - let genPatWithIdent (node: NamePatPair) = - genSingleTextNode node.Ident - +> sepSpace - +> genSingleTextNode node.Equals - +> sepSpace - +> genPat node.Pattern - |> genNode node let pats = expressionFitsOnRestOfLine - (atCurrentColumn (col sepSemi node.Pairs genPatWithIdent)) - (atCurrentColumn (col sepNln node.Pairs genPatWithIdent)) + (atCurrentColumn (col sepSemi node.Pairs genNamePatPair)) + (atCurrentColumn (col sepNln node.Pairs genNamePatPair)) genIdentListNode node.Identifier +> optSingle genTyparDecls node.TyparDecls @@ -2724,14 +2711,14 @@ let genPat (p: Pattern) = let smallRecordExpr = genSingleTextNode node.OpeningNode +> addSpaceIfSpaceAroundDelimiter - +> col sepSemi node.Fields genPatRecordFieldName + +> col sepSemi node.Fields genNamePatPair +> addSpaceIfSpaceAroundDelimiter +> genSingleTextNode node.ClosingNode let multilineRecordExpr = genSingleTextNode node.OpeningNode +> addSpaceIfSpaceAroundDelimiter - +> atCurrentColumn (col sepNln node.Fields genPatRecordFieldName) + +> atCurrentColumn (col sepNln node.Fields genNamePatPair) +> addSpaceIfSpaceAroundDelimiter +> genSingleTextNode node.ClosingNode @@ -2739,7 +2726,7 @@ let genPat (p: Pattern) = genSingleTextNode node.OpeningNode +> indent +> sepNln - +> atCurrentColumn (col sepNln node.Fields genPatRecordFieldName) + +> atCurrentColumn (col sepNln node.Fields genNamePatPair) +> unindent +> sepNln +> genSingleTextNode node.ClosingNode @@ -2782,23 +2769,6 @@ let genPatInClause (pat: Pattern) = genPatMultiline pat -let genPatRecordFieldName (node: PatRecordField) = - match node.Prefix with - | None -> - genSingleTextNode node.FieldName - +> sepSpace - +> genSingleTextNode node.Equals - +> sepSpace - +> genPat node.Pattern - | Some prefix -> - genIdentListNode prefix - +> sepDot - +> genSingleTextNode node.FieldName - +> sepSpace - +> genSingleTextNode node.Equals - +> sepSpace - +> genPat node.Pattern - let genReturnTypeBinding (node: BindingReturnInfoNode option) = match node with | None -> sepNone diff --git a/src/Fantomas.Core/SyntaxOak.fs b/src/Fantomas.Core/SyntaxOak.fs index 27074f18e8..d0c41d7d9d 100644 --- a/src/Fantomas.Core/SyntaxOak.fs +++ b/src/Fantomas.Core/SyntaxOak.fs @@ -531,10 +531,10 @@ type PatNamedNode(accessibility: SingleTextNode option, name: SingleTextNode, ra member val Name = name member val Accessibility = accessibility -type NamePatPair(ident: SingleTextNode, equals: SingleTextNode, pat: Pattern, range) = +type NamePatPairNode(fieldName: IdentListNode, equals: SingleTextNode, pat: Pattern, range) = inherit NodeBase(range) - override val Children: Node array = [| yield ident; yield equals; yield Pattern.Node pat |] - member val Ident = ident + override val Children: Node array = [| yield fieldName; yield equals; yield Pattern.Node pat |] + member val FieldName = fieldName member val Equals = equals member val Pattern = pat @@ -543,7 +543,7 @@ type PatNamePatPairsNode identifier: IdentListNode, typarDecls: TyparDecls option, openingParen: SingleTextNode, - pairs: NamePatPair list, + pairs: NamePatPairNode list, closingParen: SingleTextNode, range ) = @@ -618,18 +618,7 @@ type PatArrayOrListNode(openToken: SingleTextNode, pats: Pattern list, closeToke member val Patterns = pats member val CloseToken = closeToken -type PatRecordField - (prefix: IdentListNode option, fieldName: SingleTextNode, equals: SingleTextNode, pat: Pattern, range) = - inherit NodeBase(range) - - override val Children: Node array = [| yield! noa prefix; yield fieldName; yield equals; yield Pattern.Node pat |] - - member val Prefix = prefix - member val FieldName = fieldName - member val Equals = equals - member val Pattern = pat - -type PatRecordNode(openingNode: SingleTextNode, fields: PatRecordField list, closingNode: SingleTextNode, range) = +type PatRecordNode(openingNode: SingleTextNode, fields: NamePatPairNode list, closingNode: SingleTextNode, range) = inherit NodeBase(range) override val Children: Node array = [| yield openingNode; yield! nodes fields; yield closingNode |] @@ -1072,16 +1061,12 @@ type ExprLetOrUseBangNode(leadingKeyword: SingleTextNode, pat: Pattern, equals: [] type ComputationExpressionStatement = - | LetOrUseStatement of ExprLetOrUseNode - | LetOrUseBangStatement of ExprLetOrUseBangNode - | AndBangStatement of BindingNode + | BindingStatement of ExprLetOrUseNode | OtherStatement of Expr static member Node(ces: ComputationExpressionStatement) : Node = match ces with - | LetOrUseStatement n -> n - | LetOrUseBangStatement n -> n - | AndBangStatement n -> n + | BindingStatement n -> n | OtherStatement o -> Expr.Node o type ExprCompExprBodyNode(statements: ComputationExpressionStatement list, range) = diff --git a/src/Fantomas.FCS/Fantomas.FCS.fsproj b/src/Fantomas.FCS/Fantomas.FCS.fsproj index 26de30e34b..dbc05bc235 100644 --- a/src/Fantomas.FCS/Fantomas.FCS.fsproj +++ b/src/Fantomas.FCS/Fantomas.FCS.fsproj @@ -33,6 +33,12 @@ Utilities\Activity.fs + + Utilities\Caches.fsi + + + Utilities\Caches.fs + Utilities\sformat.fsi