From 52dda6a534ac705e4f475fa1cd561c72807a5604 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 02:27:52 +0300 Subject: [PATCH 01/15] wip --- src/Compiler/Service/ServiceParsedInputOps.fs | 12 ++++++++ .../CompletionTests.fs | 28 ++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index f5b15936902..429e6a1b3de 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -320,6 +320,18 @@ module ParsedInput = let _, r = CheckLongIdent longIdent Some r + | SynExpr.DotLambda(SynExpr.LongIdent _, range, _) -> Some range + | SynExpr.DotLambda(synExpr, range, _) -> + let result = traverseSynExpr synExpr + + match result with + | None -> None + | Some r as result -> + if posEq r.Start synExpr.Range.Start then + Some range + else + result + | SynExpr.DotGet(synExpr, _dotm, lid, _) -> let (SynLongIdent(longIdent, _, _)) = lid diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index 2d70f5c58f6..bc034525044 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -78,11 +78,31 @@ let record = { Field = 1 } assertHasItemWithNames ["Field"; "record"] info [] -let ``Underscore dot lambda - completion`` () = +let ``Underscore dot lambda - completion 01`` () = let info = getCompletionInfo """ -let myFancyFunc (x:string) = - x - |> _.Len{caret}""" +"" |> _.Len{caret}""" + + assertHasItemWithNames ["Length"] info + +[] +let ``Underscore dot lambda - completion 02`` () = + let info = getCompletionInfo """ +"" |> _.Length.ToStr{caret}""" + + assertHasItemWithNames ["ToString"] info + +[] +let ``Underscore dot lambda - completion 03`` () = + let info = getCompletionInfo """ +"" |> _.ToString().Len{caret}""" + + assertHasItemWithNames ["Length"] info + +[] +let ``Underscore dot lambda - completion 04`` () = + let info = getCompletionInfo """ +"" |> _.Length.ToString().Chars("".Len{caret})""" + assertHasItemWithNames ["Length"] info [] From 657f350060920d1eaa118c1e88c9a8c62a438265 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 02:34:46 +0300 Subject: [PATCH 02/15] +test --- tests/FSharp.Compiler.Service.Tests/CompletionTests.fs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index bc034525044..ef3001ae5c7 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -105,6 +105,13 @@ let ``Underscore dot lambda - completion 04`` () = assertHasItemWithNames ["Length"] info +[] +let ``Underscore dot lambda - completion 05`` () = + let info = getCompletionInfo """ +"" |> _.Len{caret}.ToString()""" + + assertHasItemWithNames ["Length"] info + [] let ``Underscore dot lambda - method completion`` () = let info = getCompletionInfo """ From a15f5c02bc028207e53ea15b90911c4e6bfdf953 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 02:42:10 +0300 Subject: [PATCH 03/15] +test --- .../FSharp.Compiler.Service.Tests/CompletionTests.fs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index ef3001ae5c7..7e2ba6027c1 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -101,17 +101,24 @@ let ``Underscore dot lambda - completion 03`` () = [] let ``Underscore dot lambda - completion 04`` () = let info = getCompletionInfo """ -"" |> _.Length.ToString().Chars("".Len{caret})""" +"" |> _.Len{caret}gth.ToString()""" assertHasItemWithNames ["Length"] info [] let ``Underscore dot lambda - completion 05`` () = let info = getCompletionInfo """ -"" |> _.Len{caret}.ToString()""" +"" |> _.Length.ToString().Chars("".Len{caret})""" assertHasItemWithNames ["Length"] info +[] +let ``Underscore dot lambda - completion 06`` () = + let info = getCompletionInfo """ +"" |> _.Chars(System.DateTime.UtcNow.Tic{caret}).ToString()""" + + assertHasItemWithNames ["Ticks"] info + [] let ``Underscore dot lambda - method completion`` () = let info = getCompletionInfo """ From 4fd1e39e9ff73a67647804dc64eea49de7c2c5bd Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 02:46:13 +0300 Subject: [PATCH 04/15] wip --- src/Compiler/Service/ServiceParsedInputOps.fs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index 429e6a1b3de..b8ffe0d030f 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -324,13 +324,8 @@ module ParsedInput = | SynExpr.DotLambda(synExpr, range, _) -> let result = traverseSynExpr synExpr - match result with - | None -> None - | Some r as result -> - if posEq r.Start synExpr.Range.Start then - Some range - else - result + result + |> Option.map (fun r -> if posEq r.Start synExpr.Range.Start then range else r) | SynExpr.DotGet(synExpr, _dotm, lid, _) -> let (SynLongIdent(longIdent, _, _)) = lid From e92ab817951fbf6f0ecc122be896e9ac842415a0 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 02:58:07 +0300 Subject: [PATCH 05/15] +tests --- .../CompletionTests.fs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index 7e2ba6027c1..0d5a5651af1 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -119,6 +119,21 @@ let ``Underscore dot lambda - completion 06`` () = assertHasItemWithNames ["Ticks"] info +[] +let ``Underscore dot lambda - completion 07`` () = + let info = getCompletionInfo """ +"" |> _.Length.ToString().Len{caret}""" + + assertHasItemWithNames ["Length"] info + +[] +let ``Underscore dot lambda - completion 08`` () = + let info = getCompletionInfo """ +"" |> _.Length + .ToStr{caret}""" + + assertHasItemWithNames ["ToString"] info + [] let ``Underscore dot lambda - method completion`` () = let info = getCompletionInfo """ From e44d0b1f34dcdefa92ab5888f61daeed36e73206 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 15:48:25 +0300 Subject: [PATCH 06/15] wip --- .../CompletionTests.fs | 79 ++++++++++++++++--- 1 file changed, 67 insertions(+), 12 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index 0d5a5651af1..b90a3e4b899 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -87,66 +87,121 @@ let ``Underscore dot lambda - completion 01`` () = [] let ``Underscore dot lambda - completion 02`` () = let info = getCompletionInfo """ -"" |> _.Length.ToStr{caret}""" +"" |> _.Length.{caret}""" - assertHasItemWithNames ["ToString"] info + assertHasItemWithNames ["TryFormat"] info [] let ``Underscore dot lambda - completion 03`` () = let info = getCompletionInfo """ -"" |> _.ToString().Len{caret}""" +"" |> _.Length.ToString().{caret}""" assertHasItemWithNames ["Length"] info [] let ``Underscore dot lambda - completion 04`` () = let info = getCompletionInfo """ +"" |> _.Length.TryF{caret}""" + + assertHasItemWithNames ["TryFormat"] info + +[] +let ``Underscore dot lambda - completion 05`` () = + let info = getCompletionInfo """ +"" |> _.ToString().Len{caret}""" + + assertHasItemWithNames ["Length"] info + +[] +let ``Underscore dot lambda - completion 06`` () = + let info = getCompletionInfo """ "" |> _.Len{caret}gth.ToString()""" assertHasItemWithNames ["Length"] info [] -let ``Underscore dot lambda - completion 05`` () = +let ``Underscore dot lambda - completion 07`` () = let info = getCompletionInfo """ "" |> _.Length.ToString().Chars("".Len{caret})""" assertHasItemWithNames ["Length"] info [] -let ``Underscore dot lambda - completion 06`` () = +let ``Underscore dot lambda - completion 08`` () = let info = getCompletionInfo """ "" |> _.Chars(System.DateTime.UtcNow.Tic{caret}).ToString()""" assertHasItemWithNames ["Ticks"] info [] -let ``Underscore dot lambda - completion 07`` () = +let ``Underscore dot lambda - completion 09`` () = let info = getCompletionInfo """ "" |> _.Length.ToString().Len{caret}""" assertHasItemWithNames ["Length"] info [] -let ``Underscore dot lambda - completion 08`` () = +let ``Underscore dot lambda - completion 10`` () = let info = getCompletionInfo """ "" |> _.Length - .ToStr{caret}""" + .TryF{caret}""" + + assertHasItemWithNames ["TryFormat"] info + +[] +let ``Underscore dot lambda - completion 11`` () = + let info = getCompletionInfo """ +"" |> _.Length.ToSt{caret}.Length""" assertHasItemWithNames ["ToString"] info [] -let ``Underscore dot lambda - method completion`` () = +let ``Underscore dot lambda - completion 12`` () = + let info = getCompletionInfo """ +"" |> _.Chars(0).ToStr{caret}.Length""" + + assertHasItemWithNames ["ToString"] info + +[] +let ``Underscore dot lambda - completion 13`` () = + let info = getCompletionInfo """ +open System.Linq + +[[""]] |> _.Select(_.Head.ToL{caret})""" + + assertHasItemWithNames ["ToLower"] info + +[] +let ``Underscore dot lambda - completion 14`` () = let info = getCompletionInfo """ -let myFancyFunc (x:string) = - x +open System.Linq + +[[[""]]] |> _.Head.Select(_.Head.ToL{caret})""" + + assertHasItemWithNames ["ToLower"] info + +[] +let ``Underscore dot lambda - completion 15`` () = + let info = getCompletionInfo """ +let myFancyFunc (x:string) = + x |> _.ToL{caret}""" assertHasItemWithNames ["ToLower"] info +[] +let ``Underscore dot lambda - completion 16`` () = + let info = getCompletionInfo """ +let myFancyFunc (x:string) = + x + |> _.Length.TryF{caret} + |> id""" + assertHasItemWithNames ["TryFormat"] info + [] let ``Underscore dot lambda - No prefix`` () = let info = getCompletionInfo """ let s = "" -[s] |> List.map _.{caret} +[s] |> List.map _.{caret} """ assertHasItemWithNames ["Length"] info From 1c7c20dfd3293132aebc5b73e6fd2e8c7422288e Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 17:05:57 +0300 Subject: [PATCH 07/15] wip --- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 6633dab2408..27c4f182900 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -103,6 +103,8 @@ let rec pushUnaryArg expr arg = SynExpr.TypeApp(innerExpr, mLess, tyargs, mCommas, mGreater, mTypars, m) | SynExpr.ArbitraryAfterError(_, m) when m.Start = m.End -> SynExpr.DiscardAfterMissingQualificationAfterDot(SynExpr.Ident arg, m.StartRange, unionRanges arg.idRange m) + | SynExpr.DiscardAfterMissingQualificationAfterDot(synExpr, _, _) -> + pushUnaryArg synExpr arg | _ -> errorR (Error(FSComp.SR.tcDotLambdaAtNotSupportedExpression (), expr.Range)) expr From 0588503f28ab1e190e5c9acec951ebb4d953a655 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 17:15:24 +0300 Subject: [PATCH 08/15] test --- .../Language/DotLambdaTests.fs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index ab135a31be0..c8a34da06df 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -105,6 +105,17 @@ let myFunction (x:MyRecord) = x |> _.DoStuff 1 2 3""" Error 72, Line 4, Col 36, Line 4, Col 45, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved." ] +[] +let ``Underscore Dot Lambda - Missing qualification after dot`` () = + Fsx """ +"" |> _.Length. """ + |> withLangVersion80 + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 599, Line 2, Col 15, Line 2, Col 16, "Missing qualification after '.'" + ] + [] let ``Underscore Dot Length on string`` () = Fsx """ From d9d7fa0f9a9c2ecc0c13b99779bb94051e360bc9 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 17:40:46 +0300 Subject: [PATCH 09/15] wip --- docs/release-notes/.FSharp.Compiler.Service/10.0.100.md | 2 ++ src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 docs/release-notes/.FSharp.Compiler.Service/10.0.100.md diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md new file mode 100644 index 00000000000..2a66e373e42 --- /dev/null +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -0,0 +1,2 @@ +### Fixed +* Shorthand lambda: fix completion for chained calls and analysis for unfinished expression ([PR #18560](https://github.com/dotnet/fsharp/pull/18560)) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 27c4f182900..3a076cfd48e 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -103,8 +103,7 @@ let rec pushUnaryArg expr arg = SynExpr.TypeApp(innerExpr, mLess, tyargs, mCommas, mGreater, mTypars, m) | SynExpr.ArbitraryAfterError(_, m) when m.Start = m.End -> SynExpr.DiscardAfterMissingQualificationAfterDot(SynExpr.Ident arg, m.StartRange, unionRanges arg.idRange m) - | SynExpr.DiscardAfterMissingQualificationAfterDot(synExpr, _, _) -> - pushUnaryArg synExpr arg + | SynExpr.DiscardAfterMissingQualificationAfterDot(synExpr, _, _) -> pushUnaryArg synExpr arg | _ -> errorR (Error(FSComp.SR.tcDotLambdaAtNotSupportedExpression (), expr.Range)) expr From a8d1c70a86d9c7f9f7538a05e597ac2c5eae2b18 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 17:50:37 +0300 Subject: [PATCH 10/15] wip --- .../CompletionTests.fs | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index b90a3e4b899..9a9a8bf472f 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -87,61 +87,47 @@ let ``Underscore dot lambda - completion 01`` () = [] let ``Underscore dot lambda - completion 02`` () = let info = getCompletionInfo """ -"" |> _.Length.{caret}""" - - assertHasItemWithNames ["TryFormat"] info - -[] -let ``Underscore dot lambda - completion 03`` () = - let info = getCompletionInfo """ -"" |> _.Length.ToString().{caret}""" - - assertHasItemWithNames ["Length"] info - -[] -let ``Underscore dot lambda - completion 04`` () = - let info = getCompletionInfo """ "" |> _.Length.TryF{caret}""" assertHasItemWithNames ["TryFormat"] info [] -let ``Underscore dot lambda - completion 05`` () = +let ``Underscore dot lambda - completion 03`` () = let info = getCompletionInfo """ "" |> _.ToString().Len{caret}""" assertHasItemWithNames ["Length"] info [] -let ``Underscore dot lambda - completion 06`` () = +let ``Underscore dot lambda - completion 04`` () = let info = getCompletionInfo """ "" |> _.Len{caret}gth.ToString()""" assertHasItemWithNames ["Length"] info [] -let ``Underscore dot lambda - completion 07`` () = +let ``Underscore dot lambda - completion 05`` () = let info = getCompletionInfo """ "" |> _.Length.ToString().Chars("".Len{caret})""" assertHasItemWithNames ["Length"] info [] -let ``Underscore dot lambda - completion 08`` () = +let ``Underscore dot lambda - completion 06`` () = let info = getCompletionInfo """ "" |> _.Chars(System.DateTime.UtcNow.Tic{caret}).ToString()""" assertHasItemWithNames ["Ticks"] info [] -let ``Underscore dot lambda - completion 09`` () = +let ``Underscore dot lambda - completion 07`` () = let info = getCompletionInfo """ "" |> _.Length.ToString().Len{caret}""" assertHasItemWithNames ["Length"] info [] -let ``Underscore dot lambda - completion 10`` () = +let ``Underscore dot lambda - completion 08`` () = let info = getCompletionInfo """ "" |> _.Length .TryF{caret}""" @@ -149,21 +135,21 @@ let ``Underscore dot lambda - completion 10`` () = assertHasItemWithNames ["TryFormat"] info [] -let ``Underscore dot lambda - completion 11`` () = +let ``Underscore dot lambda - completion 09`` () = let info = getCompletionInfo """ "" |> _.Length.ToSt{caret}.Length""" assertHasItemWithNames ["ToString"] info [] -let ``Underscore dot lambda - completion 12`` () = +let ``Underscore dot lambda - completion 10`` () = let info = getCompletionInfo """ "" |> _.Chars(0).ToStr{caret}.Length""" assertHasItemWithNames ["ToString"] info [] -let ``Underscore dot lambda - completion 13`` () = +let ``Underscore dot lambda - completion 11`` () = let info = getCompletionInfo """ open System.Linq @@ -172,7 +158,7 @@ open System.Linq assertHasItemWithNames ["ToLower"] info [] -let ``Underscore dot lambda - completion 14`` () = +let ``Underscore dot lambda - completion 12`` () = let info = getCompletionInfo """ open System.Linq @@ -181,7 +167,7 @@ open System.Linq assertHasItemWithNames ["ToLower"] info [] -let ``Underscore dot lambda - completion 15`` () = +let ``Underscore dot lambda - completion 13`` () = let info = getCompletionInfo """ let myFancyFunc (x:string) = x @@ -189,7 +175,7 @@ let myFancyFunc (x:string) = assertHasItemWithNames ["ToLower"] info [] -let ``Underscore dot lambda - completion 16`` () = +let ``Underscore dot lambda - completion 14`` () = let info = getCompletionInfo """ let myFancyFunc (x:string) = x @@ -198,13 +184,27 @@ let myFancyFunc (x:string) = assertHasItemWithNames ["TryFormat"] info [] -let ``Underscore dot lambda - No prefix`` () = +let ``Underscore dot lambda - No prefix 01`` () = let info = getCompletionInfo """ let s = "" [s] |> List.map _.{caret} """ assertHasItemWithNames ["Length"] info +[] +let ``Underscore dot lambda - No prefix 02`` () = + let info = getCompletionInfo """ +"" |> _.Length.{caret}""" + + assertHasItemWithNames ["TryFormat"] info + +[] +let ``Underscore dot lambda - No prefix 03`` () = + let info = getCompletionInfo """ +"" |> _.Length.ToString().{caret}""" + + assertHasItemWithNames ["Length"] info + [] let ``Type decl - Record - Field type 01`` () = let info = getCompletionInfo """ From 23ad088ef1374bb220e8a45f253f2b41f6a0fdde Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 18:08:32 +0300 Subject: [PATCH 11/15] merge fix --- docs/release-notes/.FSharp.Compiler.Service/10.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index cb45cd6fbf4..4273af66f62 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -1,3 +1,4 @@ ### Fixed + * Allow `let!` and `use!` type annotations without requiring parentheses ([PR #18508](https://github.com/dotnet/fsharp/pull/18508)) * Shorthand lambda: fix completion for chained calls and analysis for unfinished expression ([PR #18560](https://github.com/dotnet/fsharp/pull/18560)) From 6f45e364072d584ef1d033858662675d30d9e761 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 18:22:21 +0300 Subject: [PATCH 12/15] + test --- tests/FSharp.Compiler.Service.Tests/CompletionTests.fs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index 9a9a8bf472f..32de8f64182 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -183,6 +183,13 @@ let myFancyFunc (x:string) = |> id""" assertHasItemWithNames ["TryFormat"] info +[] +let ``Underscore dot lambda - completion 15`` () = + let info = getCompletionInfo """ +let _a = 5 +"" |> _{caret}.Length.ToString() """ + assertHasItemWithNames ["_a"] info + [] let ``Underscore dot lambda - No prefix 01`` () = let info = getCompletionInfo """ From 2936d4dc90dfca5d459d3122f38cc22a769b1596 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 19:17:03 +0300 Subject: [PATCH 13/15] ilverify --- .../ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl | 2 +- .../ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index e81c636f402..4f5daf0954d 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -34,7 +34,7 @@ [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+dataTipOfReferences@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000084][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x00000059][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1&)][offset 0x000000DA][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1424-6::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000605][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1431-6::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000605][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-509::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index b53d7c7ecc6..e1bc01e19b7 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -33,7 +33,7 @@ [IL]: Error [StackUnexpected]: : .$FSharpCheckerResults+GetReferenceResolutionStructuredToolTipText@2225::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000076][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseMemberFunctionAndValues@176::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Symbols.FSharpMemberOrFunctionOrValue)][offset 0x0000002B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.AssemblyContent+traverseEntity@218::GenerateNext([S.P.CoreLib]System.Collections.Generic.IEnumerable`1&)][offset 0x000000BB][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1424-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000620][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.EditorServices.ParsedInput+visitor@1431-11::VisitExpr([FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, [FSharp.Compiler.Service]FSharp.Compiler.Syntax.SynExpr)][offset 0x00000620][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000032][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000003B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@922-530::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. From 6f8faffc4e30f4aa4d67310d8388033852a4d4db Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Fri, 16 May 2025 20:40:54 +0300 Subject: [PATCH 14/15] fix --- .../CompletionTests.fs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs index 32de8f64182..cfe43453d74 100644 --- a/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/CompletionTests.fs @@ -87,9 +87,9 @@ let ``Underscore dot lambda - completion 01`` () = [] let ``Underscore dot lambda - completion 02`` () = let info = getCompletionInfo """ -"" |> _.Length.TryF{caret}""" +System.DateTime.Now |> _.TimeOfDay.Mill{caret}""" - assertHasItemWithNames ["TryFormat"] info + assertHasItemWithNames ["Milliseconds"] info [] let ``Underscore dot lambda - completion 03`` () = @@ -129,10 +129,10 @@ let ``Underscore dot lambda - completion 07`` () = [] let ``Underscore dot lambda - completion 08`` () = let info = getCompletionInfo """ -"" |> _.Length - .TryF{caret}""" +System.DateTime.Now |> _.TimeOfDay + .Mill{caret}""" - assertHasItemWithNames ["TryFormat"] info + assertHasItemWithNames ["Milliseconds"] info [] let ``Underscore dot lambda - completion 09`` () = @@ -177,11 +177,11 @@ let myFancyFunc (x:string) = [] let ``Underscore dot lambda - completion 14`` () = let info = getCompletionInfo """ -let myFancyFunc (x:string) = +let myFancyFunc (x:System.DateTime) = x - |> _.Length.TryF{caret} + |> _.TimeOfDay.Mill{caret} |> id""" - assertHasItemWithNames ["TryFormat"] info + assertHasItemWithNames ["Milliseconds"] info [] let ``Underscore dot lambda - completion 15`` () = @@ -201,9 +201,9 @@ let s = "" [] let ``Underscore dot lambda - No prefix 02`` () = let info = getCompletionInfo """ -"" |> _.Length.{caret}""" +System.DateTime.Now |> _.TimeOfDay.{caret}""" - assertHasItemWithNames ["TryFormat"] info + assertHasItemWithNames ["Milliseconds"] info [] let ``Underscore dot lambda - No prefix 03`` () = From 0fd489d38482fe0d3d012fd72c2b2fcf61c89813 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Sat, 17 May 2025 01:24:05 +0300 Subject: [PATCH 15/15] nit it is better to return the same DiscardAfterMissingQualificationAfterDot instead of nested expression, just for consistency --- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 3a076cfd48e..616191c9b5a 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -103,7 +103,8 @@ let rec pushUnaryArg expr arg = SynExpr.TypeApp(innerExpr, mLess, tyargs, mCommas, mGreater, mTypars, m) | SynExpr.ArbitraryAfterError(_, m) when m.Start = m.End -> SynExpr.DiscardAfterMissingQualificationAfterDot(SynExpr.Ident arg, m.StartRange, unionRanges arg.idRange m) - | SynExpr.DiscardAfterMissingQualificationAfterDot(synExpr, _, _) -> pushUnaryArg synExpr arg + | SynExpr.DiscardAfterMissingQualificationAfterDot(synExpr, dotRange, m) -> + SynExpr.DiscardAfterMissingQualificationAfterDot(pushUnaryArg synExpr arg, dotRange, unionRanges arg.idRange m) | _ -> errorR (Error(FSComp.SR.tcDotLambdaAtNotSupportedExpression (), expr.Range)) expr