This tutorial demonstrates how to host the F# compiler.
NOTE: The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published
NOTE: There are several options for hosting the F# compiler. The easiest one is to use the
fsc.exe
process and pass arguments.
NOTE: By default compilations using FSharp.Compiler.Service reference FSharp.Core 4.3.0.0 (matching F# 3.0). You can override
this choice by passing a reference to FSharp.Core for 4.3.1.0 or later explicitly in your command-line arguments.
First, we need to reference the libraries that contain F# interactive service:
#r "FSharp.Compiler.Service.dll"
open System.IO
open FSharp.Compiler.CodeAnalysis
// Create an interactive checker instance
let checker = FSharpChecker.Create()
Now write content to a temporary file:
let fn = Path.GetTempFileName()
let fn2 = Path.ChangeExtension(fn, ".fsx")
let fn3 = Path.ChangeExtension(fn, ".dll")
File.WriteAllText(fn2, """
module M
type C() =
member x.P = 1
let x = 3 + 4
""")
Now invoke the compiler:
let errors1, exitCode1 =
checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
|> Async.RunSynchronously
If errors occur you can see this in the 'exitCode' and the returned array of errors:
File.WriteAllText(fn2, """
module M
let x = 1.0 + "" // a type error
""")
let errors1b, exitCode1b =
checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
|> Async.RunSynchronously
You can also compile to a dynamic assembly, which uses the F# Interactive code generator.
This can be useful if you are, for example, in a situation where writing to the file system
is not really an option.
You still have to pass the "-o" option to name the output file, but the output file is not actually written to disk.
The 'None' option indicates that the initialization code for the assembly is not executed.
let errors2, exitCode2, dynAssembly2 =
checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None)
|> Async.RunSynchronously
(*
Passing 'Some' for the 'execute' parameter executes the initialization code for the assembly.
*)
let errors3, exitCode3, dynAssembly3 =
checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr))
|> Async.RunSynchronously
namespace System
namespace System.IO
Multiple items
namespace FSharp
--------------------
namespace Microsoft.FSharp
namespace FSharp.Compiler
namespace FSharp.Compiler.CodeAnalysis
val checker : FSharpChecker
type FSharpChecker =
member CheckFileInProject : parseResults:FSharpParseFileResults * fileName:string * fileVersion:int * sourceText:ISourceText * options:FSharpProjectOptions * ?userOpName:string -> Async<FSharpCheckFileAnswer>
member ClearCache : options:seq<FSharpProjectOptions> * ?userOpName:string -> unit
member ClearLanguageServiceRootCachesAndCollectAndFinalizeAllTransients : unit -> unit
member Compile : argv:string [] * ?userOpName:string -> Async<FSharpDiagnostic [] * int> + 1 overload
member CompileToDynamicAssembly : otherFlags:string [] * execute:(TextWriter * TextWriter) option * ?userOpName:string -> Async<FSharpDiagnostic [] * int * Assembly option> + 1 overload
member FindBackgroundReferencesInFile : fileName:string * options:FSharpProjectOptions * symbol:FSharpSymbol * ?canInvalidateProject:bool * ?userOpName:string -> Async<seq<range>>
member GetBackgroundCheckResultsForFileInProject : fileName:string * options:FSharpProjectOptions * ?userOpName:string -> Async<FSharpParseFileResults * FSharpCheckFileResults>
member GetBackgroundParseResultsForFileInProject : fileName:string * options:FSharpProjectOptions * ?userOpName:string -> Async<FSharpParseFileResults>
member GetBackgroundSemanticClassificationForFile : fileName:string * options:FSharpProjectOptions * ?userOpName:string -> Async<SemanticClassificationView option>
member GetParsingOptionsFromCommandLineArgs : sourceFiles:string list * argv:string list * ?isInteractive:bool * ?isEditing:bool -> FSharpParsingOptions * FSharpDiagnostic list + 1 overload
...
<summary>
Used to parse and check F# source code.
</summary>
static member FSharpChecker.Create : ?projectCacheSize:int * ?keepAssemblyContents:bool * ?keepAllBackgroundResolutions:bool * ?legacyReferenceResolver:LegacyReferenceResolver * ?tryGetMetadataSnapshot:FSharp.Compiler.AbstractIL.ILBinaryReader.ILReaderTryGetMetadataSnapshot * ?suggestNamesForErrors:bool * ?keepAllBackgroundSymbolUses:bool * ?enableBackgroundItemKeyStoreAndSemanticClassification:bool * ?enablePartialTypeChecking:bool -> FSharpChecker
val fn : string
type Path =
static member ChangeExtension : path: string * extension: string -> string
static member Combine : path1: string * path2: string -> string + 3 overloads
static member EndsInDirectorySeparator : path: ReadOnlySpan<char> -> bool + 1 overload
static member GetDirectoryName : path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload
static member GetExtension : path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload
static member GetFileName : path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload
static member GetFileNameWithoutExtension : path: ReadOnlySpan<char> -> ReadOnlySpan<char> + 1 overload
static member GetFullPath : path: string -> string + 1 overload
static member GetInvalidFileNameChars : unit -> char []
static member GetInvalidPathChars : unit -> char []
...
<summary>Performs operations on <see cref="T:System.String" /> instances that contain file or directory path information. These operations are performed in a cross-platform manner.</summary>
Path.GetTempFileName() : string
val fn2 : string
Path.ChangeExtension(path: string, extension: string) : string
val fn3 : string
type File =
static member AppendAllLines : path: string * contents: IEnumerable<string> -> unit + 1 overload
static member AppendAllLinesAsync : path: string * contents: IEnumerable<string> * encoding: Encoding *?cancellationToken: CancellationToken -> Task + 1 overload
static member AppendAllText : path: string * contents: string -> unit + 1 overload
static member AppendAllTextAsync : path: string * contents: string * encoding: Encoding *?cancellationToken: CancellationToken -> Task + 1 overload
static member AppendText : path: string -> StreamWriter
static member Copy : sourceFileName: string * destFileName: string -> unit + 1 overload
static member Create : path: string -> FileStream + 2 overloads
static member CreateText : path: string -> StreamWriter
static member Decrypt : path: string -> unit
static member Delete : path: string -> unit
...
<summary>Provides static methods for the creation, copying, deletion, moving, and opening of a single file, and aids in the creation of <see cref="T:System.IO.FileStream" /> objects.</summary>
File.WriteAllText(path: string, contents: string) : unit
File.WriteAllText(path: string, contents: string, encoding: System.Text.Encoding) : unit
val errors1 : FSharp.Compiler.Diagnostics.FSharpDiagnostic []
val exitCode1 : int
member FSharpChecker.Compile : argv:string [] * ?userOpName:string -> Async<FSharp.Compiler.Diagnostics.FSharpDiagnostic [] * int>
member FSharpChecker.Compile : ast:FSharp.Compiler.Syntax.ParsedInput list * assemblyName:string * outFile:string * dependencies:string list * ?pdbFile:string * ?executable:bool * ?noframework:bool * ?userOpName:string -> Async<FSharp.Compiler.Diagnostics.FSharpDiagnostic [] * int>
Multiple items
type Async =
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task<'T> -> Async<'T> + 1 overload
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member Choice : computations:seq<Async<'T option>> -> Async<'T option>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T> + 3 overloads
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
...
<summary>Holds static members for creating and manipulating asynchronous computations.</summary>
<remarks>
See also <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">F# Language Guide - Async Workflows</a>.
</remarks>
<category index="1">Async Programming</category>
--------------------
type Async<'T> =
<summary>
An asynchronous computation, which, when run, will eventually produce a value of type T, or else raises an exception.
</summary>
<remarks>
This type has no members. Asynchronous computations are normally specified either by using an async expression
or the static methods in the <see cref="T:Microsoft.FSharp.Control.Async" /> type.
See also <a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">F# Language Guide - Async Workflows</a>.
</remarks>
<namespacedoc><summary>
Library functionality for asynchronous programming, events and agents. See also
<a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/asynchronous-workflows">Asynchronous Programming</a>,
<a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/members/events">Events</a> and
<a href="https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/lazy-expressions">Lazy Expressions</a> in the
F# Language Guide.
</summary></namespacedoc>
<category index="1">Async Programming</category>
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T
val errors1b : FSharp.Compiler.Diagnostics.FSharpDiagnostic []
val exitCode1b : int
val errors2 : FSharp.Compiler.Diagnostics.FSharpDiagnostic []
val exitCode2 : int
val dynAssembly2 : System.Reflection.Assembly option
member FSharpChecker.CompileToDynamicAssembly : otherFlags:string [] * execute:(TextWriter * TextWriter) option * ?userOpName:string -> Async<FSharp.Compiler.Diagnostics.FSharpDiagnostic [] * int * System.Reflection.Assembly option>
member FSharpChecker.CompileToDynamicAssembly : ast:FSharp.Compiler.Syntax.ParsedInput list * assemblyName:string * dependencies:string list * execute:(TextWriter * TextWriter) option * ?debug:bool * ?noframework:bool * ?userOpName:string -> Async<FSharp.Compiler.Diagnostics.FSharpDiagnostic [] * int * System.Reflection.Assembly option>
union case Option.None: Option<'T>
<summary>The representation of "No value"</summary>
val errors3 : FSharp.Compiler.Diagnostics.FSharpDiagnostic []
val exitCode3 : int
val dynAssembly3 : System.Reflection.Assembly option
union case Option.Some: Value: 'T -> Option<'T>
<summary>The representation of "Value of type 'T"</summary>
<param name="Value">The input value.</param>
<returns>An option representing the value.</returns>
val stdout<'T> : TextWriter
<summary>Reads the value of the property <see cref="P:System.Console.Out" />.</summary>
val stderr<'T> : TextWriter
<summary>Reads the value of the property <see cref="P:System.Console.Error" />. </summary>