Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 4 additions & 1 deletion src/Compiler/Service/ItemKey.fs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,10 @@ and [<Sealed>] ItemKeyStoreBuilder() =
match stripTyparEqns ty with
| TType_forall (_, ty) -> writeType false ty

| TType_app (tcref, _, _) -> writeEntityRef tcref
| TType_app (tcref, _, _) ->
match tcref.TypeAbbrev with
| Some ty -> writeType isStandalone ty
| None -> writeEntityRef tcref

| TType_tuple (_, tinst) ->
writeString ItemKeyTags.typeTuple
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,26 @@ let foo x = 5""" })
"FileSecond.fs", 8, 2, 4
"FileThird.fs", 8, 2, 13
])
}
}

[<Fact>]
let ``We find a type that has been aliased`` () =

let project = SyntheticProject.Create("TypeAliasTest",
{ sourceFile "First" [] with
ExtraSource = "type MyInt = int32\n" +
"let myNum = 7"
SignatureFile = Custom ("module TypeAliasTest.ModuleFirst\n" +
"type MyInt = int32\n" +
"val myNum: MyInt") },
{ sourceFile "Second" [] with
ExtraSource = "let goo x = ModuleFirst.myNum + x"})

project.Workflow {
placeCursor "First" "myNum"
findAllReferences (expectToFind [
"FileFirst.fs", 7, 4, 9
"FileFirst.fsi", 3, 4, 9
"FileSecond.fs", 6, 12, 29
])
}
31 changes: 29 additions & 2 deletions tests/FSharp.Test.Utilities/ProjectGeneration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,33 @@ type ProjectWorkflowBuilder
return { ctx with Cursor = su }
}

/// Find a symbol by finding the first occurrence of the symbol name in the file
[<CustomOperation "placeCursor">]
member this.PlaceCursor(workflow: Async<WorkflowContext>, fileId, symbolName: string) =
async {
let! ctx = workflow

let source = renderSourceFile ctx.Project (ctx.Project.Find fileId)
let index = source.IndexOf symbolName
let line = source |> Seq.take index |> Seq.where ((=) '\n') |> Seq.length
let fullLine = source.Split '\n' |> Array.item line
let colAtEndOfNames = fullLine.IndexOf symbolName + symbolName.Length

let! results = checkFile fileId ctx.Project checker
let typeCheckResults = getTypeCheckResult results

let su =
typeCheckResults.GetSymbolUseAtLocation(line + 1, colAtEndOfNames, fullLine, [symbolName])

if su.IsNone then
let file = ctx.Project.Find fileId

failwith
$"No symbol found in {file.FileName} at {line}:{colAtEndOfNames}\nFile contents:\n\n{source}\n"

return { ctx with Cursor = su }
}

/// Find all references within a single file, results are provided to the 'processResults' function
[<CustomOperation "findAllReferencesInFile">]
member this.FindAllReferencesInFile(workflow: Async<WorkflowContext>, fileId: string, processResults) =
Expand All @@ -606,7 +633,7 @@ type ProjectWorkflowBuilder
let symbolUse =
ctx.Cursor
|> Option.defaultWith (fun () ->
failwith $"Please place cursor at a valid location via {nameof this.PlaceCursor} first")
failwith $"Please place cursor at a valid location via placeCursor first")

let file = ctx.Project.Find fileId
let absFileName = ctx.Project.ProjectDir ++ file.FileName
Expand All @@ -629,7 +656,7 @@ type ProjectWorkflowBuilder
let symbolUse =
ctx.Cursor
|> Option.defaultWith (fun () ->
failwith $"Please place cursor at a valid location via {nameof this.PlaceCursor} first")
failwith $"Please place cursor at a valid location via placeCursor first")

let! results =
[ for f in options.SourceFiles do
Expand Down