Skip to content

[automated] Merge branch 'main' => 'feature/lsp' #18515

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
264a54e
Update dependencies from https://github.com/dotnet/arcade build 20250…
dotnet-maestro[bot] Apr 28, 2025
9995898
Allow `_` in `use!` bindings values (#18487)
edgarfgp Apr 28, 2025
54fb3da
Checker: don't capture environment for checked modules (#18519)
auduchinok Apr 30, 2025
cf6b53e
reuse fsi sessions in tests (#18527)
majocha Apr 30, 2025
34dbfc1
Code completion: fix getting qualifier expression in `do` statements …
auduchinok Apr 30, 2025
05500b8
Enable TypeSubsumptionCache for IDE use (#18499)
majocha May 1, 2025
172dc31
include accessibility range in `SynPat.Named` (#18526)
edgarfgp May 2, 2025
abffd37
Fix mixed emit-multi+/- sessions (#18465)
KevinRansom May 5, 2025
63dd8ca
[main] Update dependencies from dotnet/arcade (#18535)
dotnet-maestro[bot] May 6, 2025
aa4550e
Update VisualFSharp.Core.targets (#18536)
AlexDelepine May 7, 2025
5a239f6
Update dependencies from https://github.com/dotnet/arcade build 20250…
dotnet-maestro[bot] May 7, 2025
f78ce10
Keep parens around records in interpolated strings (#18534)
brianrourkeboll May 12, 2025
c4ed80c
Clean up Conformance UnitsOfMeasure (#18537)
KevinRansom May 13, 2025
66e1637
Scoped nowarn (#18049)
Martin521 May 14, 2025
230df0c
Make attribute target mismatch a warning and not an error. (#18492)
edgarfgp May 14, 2025
9e74c0e
Fix race in cache eviction (#18528)
majocha May 14, 2025
29bcaf1
Cancellable: always catch internal cancellations (#18531)
majocha May 14, 2025
c4dfbd5
Merge branch 'merge/main-to-feature/lsp' of https://github.com/dotnet…
abonie May 14, 2025
190dccd
Merge branch 'feature/lsp' into merge/main-to-feature/lsp
abonie May 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Code completion: fix getting qualifier expression in do statements …
…in type decls (#18524)
  • Loading branch information
auduchinok authored Apr 30, 2025
commit 34dbfc17eaea59e08286ccfb7d9b28b6b35269e2
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* Allow `_` in `use!` bindings values (lift FS1228 restriction) ([PR #18487](https://github.com/dotnet/fsharp/pull/18487))
* Make `[<CallerMemberName; Struct>]` combination work([PR #18444](https://github.com/dotnet/fsharp/pull/18444/))
* Fix code completion considers types from own namespace non-imported ([PR #18518](https://github.com/dotnet/fsharp/issues/18518))
* Code completion: fix getting qualifier expression in do statements in type decls ([PR #18524](https://github.com/dotnet/fsharp/pull/18524))

### Added
* Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241))
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Service/ServiceParseTreeWalk.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,8 @@ module SyntaxTraversal =
let path = SyntaxNode.SynBinding b :: origPath

match b with
| SynBinding(kind = SynBindingKind.Do; expr = expr) -> traverseSynExpr path expr

| SynBinding(headPat = synPat; expr = synExpr; attributes = attributes; range = m) ->
[
yield! attributeApplicationDives path attributes
Expand Down
10 changes: 10 additions & 0 deletions tests/FSharp.Compiler.Service.Tests/Common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,16 @@ let rec allSymbolsInEntities compGen (entities: IList<FSharpEntity>) =
yield! allSymbolsInEntities compGen entity.NestedEntities ]


let getCursorPosAndPrepareSource (source: string) : string * string * pos =
let lines = source.Split([|"\r\n"; "\n"|], StringSplitOptions.None)
let line = lines |> Seq.findIndex _.Contains("{caret}")
let lineText = lines[line]
let column = lineText.IndexOf("{caret}")

let source = source.Replace("{caret}", "")
let lineText = lineText.Replace("{caret}", "")
source, lineText, Position.mkPos (line + 1) (column - 1)

let getParseResults (source: string) =
parseSourceCode("Test.fsx", source)

Expand Down
113 changes: 79 additions & 34 deletions tests/FSharp.Compiler.Service.Tests/CompletionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ open FSharp.Compiler.Service.Tests.Common
open FSharp.Compiler.EditorServices
open Xunit

let getCompletionInfo lineText (line, column) source =
let getCompletionInfo source =
let source, lineText, pos = getCursorPosAndPrepareSource source
let parseResults, checkResults = getParseAndCheckResultsPreview source
let plid = QuickParse.GetPartialLongNameEx(lineText, column)
checkResults.GetDeclarationListInfo(Some parseResults, line, lineText, plid)
let plid = QuickParse.GetPartialLongNameEx(lineText, pos.Column)
checkResults.GetDeclarationListInfo(Some parseResults, pos.Line, lineText, plid)

let getCompletionItemNames (completionInfo: DeclarationListInfo) =
completionInfo.Items |> Array.map (fun item -> item.NameInCode)
Expand All @@ -19,92 +20,100 @@ let assertHasItemWithNames names (completionInfo: DeclarationListInfo) =
Assert.True(Set.contains name itemNames, $"{name} not found in {itemNames}")

[<Fact>]
let ``Expr - After record decl`` () =
let info = getCompletionInfo "{ Fi }" (4, 0) """
let ``Expr - After record decl 01`` () =
let info = getCompletionInfo """
type Record = { Field: int }

{ Fi{caret} }
"""
assertHasItemWithNames ["ignore"] info

[<Fact>]
let ``Expr - After record decl 02`` () =
let info = getCompletionInfo """
type Record = { Field: int }

{caret}
"""
assertHasItemWithNames ["ignore"] info

[<Fact>]
let ``Expr - record - field 01 - anon module`` () =
let info = getCompletionInfo "{ Fi }" (4, 3) """
let info = getCompletionInfo """
type Record = { Field: int }

{ Fi }
{ Fi{caret} }
"""
assertHasItemWithNames ["Field"] info

[<Fact>]
let ``Expr - record - field 02 - anon module`` () =
let info = getCompletionInfo "{ Fi }" (6, 3) """
let info = getCompletionInfo """
type Record = { Field: int }

let record = { Field = 1 }

{ Fi }
{ Fi{caret} }
"""
assertHasItemWithNames ["Field"] info

[<Fact>]
let ``Expr - record - empty 01`` () =
let info = getCompletionInfo "{ }" (4, 2) """
let info = getCompletionInfo """
type Record = { Field: int }

{ }
{ {caret} }
"""
assertHasItemWithNames ["Field"] info

[<Fact>]
let ``Expr - record - empty 02`` () =
let info = getCompletionInfo "{ }" (6, 2) """
let info = getCompletionInfo """
type Record = { Field: int }

let record = { Field = 1 }

{ }
{ {caret} }
"""
assertHasItemWithNames ["Field"; "record"] info

[<Fact>]
let ``Underscore dot lambda - completion`` () =
let info = getCompletionInfo " |> _.Len" (4, 11) """
let info = getCompletionInfo """
let myFancyFunc (x:string) =
x
|> _.Len"""
|> _.Len{caret}"""
assertHasItemWithNames ["Length"] info

[<Fact>]
let ``Underscore dot lambda - method completion`` () =
let info = getCompletionInfo " |> _.ToL" (4, 11) """
let info = getCompletionInfo """
let myFancyFunc (x:string) =
x
|> _.ToL"""
|> _.ToL{caret}"""
assertHasItemWithNames ["ToLower"] info

[<Fact>]
let ``Underscore dot lambda - No prefix`` () =
let info = getCompletionInfo "[s] |> List.map _. " (3, 18) """
let info = getCompletionInfo """
let s = ""
[s] |> List.map _.
[s] |> List.map _.{caret}
"""
assertHasItemWithNames ["Length"] info

[<Fact>]
let ``Type decl - Record - Field type 01`` () =
let info = getCompletionInfo "type Record = { Field: }" (2, 23) """
type Record = { Field: }
let info = getCompletionInfo """
type Record = { Field: {caret} }
"""
assertHasItemWithNames ["string"] info


[<Fact>]
let ``Expr - Qualifier 01`` () =
let info =
getCompletionInfo "s.Trim(). " (3, 13) """
let info = getCompletionInfo """
let f (s: string) =
s.Trim().
s.Trim().{caret}
s.Trim()
s.Trim()
()
Expand All @@ -114,10 +123,10 @@ let f (s: string) =
[<Fact>]
let ``Expr - Qualifier 02`` () =
let info =
getCompletionInfo "s.Trim(). " (4, 13) """
getCompletionInfo """
let f (s: string) =
s.Trim()
s.Trim().
s.Trim().{caret}
s.Trim()
()
"""
Expand All @@ -126,20 +135,56 @@ let f (s: string) =
[<Fact>]
let ``Expr - Qualifier 03`` () =
let info =
getCompletionInfo "s.Trim(). " (5, 13) """
getCompletionInfo """
let f (s: string) =
s.Trim()
s.Trim()
s.Trim().
s.Trim().{caret}
()
"""
assertHasItemWithNames ["Length"] info

[<Fact>]
let ``Expr - Qualifier 04`` () =
let info =
getCompletionInfo """
type T() =
do
System.String.Empty.ToString().L{caret}
"""
assertHasItemWithNames ["Length"] info

[<Fact>]
let ``Expr - Qualifier 05`` () =
let info =
getCompletionInfo """
System.String.Empty.ToString().{caret}
"""
assertHasItemWithNames ["Length"] info

[<Fact>]
let ``Expr - Qualifier 06`` () =
let info =
getCompletionInfo """
System.String.Empty.ToString().L{caret}
"""
assertHasItemWithNames ["Length"] info

[<Fact>]
let ``Expr - Qualifier 07`` () =
let info =
getCompletionInfo """
type T() =
do
System.String.Empty.ToString().L{caret}
()
"""
assertHasItemWithNames ["Length"] info

[<Fact>]
let ``Import - Ns 01`` () =
let info =
getCompletionInfo "let _: R " (14, 12) """
getCompletionInfo """
namespace Ns

type Rec1 = { F: int }
Expand All @@ -153,14 +198,14 @@ module M =

type Rec3 = { F: int }

let _: R = ()
let _: R{caret} = ()
"""
assertHasItemWithNames ["Rec1"; "Rec2"; "Rec3"] info

[<Fact>]
let ``Import - Ns 02 - Rec`` () =
let info =
getCompletionInfo "let _: R " (14, 12) """
getCompletionInfo """
namespace Ns

type Rec1 = { F: int }
Expand All @@ -174,14 +219,14 @@ module M =

type Rec3 = { F: int }

let _: R = ()
let _: R{caret} = ()
"""
assertHasItemWithNames ["Rec1"; "Rec2"; "Rec3"] info

[<Fact>]
let ``Import - Ns 03 - Rec`` () =
let info =
getCompletionInfo "let _: R " (14, 12) """
getCompletionInfo """
namespace Ns

type Rec1 = { F: int }
Expand All @@ -195,6 +240,6 @@ module rec M =

type Rec3 = { F: int }

let _: R = ()
let _: R{caret} = ()
"""
assertHasItemWithNames ["Rec1"; "Rec2"; "Rec3"] info
Loading