F# Compiler Guide


Compiler Services: Processing typed expression tree

This tutorial demonstrates how to get the checked, typed expressions tree (TAST) for F# code and how to walk over the tree.

This can be used for creating tools such as source code analyzers and refactoring tools. You can also combine the information with the API available from symbols.

NOTE: The FSharp.Compiler.Service API is subject to change when later versions of the nuget package are published

Getting checked expressions

To access the type-checked, resolved expressions, you need to create an instance of InteractiveChecker.

To use the interactive checker, reference FSharp.Compiler.Service.dll and open the relevant namespaces:

#r "FSharp.Compiler.Service.dll"
open System
open System.IO
open FSharp.Compiler.CodeAnalysis
open FSharp.Compiler.EditorServices
open FSharp.Compiler.Symbols
open FSharp.Compiler.Text

Checking code

We first parse and check some code as in the symbols tutorial. One difference is that we set keepAssemblyContents to true.

// Create an interactive checker instance 
let checker = FSharpChecker.Create(keepAssemblyContents=true)

let parseAndCheckSingleFile (input) = 
    let file = Path.ChangeExtension(System.IO.Path.GetTempFileName(), "fsx")  
    File.WriteAllText(file, input)
    // Get context representing a stand-alone (script) file
    let projOptions, _errors = 
        checker.GetProjectOptionsFromScript(file, SourceText.ofString input, assumeDotNetFramework=false)
        |> Async.RunSynchronously

    checker.ParseAndCheckProject(projOptions) 
    |> Async.RunSynchronously

Getting the expressions

After type checking a file, you can access the declarations and contents of the assembly, including expressions:

let input2 = 
      """
module MyLibrary 

open System

let foo(x, y) = 
    let msg = String.Concat("Hello", " ", "world")
    if msg.Length > 10 then 
        10 
    else 
        20

type MyClass() = 
    member x.MyMethod() = 1
      """
let checkProjectResults = 
    parseAndCheckSingleFile(input2)

checkProjectResults.Diagnostics // should be empty

Checked assemblies are made up of a series of checked implementation files. The "file" granularity matters in F# because initialization actions are triggered at the granularity of files. In this case there is only one implementation file in the project:

let checkedFile = checkProjectResults.AssemblyContents.ImplementationFiles.[0]

Checked assemblies are made up of a series of checked implementation files. The "file" granularity matters in F# because initialization actions are triggered at the granularity of files. In this case there is only one implementation file in the project:

let rec printDecl prefix d = 
    match d with 
    | FSharpImplementationFileDeclaration.Entity (e, subDecls) -> 
        printfn "%sEntity %s was declared and contains %d sub-declarations" prefix e.CompiledName subDecls.Length
        for subDecl in subDecls do 
            printDecl (prefix+"    ") subDecl
    | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) -> 
        printfn "%sMember or value %s was declared" prefix  v.CompiledName
    | FSharpImplementationFileDeclaration.InitAction(e) -> 
        printfn "%sA top-level expression was declared" prefix 


for d in checkedFile.Declarations do 
   printDecl "" d

// Entity MyLibrary was declared and contains 4 sub-declarations
//     Member or value foo was declared
//     Entity MyClass was declared and contains 0 sub-declarations
//     Member or value .ctor was declared
//     Member or value MyMethod was declared

As can be seen, the only declaration in the implementation file is that of the module MyLibrary, which contains fours sub-declarations.

As an aside, one peculiarity here is that the member declarations (e.g. the "MyMethod" member) are returned as part of the containing module entity, not as part of their class. Note that the class constructor is returned as a separate declaration. The class type definition has been "split" into a constructor and the other declarations.

let myLibraryEntity, myLibraryDecls =    
   match checkedFile.Declarations.[0] with 
   | FSharpImplementationFileDeclaration.Entity (e, subDecls) -> (e, subDecls)
   | _ -> failwith "unexpected"

What about the expressions, for example the body of function "foo"? Let's find it:

let (fooSymbol, fooArgs, fooExpression) = 
    match myLibraryDecls.[0] with 
    | FSharpImplementationFileDeclaration.MemberOrFunctionOrValue(v, vs, e) -> (v, vs, e)
    | _ -> failwith "unexpected"

Here 'fooSymbol' is a symbol associated with the declaration of 'foo', 'fooArgs' represents the formal arguments to the 'foo' function, and 'fooExpression' is an expression for the implementation of the 'foo' function.

Once you have an expression, you can work with it much like an F# quotation. For example, you can find its declaration range and its type:

fooExpression.Type  // shows that the return type of the body expression is 'int'
fooExpression.Range  // shows the declaration range of the expression implementing 'foo'

Walking over expressions

Expressions are analyzed using active patterns, much like F# quotations. Here is a generic expression visitor:

let rec visitExpr f (e:FSharpExpr) = 
    f e
    match e with 
    | FSharpExprPatterns.AddressOf(lvalueExpr) -> 
        visitExpr f lvalueExpr
    | FSharpExprPatterns.AddressSet(lvalueExpr, rvalueExpr) -> 
        visitExpr f lvalueExpr; visitExpr f rvalueExpr
    | FSharpExprPatterns.Application(funcExpr, typeArgs, argExprs) -> 
        visitExpr f funcExpr; visitExprs f argExprs
    | FSharpExprPatterns.Call(objExprOpt, memberOrFunc, typeArgs1, typeArgs2, argExprs) -> 
        visitObjArg f objExprOpt; visitExprs f argExprs
    | FSharpExprPatterns.Coerce(targetType, inpExpr) -> 
        visitExpr f inpExpr
    | FSharpExprPatterns.FastIntegerForLoop(startExpr, limitExpr, consumeExpr, isUp, _, _) -> 
        visitExpr f startExpr; visitExpr f limitExpr; visitExpr f consumeExpr
    | FSharpExprPatterns.ILAsm(asmCode, typeArgs, argExprs) -> 
        visitExprs f argExprs
    | FSharpExprPatterns.ILFieldGet (objExprOpt, fieldType, fieldName) -> 
        visitObjArg f objExprOpt
    | FSharpExprPatterns.ILFieldSet (objExprOpt, fieldType, fieldName, valueExpr) -> 
        visitObjArg f objExprOpt
    | FSharpExprPatterns.IfThenElse (guardExpr, thenExpr, elseExpr) -> 
        visitExpr f guardExpr; visitExpr f thenExpr; visitExpr f elseExpr
    | FSharpExprPatterns.Lambda(lambdaVar, bodyExpr) -> 
        visitExpr f bodyExpr
    | FSharpExprPatterns.Let((bindingVar, bindingExpr, dbg), bodyExpr) -> 
        visitExpr f bindingExpr; visitExpr f bodyExpr
    | FSharpExprPatterns.LetRec(recursiveBindings, bodyExpr) ->
        for _,bindingExpr,_ in recursiveBindings do visitExpr f bindingExpr
        visitExpr f bodyExpr
    | FSharpExprPatterns.NewArray(arrayType, argExprs) -> 
        visitExprs f argExprs
    | FSharpExprPatterns.NewDelegate(delegateType, delegateBodyExpr) -> 
        visitExpr f delegateBodyExpr
    | FSharpExprPatterns.NewObject(objType, typeArgs, argExprs) -> 
        visitExprs f argExprs
    | FSharpExprPatterns.NewRecord(recordType, argExprs) ->  
        visitExprs f argExprs
    | FSharpExprPatterns.NewAnonRecord(recordType, argExprs) ->  
        visitExprs f argExprs
    | FSharpExprPatterns.NewTuple(tupleType, argExprs) -> 
        visitExprs f argExprs
    | FSharpExprPatterns.NewUnionCase(unionType, unionCase, argExprs) -> 
        visitExprs f argExprs
    | FSharpExprPatterns.Quote(quotedExpr) -> 
        visitExpr f quotedExpr
    | FSharpExprPatterns.FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) -> 
        visitObjArg f objExprOpt
    | FSharpExprPatterns.AnonRecordGet(objExpr, recordOrClassType, fieldInfo) -> 
        visitExpr f objExpr
    | FSharpExprPatterns.FSharpFieldSet(objExprOpt, recordOrClassType, fieldInfo, argExpr) -> 
        visitObjArg f objExprOpt; visitExpr f argExpr
    | FSharpExprPatterns.Sequential(firstExpr, secondExpr) -> 
        visitExpr f firstExpr; visitExpr f secondExpr
    | FSharpExprPatterns.TryFinally(bodyExpr, finalizeExpr, dbgTry, dbgFinally) -> 
        visitExpr f bodyExpr; visitExpr f finalizeExpr
    | FSharpExprPatterns.TryWith(bodyExpr, _, _, catchVar, catchExpr, dbgTry, dbgWith) -> 
        visitExpr f bodyExpr; visitExpr f catchExpr
    | FSharpExprPatterns.TupleGet(tupleType, tupleElemIndex, tupleExpr) -> 
        visitExpr f tupleExpr
    | FSharpExprPatterns.DecisionTree(decisionExpr, decisionTargets) -> 
        visitExpr f decisionExpr; List.iter (snd >> visitExpr f) decisionTargets
    | FSharpExprPatterns.DecisionTreeSuccess (decisionTargetIdx, decisionTargetExprs) -> 
        visitExprs f decisionTargetExprs
    | FSharpExprPatterns.TypeLambda(genericParam, bodyExpr) -> 
        visitExpr f bodyExpr
    | FSharpExprPatterns.TypeTest(ty, inpExpr) -> 
        visitExpr f inpExpr
    | FSharpExprPatterns.UnionCaseSet(unionExpr, unionType, unionCase, unionCaseField, valueExpr) -> 
        visitExpr f unionExpr; visitExpr f valueExpr
    | FSharpExprPatterns.UnionCaseGet(unionExpr, unionType, unionCase, unionCaseField) -> 
        visitExpr f unionExpr
    | FSharpExprPatterns.UnionCaseTest(unionExpr, unionType, unionCase) -> 
        visitExpr f unionExpr
    | FSharpExprPatterns.UnionCaseTag(unionExpr, unionType) -> 
        visitExpr f unionExpr
    | FSharpExprPatterns.ObjectExpr(objType, baseCallExpr, overrides, interfaceImplementations) -> 
        visitExpr f baseCallExpr
        List.iter (visitObjMember f) overrides
        List.iter (snd >> List.iter (visitObjMember f)) interfaceImplementations
    | FSharpExprPatterns.TraitCall(sourceTypes, traitName, typeArgs, typeInstantiation, argTypes, argExprs) -> 
        visitExprs f argExprs
    | FSharpExprPatterns.ValueSet(valToSet, valueExpr) -> 
        visitExpr f valueExpr
    | FSharpExprPatterns.WhileLoop(guardExpr, bodyExpr, dbg) -> 
        visitExpr f guardExpr; visitExpr f bodyExpr
    | FSharpExprPatterns.BaseValue baseType -> ()
    | FSharpExprPatterns.DefaultValue defaultType -> ()
    | FSharpExprPatterns.ThisValue thisType -> ()
    | FSharpExprPatterns.Const(constValueObj, constType) -> ()
    | FSharpExprPatterns.Value(valueToGet) -> ()
    | _ -> failwith (sprintf "unrecognized %+A" e)

and visitExprs f exprs = 
    List.iter (visitExpr f) exprs

and visitObjArg f objOpt = 
    Option.iter (visitExpr f) objOpt

and visitObjMember f memb = 
    visitExpr f memb.Body

Let's use this expresssion walker:

fooExpression |> visitExpr (fun e -> printfn "Visiting %A" e)

// Prints:
//
// Visiting Let...
// Visiting Call...
// Visiting Const ("Hello", ...)
// Visiting Const (" ", ...)
// Visiting Const ("world", ...)
// Visiting IfThenElse...
// Visiting Call...
// Visiting Call...
// Visiting Value ...
// Visiting Const ...
// Visiting Const ...
// Visiting Const ...

Note that

Summary

In this tutorial, we looked at the basics of working with checked declarations and expressions.

In practice, it is also useful to combine the information here with some information you can obtain from the symbols tutorial.

namespace System
namespace System.IO
Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
namespace FSharp.Compiler
namespace FSharp.Compiler.CodeAnalysis
namespace FSharp.Compiler.EditorServices
namespace FSharp.Compiler.Symbols
Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp

--------------------
type FSharpAttribute = member Format : context:FSharpDisplayContext -> string member IsAttribute : unit -> bool member AttributeType : FSharpEntity member ConstructorArguments : IList<FSharpType * obj> member IsUnresolved : bool member NamedArguments : IList<FSharpType * string * bool * obj> member Range : range
<summary> Represents a custom attribute attached to F# source code or a compiler .NET component </summary>
namespace FSharp.Compiler.Text
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 parseAndCheckSingleFile : input:string -> FSharpCheckProjectResults
val input : string
val file : 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.ChangeExtension(path: string, extension: string) : string
Path.GetTempFileName() : 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: Text.Encoding) : unit
val projOptions : FSharpProjectOptions
val _errors : FSharp.Compiler.Diagnostics.FSharpDiagnostic list
member FSharpChecker.GetProjectOptionsFromScript : fileName:string * source:ISourceText * ?previewEnabled:bool * ?loadedTimeStamp:DateTime * ?otherFlags:string [] * ?useFsiAuxLib:bool * ?useSdkRefs:bool * ?assumeDotNetFramework:bool * ?sdkDirOverride:string * ?optionsStamp:int64 * ?userOpName:string -> Async<FSharpProjectOptions * FSharp.Compiler.Diagnostics.FSharpDiagnostic list>
module SourceText from FSharp.Compiler.Text
<summary> Functions related to ISourceText objects </summary>
val ofString : string -> ISourceText
<summary> Creates an ISourceText object from the given string </summary>
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:Threading.CancellationToken -> 'T
member FSharpChecker.ParseAndCheckProject : options:FSharpProjectOptions * ?userOpName:string -> Async<FSharpCheckProjectResults>
val input2 : string
val checkProjectResults : FSharpCheckProjectResults
property FSharpCheckProjectResults.Diagnostics: FSharp.Compiler.Diagnostics.FSharpDiagnostic [] with get
<summary> The errors returned by processing the project </summary>
val checkedFile : FSharpImplementationFileContents
property FSharpCheckProjectResults.AssemblyContents: FSharpAssemblyContents with get
<summary> Get a view of the overall contents of the assembly. Only valid to use if HasCriticalErrors is false. </summary>
property FSharpAssemblyContents.ImplementationFiles: FSharpImplementationFileContents list with get
<summary> The contents of the implementation files in the assembly </summary>
val printDecl : prefix:string -> d:FSharpImplementationFileDeclaration -> unit
val prefix : string
val d : FSharpImplementationFileDeclaration
type FSharpImplementationFileDeclaration = | Entity of entity: FSharpEntity * declarations: FSharpImplementationFileDeclaration list | MemberOrFunctionOrValue of value: FSharpMemberOrFunctionOrValue * curriedArgs: FSharpMemberOrFunctionOrValue list list * body: FSharpExpr | InitAction of action: FSharpExpr
<summary> Represents a declaration in an implementation file, as seen by the F# language </summary>
union case FSharpImplementationFileDeclaration.Entity: entity: FSharpEntity * declarations: FSharpImplementationFileDeclaration list -> FSharpImplementationFileDeclaration
<summary> Represents the declaration of a type </summary>
val e : FSharpEntity
val subDecls : FSharpImplementationFileDeclaration list
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
<summary>Print to <c>stdout</c> using the given format, and add a newline.</summary>
<param name="format">The formatter.</param>
<returns>The formatted result.</returns>
property FSharpEntity.CompiledName: string with get
<summary> Get the compiled name of the type or module, possibly with `n mangling. This is identical to LogicalName unless the CompiledName attribute is used. </summary>
property List.Length: int with get
<summary>Gets the number of items contained in the list</summary>
val subDecl : FSharpImplementationFileDeclaration
union case FSharpImplementationFileDeclaration.MemberOrFunctionOrValue: value: FSharpMemberOrFunctionOrValue * curriedArgs: FSharpMemberOrFunctionOrValue list list * body: FSharpExpr -> FSharpImplementationFileDeclaration
<summary> Represents the declaration of a member, function or value, including the parameters and body of the member </summary>
val v : FSharpMemberOrFunctionOrValue
val vs : FSharpMemberOrFunctionOrValue list list
val e : FSharpExpr
property FSharpMemberOrFunctionOrValue.CompiledName: string with get
<summary> Get the member name in compiled code </summary>
union case FSharpImplementationFileDeclaration.InitAction: action: FSharpExpr -> FSharpImplementationFileDeclaration
<summary> Represents the declaration of a static initialization action </summary>
property FSharpImplementationFileContents.Declarations: FSharpImplementationFileDeclaration list with get
<summary> Get the declarations that make up this implementation file </summary>
val myLibraryEntity : FSharpEntity
val myLibraryDecls : FSharpImplementationFileDeclaration list
val failwith : message:string -> 'T
<summary>Throw a <see cref="T:System.Exception" /> exception.</summary>
<param name="message">The exception message.</param>
<returns>The result value.</returns>
val fooSymbol : FSharpMemberOrFunctionOrValue
val fooArgs : FSharpMemberOrFunctionOrValue list list
val fooExpression : FSharpExpr
property FSharpExpr.Type: FSharpType with get
<summary> The type of the expression </summary>
property FSharpExpr.Range: range with get
<summary> The range of the expression </summary>
val visitExpr : f:(FSharpExpr -> unit) -> e:FSharpExpr -> unit
val f : (FSharpExpr -> unit)
type FSharpExpr = member ImmediateSubExpressions : FSharpExpr list member Range : range member Type : FSharpType
<summary> Represents a checked and reduced expression, as seen by the F# language. The active patterns in 'FSharp.Compiler.SourceCodeServices' can be used to analyze information about the expression. Pattern matching is reduced to decision trees and conditional tests. Some other constructs may be represented in reduced form. </summary>
module FSharpExprPatterns from FSharp.Compiler.Symbols
<summary> A collection of active patterns to analyze expressions </summary>
active recognizer AddressOf: FSharpExpr -> FSharpExpr option
<summary> Matches expressions which take the address of a location </summary>
val lvalueExpr : FSharpExpr
active recognizer AddressSet: FSharpExpr -> (FSharpExpr * FSharpExpr) option
<summary> Matches expressions which set the contents of an address </summary>
val rvalueExpr : FSharpExpr
active recognizer Application: FSharpExpr -> (FSharpExpr * FSharpType list * FSharpExpr list) option
<summary> Matches expressions which are the application of function values </summary>
val funcExpr : FSharpExpr
val typeArgs : FSharpType list
val argExprs : FSharpExpr list
val visitExprs : f:(FSharpExpr -> unit) -> exprs:FSharpExpr list -> unit
active recognizer Call: FSharpExpr -> (FSharpExpr option * FSharpMemberOrFunctionOrValue * FSharpType list * FSharpType list * FSharpExpr list) option
<summary> Matches expressions which are calls to members or module-defined functions. When calling curried functions and members the arguments are collapsed to a single collection of arguments, as done in the compiled version of these. </summary>
val objExprOpt : FSharpExpr option
val memberOrFunc : FSharpMemberOrFunctionOrValue
val typeArgs1 : FSharpType list
val typeArgs2 : FSharpType list
val visitObjArg : f:(FSharpExpr -> unit) -> objOpt:FSharpExpr option -> unit
active recognizer Coerce: FSharpExpr -> (FSharpType * FSharpExpr) option
<summary> Matches expressions which coerce the type of a value </summary>
val targetType : FSharpType
val inpExpr : FSharpExpr
active recognizer FastIntegerForLoop: FSharpExpr -> (FSharpExpr * FSharpExpr * FSharpExpr * bool * FSharp.Compiler.Syntax.DebugPointAtFor * FSharp.Compiler.Syntax.DebugPointAtInOrTo) option
<summary> Matches fast-integer loops (up or down) </summary>
val startExpr : FSharpExpr
val limitExpr : FSharpExpr
val consumeExpr : FSharpExpr
val isUp : bool
active recognizer ILAsm: FSharpExpr -> (string * FSharpType list * FSharpExpr list) option
<summary> Matches expressions which are IL assembly code </summary>
val asmCode : string
active recognizer ILFieldGet: FSharpExpr -> (FSharpExpr option * FSharpType * string) option
<summary> Matches expressions which fetch a field from a .NET type </summary>
val fieldType : FSharpType
val fieldName : string
active recognizer ILFieldSet: FSharpExpr -> (FSharpExpr option * FSharpType * string * FSharpExpr) option
<summary> Matches expressions which set a field in a .NET type </summary>
val valueExpr : FSharpExpr
active recognizer IfThenElse: FSharpExpr -> (FSharpExpr * FSharpExpr * FSharpExpr) option
<summary> Matches expressions which are conditionals </summary>
val guardExpr : FSharpExpr
val thenExpr : FSharpExpr
val elseExpr : FSharpExpr
active recognizer Lambda: FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpExpr) option
<summary> Matches expressions which are lambda abstractions </summary>
val lambdaVar : FSharpMemberOrFunctionOrValue
val bodyExpr : FSharpExpr
active recognizer Let: FSharpExpr -> ((FSharpMemberOrFunctionOrValue * FSharpExpr * FSharp.Compiler.Syntax.DebugPointAtBinding) * FSharpExpr) option
<summary> Matches expressions which are let definitions </summary>
val bindingVar : FSharpMemberOrFunctionOrValue
val bindingExpr : FSharpExpr
val dbg : FSharp.Compiler.Syntax.DebugPointAtBinding
active recognizer LetRec: FSharpExpr -> ((FSharpMemberOrFunctionOrValue * FSharpExpr * FSharp.Compiler.Syntax.DebugPointAtBinding) list * FSharpExpr) option
<summary> Matches expressions which are let-rec definitions </summary>
val recursiveBindings : (FSharpMemberOrFunctionOrValue * FSharpExpr * FSharp.Compiler.Syntax.DebugPointAtBinding) list
active recognizer NewArray: FSharpExpr -> (FSharpType * FSharpExpr list) option
<summary> Matches array expressions </summary>
val arrayType : FSharpType
active recognizer NewDelegate: FSharpExpr -> (FSharpType * FSharpExpr) option
<summary> Matches expressions which create an instance of a delegate type </summary>
val delegateType : FSharpType
val delegateBodyExpr : FSharpExpr
active recognizer NewObject: FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpType list * FSharpExpr list) option
<summary> Matches expressions which are calls to object constructors </summary>
val objType : FSharpMemberOrFunctionOrValue
active recognizer NewRecord: FSharpExpr -> (FSharpType * FSharpExpr list) option
<summary> Matches record expressions </summary>
val recordType : FSharpType
active recognizer NewAnonRecord: FSharpExpr -> (FSharpType * FSharpExpr list) option
<summary> Matches anonymous record expressions </summary>
active recognizer NewTuple: FSharpExpr -> (FSharpType * FSharpExpr list) option
<summary> Matches tuple expressions </summary>
val tupleType : FSharpType
active recognizer NewUnionCase: FSharpExpr -> (FSharpType * FSharpUnionCase * FSharpExpr list) option
<summary> Matches expressions which create an object corresponding to a union case </summary>
val unionType : FSharpType
val unionCase : FSharpUnionCase
active recognizer Quote: FSharpExpr -> FSharpExpr option
<summary> Matches expressions which are quotation literals </summary>
val quotedExpr : FSharpExpr
active recognizer FSharpFieldGet: FSharpExpr -> (FSharpExpr option * FSharpType * FSharpField) option
<summary> Matches expressions which get a field from a record or class </summary>
val recordOrClassType : FSharpType
val fieldInfo : FSharpField
active recognizer AnonRecordGet: FSharpExpr -> (FSharpExpr * FSharpType * int) option
<summary> Matches expressions getting a field from an anonymous record. The integer represents the index into the sorted fields of the anonymous record. </summary>
val objExpr : FSharpExpr
val fieldInfo : int
active recognizer FSharpFieldSet: FSharpExpr -> (FSharpExpr option * FSharpType * FSharpField * FSharpExpr) option
<summary> Matches expressions which set a field in a record or class </summary>
val argExpr : FSharpExpr
active recognizer Sequential: FSharpExpr -> (FSharpExpr * FSharpExpr) option
<summary> Matches sequential expressions </summary>
val firstExpr : FSharpExpr
val secondExpr : FSharpExpr
active recognizer TryFinally: FSharpExpr -> (FSharpExpr * FSharpExpr * FSharp.Compiler.Syntax.DebugPointAtTry * FSharp.Compiler.Syntax.DebugPointAtFinally) option
<summary> Matches try/finally expressions </summary>
val finalizeExpr : FSharpExpr
val dbgTry : FSharp.Compiler.Syntax.DebugPointAtTry
val dbgFinally : FSharp.Compiler.Syntax.DebugPointAtFinally
active recognizer TryWith: FSharpExpr -> (FSharpExpr * FSharpMemberOrFunctionOrValue * FSharpExpr * FSharpMemberOrFunctionOrValue * FSharpExpr * FSharp.Compiler.Syntax.DebugPointAtTry * FSharp.Compiler.Syntax.DebugPointAtWith) option
<summary> Matches try/with expressions </summary>
val catchVar : FSharpMemberOrFunctionOrValue
val catchExpr : FSharpExpr
val dbgWith : FSharp.Compiler.Syntax.DebugPointAtWith
active recognizer TupleGet: FSharpExpr -> (FSharpType * int * FSharpExpr) option
<summary> Matches expressions which get a value from a tuple </summary>
val tupleElemIndex : int
val tupleExpr : FSharpExpr
active recognizer DecisionTree: FSharpExpr -> (FSharpExpr * (FSharpMemberOrFunctionOrValue list * FSharpExpr) list) option
<summary> Matches expressions with a decision expression, each branch of which ends in DecisionTreeSuccess passing control and values to one of the targets. </summary>
val decisionExpr : FSharpExpr
val decisionTargets : (FSharpMemberOrFunctionOrValue list * FSharpExpr) list
Multiple items
module List from Microsoft.FSharp.Collections
<summary>Contains operations for working with values of type <see cref="T:Microsoft.FSharp.Collections.list`1" />.</summary>
<namespacedoc><summary>Operations for collections such as lists, arrays, sets, maps and sequences. See also <a href="https://docs.microsoft.com/dotnet/fsharp/language-reference/fsharp-collection-types">F# Collection Types</a> in the F# Language Guide. </summary></namespacedoc>


--------------------
type List<'T> = | ( [] ) | ( :: ) of Head: 'T * Tail: 'T list interface IReadOnlyList<'T> interface IReadOnlyCollection<'T> interface IEnumerable interface IEnumerable<'T> member GetReverseIndex : rank:int * offset:int -> int member GetSlice : startIndex:int option * endIndex:int option -> 'T list static member Cons : head:'T * tail:'T list -> 'T list member Head : 'T member IsEmpty : bool member Item : index:int -> 'T with get ...
<summary>The type of immutable singly-linked lists.</summary>
<remarks>Use the constructors <c>[]</c> and <c>::</c> (infix) to create values of this type, or the notation <c>[1;2;3]</c>. Use the values in the <c>List</c> module to manipulate values of this type, or pattern match against the values directly. </remarks>
<exclude />
val iter : action:('T -> unit) -> list:'T list -> unit
<summary>Applies the given function to each element of the collection.</summary>
<param name="action">The function to apply to elements from the input list.</param>
<param name="list">The input list.</param>
val snd : tuple:('T1 * 'T2) -> 'T2
<summary>Return the second element of a tuple, <c>snd (a,b) = b</c>.</summary>
<param name="tuple">The input tuple.</param>
<returns>The second value.</returns>
active recognizer DecisionTreeSuccess: FSharpExpr -> (int * FSharpExpr list) option
<summary> Special expressions at the end of a conditional decision structure in the decision expression node of a DecisionTree . The given expressions are passed as values to the decision tree target. </summary>
val decisionTargetIdx : int
val decisionTargetExprs : FSharpExpr list
active recognizer TypeLambda: FSharpExpr -> (FSharpGenericParameter list * FSharpExpr) option
<summary> Matches expressions which are type abstractions </summary>
val genericParam : FSharpGenericParameter list
active recognizer TypeTest: FSharpExpr -> (FSharpType * FSharpExpr) option
<summary> Matches expressions which test the runtime type of a value </summary>
val ty : FSharpType
active recognizer UnionCaseSet: FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase * FSharpField * FSharpExpr) option
<summary> Matches expressions which set a field from a union case (only used in FSharp.Core itself) </summary>
val unionExpr : FSharpExpr
val unionCaseField : FSharpField
active recognizer UnionCaseGet: FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase * FSharpField) option
<summary> Matches expressions which get a field from a union case </summary>
active recognizer UnionCaseTest: FSharpExpr -> (FSharpExpr * FSharpType * FSharpUnionCase) option
<summary> Matches expressions which test if an expression corresponds to a particular union case </summary>
active recognizer UnionCaseTag: FSharpExpr -> (FSharpExpr * FSharpType) option
<summary> Matches expressions which gets the tag for a union case </summary>
active recognizer ObjectExpr: FSharpExpr -> (FSharpType * FSharpExpr * FSharpObjectExprOverride list * (FSharpType * FSharpObjectExprOverride list) list) option
<summary> Matches object expressions, returning the base type, the base call, the overrides and the interface implementations </summary>
val objType : FSharpType
val baseCallExpr : FSharpExpr
val overrides : FSharpObjectExprOverride list
val interfaceImplementations : (FSharpType * FSharpObjectExprOverride list) list
val visitObjMember : f:(FSharpExpr -> unit) -> memb:FSharpObjectExprOverride -> unit
active recognizer TraitCall: FSharpExpr -> (FSharpType list * string * FSharp.Compiler.Syntax.SynMemberFlags * FSharpType list * FSharpType list * FSharpExpr list) option
<summary> Matches expressions for an unresolved call to a trait </summary>
val sourceTypes : FSharpType list
val traitName : string
val typeArgs : FSharp.Compiler.Syntax.SynMemberFlags
val typeInstantiation : FSharpType list
val argTypes : FSharpType list
active recognizer ValueSet: FSharpExpr -> (FSharpMemberOrFunctionOrValue * FSharpExpr) option
<summary> Matches expressions which set the contents of a mutable variable </summary>
val valToSet : FSharpMemberOrFunctionOrValue
active recognizer WhileLoop: FSharpExpr -> (FSharpExpr * FSharpExpr * FSharp.Compiler.Syntax.DebugPointAtWhile) option
<summary> Matches while loops </summary>
val dbg : FSharp.Compiler.Syntax.DebugPointAtWhile
active recognizer BaseValue: FSharpExpr -> FSharpType option
<summary> Matches expressions which are uses of the 'base' value </summary>
val baseType : FSharpType
active recognizer DefaultValue: FSharpExpr -> FSharpType option
<summary> Matches default-value expressions, including null expressions </summary>
val defaultType : FSharpType
active recognizer ThisValue: FSharpExpr -> FSharpType option
<summary> Matches expressions which are uses of the 'this' value </summary>
val thisType : FSharpType
active recognizer Const: FSharpExpr -> (obj * FSharpType) option
<summary> Matches constant expressions, including signed and unsigned integers, strings, characters, booleans, arrays of bytes and arrays of unit16. </summary>
val constValueObj : obj
val constType : FSharpType
active recognizer Value: FSharpExpr -> FSharpMemberOrFunctionOrValue option
<summary> Matches expressions which are uses of values </summary>
val valueToGet : FSharpMemberOrFunctionOrValue
val sprintf : format:Printf.StringFormat<'T> -> 'T
<summary>Print to a string using the given format.</summary>
<param name="format">The formatter.</param>
<returns>The formatted result.</returns>
val exprs : FSharpExpr list
val objOpt : FSharpExpr option
module Option from Microsoft.FSharp.Core
<summary>Contains operations for working with options.</summary>
<category>Options</category>
val iter : action:('T -> unit) -> option:'T option -> unit
<summary><c>iter f inp</c> executes <c>match inp with None -&gt; () | Some x -&gt; f x</c>.</summary>
<param name="action">A function to apply to the option value.</param>
<param name="option">The input option.</param>
<example><code> None |&gt; Option.iter (printfn "%s") // does nothing Some "Hello world" |&gt; Option.iter (printfn "%s") // prints "Hello world" </code></example>
<returns>Unit if the option is None, otherwise it returns the result of applying the predicate to the option value.</returns>
val memb : FSharpObjectExprOverride
property FSharpObjectExprOverride.Body: FSharpExpr with get
<summary> The expression that forms the body of the method </summary>