Skip to content

Commit af9345b

Browse files
authored
Fix finding references to active pattern cases (#14966) (#14973)
* active pattern find references - only search for the one provided, not all . And works also for .fsi files.
1 parent cc6558e commit af9345b

File tree

2 files changed

+133
-6
lines changed

2 files changed

+133
-6
lines changed

src/Compiler/Service/ItemKey.fs

+16-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ open FSharp.Compiler.Text
1515
open FSharp.Compiler.Text.Range
1616
open FSharp.Compiler.TypedTree
1717
open FSharp.Compiler.TypedTreeBasics
18+
open FSharp.Compiler.Syntax.PrettyNaming
1819

1920
#nowarn "9"
2021
#nowarn "51"
@@ -301,6 +302,19 @@ and [<Sealed>] ItemKeyStoreBuilder() =
301302
| ParentNone -> writeChar '%'
302303
| Parent eref -> writeEntityRef eref
303304

305+
let writeActivePatternCase (apInfo: ActivePatternInfo) index =
306+
writeString ItemKeyTags.itemActivePattern
307+
308+
match apInfo.ActiveTagsWithRanges with
309+
| (_, m) :: _ -> m.FileName |> Path.GetFileNameWithoutExtension |> writeString
310+
| _ -> ()
311+
312+
for tag in apInfo.ActiveTags do
313+
writeChar '|'
314+
writeString tag
315+
316+
writeInt32 index
317+
304318
member _.Write(m: range, item: Item) =
305319
writeRange m
306320

@@ -325,13 +339,9 @@ and [<Sealed>] ItemKeyStoreBuilder() =
325339
writeEntityRef info.TyconRef
326340
writeString info.LogicalName
327341

328-
| Item.ActivePatternResult (info, _, _, _) ->
329-
writeString ItemKeyTags.itemActivePattern
330-
info.ActiveTags |> List.iter writeString
342+
| Item.ActivePatternResult (info, _, index, _) -> writeActivePatternCase info index
331343

332-
| Item.ActivePatternCase elemRef ->
333-
writeString ItemKeyTags.itemActivePattern
334-
elemRef.ActivePatternInfo.ActiveTags |> List.iter writeString
344+
| Item.ActivePatternCase elemRef -> writeActivePatternCase elemRef.ActivePatternInfo elemRef.CaseIndex
335345

336346
| Item.ExnCase tcref ->
337347
writeString ItemKeyTags.itemExnCase

tests/FSharp.Compiler.ComponentTests/FSharpChecker/FindReferences.fs

+117
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,120 @@ let x = MyType()
301301
"FileProgram.fs", 6, 8, 14
302302
])
303303
}
304+
305+
306+
module ActivePatterns =
307+
308+
/// https://github.com/dotnet/fsharp/issues/14206
309+
[<Fact>]
310+
let ``Finding references to an active pattern case shouldn't find other cases`` () =
311+
let source = """
312+
let (|Even|Odd|) v =
313+
if v % 2 = 0 then Even else Odd
314+
match 2 with
315+
| Even -> ()
316+
| Odd -> ()
317+
"""
318+
let fileName, options, checker = singleFileChecker source
319+
320+
let symbolUse = getSymbolUse fileName source "Even" options checker |> Async.RunSynchronously
321+
322+
checker.FindBackgroundReferencesInFile(fileName, options, symbolUse.Symbol, fastCheck = true)
323+
|> Async.RunSynchronously
324+
|> expectToFind [
325+
fileName, 2, 6, 10
326+
fileName, 3, 22, 26
327+
fileName, 5, 2, 6
328+
]
329+
330+
[<Fact>]
331+
let ``We don't find references to cases from other active patterns with the same name`` () =
332+
333+
let source = """
334+
module One =
335+
336+
let (|Even|Odd|) v =
337+
if v % 2 = 0 then Even else Odd
338+
match 2 with
339+
| Even -> ()
340+
| Odd -> ()
341+
342+
module Two =
343+
344+
let (|Even|Steven|) v =
345+
if v % 3 = 0 then Steven else Even
346+
match 2 with
347+
| Even -> ()
348+
| Steven -> ()
349+
"""
350+
351+
let fileName, options, checker = singleFileChecker source
352+
353+
let symbolUse = getSymbolUse fileName source "Even" options checker |> Async.RunSynchronously
354+
355+
checker.FindBackgroundReferencesInFile(fileName, options, symbolUse.Symbol, fastCheck = true)
356+
|> Async.RunSynchronously
357+
|> expectToFind [
358+
fileName, 4, 10, 14
359+
fileName, 5, 26, 30
360+
fileName, 7, 6, 10
361+
]
362+
363+
[<Fact>]
364+
let ``We don't find references to cases the same active pattern defined in a different file`` () =
365+
366+
let source = """
367+
let (|Even|Odd|) v =
368+
if v % 2 = 0 then Even else Odd
369+
match 2 with
370+
| Even -> ()
371+
| Odd -> ()
372+
"""
373+
SyntheticProject.Create(
374+
{ sourceFile "First" [] with Source = source },
375+
{ sourceFile "Second" [] with Source = source }
376+
).Workflow {
377+
placeCursor "First" "Even"
378+
findAllReferences (expectToFind [
379+
"FileFirst.fs", 3, 6, 10
380+
"FileFirst.fs", 4, 22, 26
381+
"FileFirst.fs", 6, 2, 6
382+
])
383+
}
384+
385+
[<Fact>]
386+
let ``We find active patterns in other files when there are signature files`` () =
387+
388+
SyntheticProject.Create(
389+
{ sourceFile "First" [] with
390+
Source = "let (|Even|Odd|) v = if v % 2 = 0 then Even else Odd"
391+
SignatureFile = AutoGenerated },
392+
{ sourceFile "Second" [] with
393+
Source = """
394+
open ModuleFirst
395+
match 2 with | Even -> () | Odd -> ()
396+
""" }
397+
).Workflow {
398+
placeCursor "Second" "Even"
399+
findAllReferences (expectToFind [
400+
"FileFirst.fs", 2, 6, 10
401+
"FileFirst.fs", 2, 39, 43
402+
"FileSecond.fs", 4, 15, 19
403+
])
404+
}
405+
406+
/// Bug: https://github.com/dotnet/fsharp/issues/14969
407+
[<Fact>]
408+
let ``We DON'T find active patterns in signature files`` () =
409+
SyntheticProject.Create(
410+
{ sourceFile "First" [] with
411+
Source = "let (|Even|Odd|) v = if v % 2 = 0 then Even else Odd"
412+
SignatureFile = AutoGenerated }
413+
).Workflow {
414+
placeCursor "First" "Even"
415+
findAllReferences (expectToFind [
416+
"FileFirst.fs", 2, 6, 10
417+
"FileFirst.fs", 2, 39, 43
418+
//"FileFirst.fsi", 4, 6, 10 <-- this should also be found
419+
])
420+
}

0 commit comments

Comments
 (0)