-
Notifications
You must be signed in to change notification settings - Fork 367
/
FSharpScriptHelpers.fs
75 lines (61 loc) · 2.87 KB
/
FSharpScriptHelpers.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace Microsoft.DotNet.Interactive.FSharp.ScriptHelpers
open System
open System.Collections.Generic
open System.IO
open System.Text
open System.Threading
open FSharp.Compiler
open FSharp.Compiler.Interactive.Shell
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.EditorServices
[<RequireQualifiedAccess>]
type LangVersion =
| V47
| V50
| Preview
type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVersion) =
let additionalArgs = defaultArg additionalArgs [||]
let quiet = defaultArg quiet true
let langVersion = defaultArg langVersion LangVersion.Preview
let config = FsiEvaluationSession.GetDefaultConfiguration()
let computedProfile =
// If we are being executed on the desktop framework (we can tell because the assembly containing int is mscorlib) then profile must be mscorlib otherwise use netcore
if typeof<int>.Assembly.GetName().Name = "mscorlib" then "mscorlib"
else "netcore"
let baseArgs = [|
typeof<FSharpScript>.Assembly.Location;
"--noninteractive";
"--targetprofile:" + computedProfile
if quiet then "--quiet"
match langVersion with
| LangVersion.V47 -> "--langversion:4.7"
| LangVersion.V50 -> "--langversion:5.0"
| LangVersion.Preview -> "--langversion:preview"
|]
let argv = Array.append baseArgs additionalArgs
let fsi = FsiEvaluationSession.Create (config, argv, stdin, stdout, stderr)
member _.ValueBound = fsi.ValueBound
member _.Fsi = fsi
member _.Eval(code: string, ?cancellationToken: CancellationToken) =
let cancellationToken = defaultArg cancellationToken CancellationToken.None
let ch, errors = fsi.EvalInteractionNonThrowing(code, cancellationToken)
match ch with
| Choice1Of2 v -> Ok(v), errors
| Choice2Of2 ex -> Error(ex), errors
/// Get the available completion items 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 _.GetCompletionItems(text: string, line: int, column: int) =
task {
let parseResults, checkResults, _projectResults = fsi.ParseAndCheckInteraction(text)
let lineText = text.Split('\n').[line - 1]
let partialName = QuickParse.GetPartialLongNameEx(lineText, column - 1)
let declarationListInfos = checkResults.GetDeclarationListInfo(Some parseResults, line, lineText, partialName)
return declarationListInfos.Items
}
interface IDisposable with
member _.Dispose() =
(fsi :> IDisposable).Dispose()