未验证 提交 0dabe8da 编写于 作者: B Brett V. Forsgren 提交者: GitHub

enable symbol completion for scripting (#7893)

上级 e52675ac
......@@ -4,6 +4,7 @@ namespace FSharp.Compiler.Scripting
open System
open System.Threading
open FSharp.Compiler
open FSharp.Compiler.Interactive.Shell
type FSharpScript(?captureInput: bool, ?captureOutput: bool, ?additionalArgs: string[]) as this =
......@@ -50,6 +51,23 @@ type FSharpScript(?captureInput: bool, ?captureOutput: bool, ?additionalArgs: st
| Choice1Of2 v -> Ok(v), errors
| Choice2Of2 ex -> Error(ex), errors
/// Get the available completion symbols from the code at the specified location.
///
/// <param name="text">The input text on which completions will be calculated</param>
/// <param name="line">The 1-based line index</param>
/// <param name="column">The 0-based column index</param>
member __.GetCompletionSymbols(text: string, line: int, column: int) =
async {
let! parseResults, checkResults, _projectResults = fsi.ParseAndCheckInteraction(text)
let lineText = text.Split('\n').[line - 1]
let partialName = QuickParse.GetPartialLongNameEx(lineText, column - 1)
let! symbolUses = checkResults.GetDeclarationListSymbols(Some parseResults, line, lineText, partialName)
let symbols = symbolUses
|> List.concat
|> List.map (fun s -> s.Symbol)
return symbols
}
interface IDisposable with
member __.Dispose() =
if captureInput then
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Scripting.UnitTests
open System
open System.Threading.Tasks
open FSharp.Compiler.Scripting
open NUnit.Framework
[<TestFixture>]
type CompletionTests() =
[<Test>]
member _.``Instance completions in the same submission``() =
async {
use script = new FSharpScript()
let lines = [ "let x = 1"
"x." ]
let! completions = script.GetCompletionSymbols(String.Join("\n", lines), 2, 2)
let matchingCompletions = completions |> List.filter (fun s -> s.DisplayName = "CompareTo")
Assert.AreEqual(1, List.length matchingCompletions)
} |> Async.StartAsTask :> Task
[<Test>]
member _.``Instance completions from a previous submission``() =
async {
use script = new FSharpScript()
script.Eval("let x = 1") |> ignoreValue
let! completions = script.GetCompletionSymbols("x.", 1, 2)
let matchingCompletions = completions |> List.filter (fun s -> s.DisplayName = "CompareTo")
Assert.AreEqual(1, List.length matchingCompletions)
} |> Async.StartAsTask :> Task
[<Test>]
member _.``Static member completions``() =
async {
use script = new FSharpScript()
let! completions = script.GetCompletionSymbols("System.String.", 1, 14)
let matchingCompletions = completions |> List.filter (fun s -> s.DisplayName = "Join")
Assert.GreaterOrEqual(List.length matchingCompletions, 1)
} |> Async.StartAsTask :> Task
[<Test>]
member _.``Type completions from namespace``() =
async {
use script = new FSharpScript()
let! completions = script.GetCompletionSymbols("System.", 1, 7)
let matchingCompletions = completions |> List.filter (fun s -> s.DisplayName = "String")
Assert.GreaterOrEqual(List.length matchingCompletions, 1)
} |> Async.StartAsTask :> Task
[<Test>]
member _.``Namespace completions``() =
async {
use script = new FSharpScript()
let! completions = script.GetCompletionSymbols("System.", 1, 7)
let matchingCompletions = completions |> List.filter (fun s -> s.DisplayName = "Collections")
Assert.AreEqual(1, List.length matchingCompletions)
} |> Async.StartAsTask :> Task
[<Test>]
member _.``Extension method completions``() =
async {
use script = new FSharpScript()
let lines = [ "open System.Linq"
"let list = new System.Collections.Generic.List<int>()"
"list." ]
let! completions = script.GetCompletionSymbols(String.Join("\n", lines), 3, 5)
let matchingCompletions = completions |> List.filter (fun s -> s.DisplayName = "Select")
Assert.AreEqual(1, List.length matchingCompletions)
} |> Async.StartAsTask :> Task
......@@ -11,7 +11,9 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="TestHelpers.fs" />
<Compile Include="FSharpScriptTests.fs" />
<Compile Include="CompletionTests.fs" />
</ItemGroup>
<ItemGroup>
......
......@@ -9,21 +9,11 @@ open System.Threading
open System.Threading.Tasks
open FSharp.Compiler.Interactive.Shell
open FSharp.Compiler.Scripting
open FSharp.Compiler.SourceCodeServices
open NUnit.Framework
[<TestFixture>]
type InteractiveTests() =
let getValue ((value: Result<FsiValue option, exn>), (errors: FSharpErrorInfo[])) =
if errors.Length > 0 then
failwith <| sprintf "Evaluation returned %d errors:\r\n\t%s" errors.Length (String.Join("\r\n\t", errors))
match value with
| Ok(value) -> value
| Error ex -> raise ex
let ignoreValue = getValue >> ignore
[<Test>]
member __.``Eval object value``() =
use script = new FSharpScript()
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace FSharp.Compiler.Scripting.UnitTests
open System
open FSharp.Compiler.Interactive.Shell
open FSharp.Compiler.SourceCodeServices
[<AutoOpen>]
module TestHelpers =
let getValue ((value: Result<FsiValue option, exn>), (errors: FSharpErrorInfo[])) =
if errors.Length > 0 then
failwith <| sprintf "Evaluation returned %d errors:\r\n\t%s" errors.Length (String.Join("\r\n\t", errors))
match value with
| Ok(value) -> value
| Error ex -> raise ex
let ignoreValue = getValue >> ignore
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册