TP

Looking under the cover (How does it work?)

The source code of the project is available in the F# Community Samples project at CodePlex (under the MS-PL license). In this section, I'll write little information about the implementation of the tool. This may be interesting if you want to implement something similar yourself (anything to do with F# color highlighting or IntelliSense) or if you want to contribute to the tool - it is open-source and you are more than welcome to make it even better!

The implementation is easier than you would expect, because the information about types as well as the tokenizer (used for colorization) is available as a service of the F# compiler (more specifically, the FSharp.Compiler.dll assembly). The only problem is that the functionality is not quite documented (there are some comments in the source code distributed with the F# CTP) and that the functionality is marked as internal (with several InternalsVisibleTo attributes that expose it to F# integration for Visual Studio).

Internal F# language service API

To call the internal API, I'm using a couple of wrapper types that provide a typed access to the F# compiler API. Under the cover, the wrappers use .NET Reflection to call the F# compiler services. To implement the wrappers, I first create my implementation of the dynamic invoke operator (<expr>?<ident>) that calls a method or reads a property of any .NET object using Reflection.

The implementation of the dynamic invoke operator is quite interesting, but it would require a whole separate blog post, so we won't discuss it here (although I may write the blog post about it sooner or later and you can find it in the source code). Instead, we'll look at a part of the wrapper for the most important type. The InteractiveChecker type represents an F# compiler service running in the background that can be called to parse a source code (Visual Studio does that when the source changes) and to get information about a parsed F# file. There are two kinds of information that we can get from the background service:

The following snippet shows a part of the wrapper for the InteractiveChecker type. It shows a method used for creating it and two methods that are used to get the untyped and typed information about F# source file. Finally, there is also a method that tries to get both of the information from a cache (which can be used by IDE to get information quickly). As you can see, the dynamic access operator makes the implementation quite easy:

 1: type InteractiveChecker(wrapped:obj) =
 2:   /// Crate a new instance of a wrapped InteractiveChecker object
 3:   static member Create (dirty:FileTypeCheckStateIsDirty) =
 4:     InteractiveChecker(FSharpCompiler.InteractiveChecker?Create(dirty))
 5:     
 6:   /// Parse a source code file, returning a handle that can be used for obtaining navigation 
 7:   /// bar information; to get the full information, call 'TypeCheckSource' method on the result
 8:   member x.UntypedParse(filename:string, source:string, options:CheckOptions) : UntypedParseInfo =
 9:     UntypedParseInfo(wrapped?UntypedParse(filename, source, options.Wrapped))
10: 
11:   /// Typecheck a source code file, returning a handle to the results of the parse including
12:   /// the reconstructed types in the file. Returns 'None' if the background builder is not yet 
13:   /// done preparing the type check results for the antecedent to the file.
14:   member x.TypeCheckSource
15:       ( parsed:UntypedParseInfo, filename:string, fileversion:int, 
16:         source:string, options:CheckOptions, (IsResultObsolete f)) = (...)
17: 
18:   /// Try to get recent type check results for a file. This may arbitrarily refuse to 
19:   /// return any results if the 'InteractiveChecker' would like a chance to recheck the 
20:   /// file, in which case 'UntypedParse' and 'TypeCheckSource' should be called. If the 
21:   /// source of the file has changed the results returned by this function may be out 
22:   /// of date, though may still be usable for generating intellsense menus and information.
23:   member x.TryGetRecentTypeCheckResultsForFile(filename:string, options:CheckOptions) =
24:     let res = wrapped?TryGetRecentTypeCheckResultsForFile(filename, options.Wrapped) : obj
25:     if res = null then None else
26:       let tuple = res?Value
27:       Some(UntypedParseInfo(tuple?Item1), TypeCheckResults(tuple?Item2), int tuple?Item3)F# Web Snippets

The ? operator can be used in various ways. In the Create method, we use it to call a static method of a type (the InteractiveChecker property of the FSharpCompiler type returns a value of type System.Type that represents the type whose static method we want to call). In the UntypedParse method, we call an instance method of the wrapped object. In both of the cases, the parameters are written as a tuple and the dynamic invoke operator extracts elements of the tuple and passes it to the method using Reflection. Note that we have to provide type annotations (for both parameters and return type), because the compiler doesn't have any hints about the types. Without type annotations, everything would be of type obj, but we want to define a typed wrapper. We also wrap the result of method call into other wrapper types (e.g. UntypedParseInfo) that are implemented similarly to InteractiveChecker.

Finally, the TryGetRecentTypeCheckResultsForFile method shows one complication of this approach. When a method returns an F# option type (or a tuple or list), we don't know the exact type of the result (because the actual type argument is some internal type). As a result, we cannot use the option type (or a tuple) in an untyped manner. For option type, we simply check if the value is null, because this is how None is represented and otherwise use the Value property to get the actual value. The situation with tuples is quite similar - we need to dynamically access the properties Item1, Item2, etc. to get the values of the tuple.

Obtaining typed information

Once we have the wrapper, we can use it to parse F# source code and get typed information for IntelliSense. The following code shows a part of a type declaration that implements the source file processing. It starts by creating an instance of InteractiveChecker and constructing object that represents F# compiler options. Then we parse the source code to get an untyped information. This is relatively fast operation that doesn't fail. Getting typed information may fail (the checker needs to process all referenced files first), so we use asynchronous workflow to invoke the operation repeatedly:

 1: type SourceFile(file, source, lines:string[], ?options, ?defines) = 
 2:   (construction of interactive checker and compiler options omitted)
 3: 
 4:   // Run first parsing phase - parse source into AST without type information 
 5:   let untypedInfo = checker.UntypedParse(file, source, opts) 
 6: 
 7:   /// Type-checking takes some time and doesn't return information on the
 8:   /// first call, so this function creates workflow that tries repeatedly
 9:   let rec getTypeCheckInfo() = async {
10:     let obs = IsResultObsolete(fun () -> false)
11:     let info = checker.TypeCheckSource(untypedInfo, file, 0, source, opts, obs) 
12:     match info with
13:     | TypeCheckSucceeded(res) when res.TypeCheckInfo.IsSome ->
14:         let errs = (copying of errors omitted)
15:         return res.TypeCheckInfo.Value, errs
16:     | _ -> 
17:         do! Async.Sleep(500)
18:         return! getTypeCheckInfo() }
19: 
20:   /// Runs type checking and allows specifying a timeout
21:   member x.RunTypeCheck(?timeout) =
22:     Async.RunSynchronously(getTypeCheckInfo(), ?timeout = timeout)F# Web Snippets

The asynchronous workflow implements a simple loop that calls TypeCheckSource. When the result of the call is a value representing successful parsing and it contains a value with the actual result then we return the value (together with a list of errors reported by F# compiler). If the operation fails, we simply wait 500ms and then try again. The workflow can be started from the RunTypeCheck method which allows specification of a timeout and blocks until the operation completes (the application doesn't hang, because the whole processing is done in background).

As you can see from the tool tips in the snippet above, the object that we get as the result has a type TypeCheckInfo. This type exposes various methods that can be used to get information that might be used to implement IntelliSense for F#. In the next section, we'll see how to use it to get tool tip for a specified location in the source.

Processing of source code lines

Once the compiler successfully parses and type-checks our F# source code, we process the entire source code, colorize keywords and literals and generate tool tips for identifiers. The processing is implemented using SourceTokenizer type, which is relatively easy to use. It gives us a list of tokens for each line. We will not look at working with this type (you can find it in the source code) and instead we'll look at post processing of lines that calculates color of tokens and finds tool tips using the TypeCheckInfo object:

 1: let rec processLine island tokens = seq {
 2:   match tokens with 
 3:   | [] -> ()
 4:   | (str, (tok:TokenInformation))::rest ->
 5:     (updating of long identifier information omitted)
 6:     let tip =
 7:       // If we're processing an identfier, see if it has any tool tip
 8:       if (tok.TokenName = "IDENT") then
 9:         let island = island |> List.rev
10:         let pos = (line, tok.LeftColumn + 1)
11:         let tip = checkInfo.GetDataTipText(pos, lines.[line], island, identToken)
12:         match ToolTip.TryCreate(tip) with
13:         | Some(_) as res -> res
14:         | _ when island.Length > 1 -> (alternative attempt omitted)
15:         | _ -> None
16:       elif tok.TokenName.StartsWith("OMIT") then (...)
17:       else None
18: 
19:     // Find color for the current token
20:     let color = 
21:       if tok.TokenName.StartsWith("OMIT") then Some("omitted")
22:       else Colors.colorMap.TryFind(tok.ColorClass)
23:     // Return all information about token and continue
24:     yield { Token = tok; Text = str; Color = color; Tip = tip }
25:     yield! processLine island rest }F# Web Snippets

The snippet shows a function processLine that recursively processes a list of tokens (tokens) on a single line. It also maintains a state with the current long name (named island), which is needed for getting tool tip information. An example of a long name is Collections.List.map - when a mouse pointer is over List, we want to show information about the module, but when the pointer moves to map, we want to show type signature of a function. When getting the IntelliSense information, the F# language service wants a current identifier as an input (so that it doesn't show outdated information based just on the location when the source code changes).

In the recursive processing, we get a TokenInformation value. When the name of the token is IDENT, we want to see if there is any tool tip information for the token, so we use the GetDataTipText method to query the F# language service. Alternatively, the token name may be OMIT - this is a special name generated by our pre-processing that deals with (*[omit:...]*) comments. In this case, we return a tool tip with the collapsed text.

Finally, once we determine the tool tip information, we also want to get a color of the current token. This is quite easy, because the color is reported from the tokenizer (the property name is ColorClass). We first handle our special OMIT token and for all other (standard) tokens, we use a simple lookup into a table that returns a CSS class name. You can find the possible CSS class names in a sample CSS file template (see downloads below).

Summary

In this article, I presented a tool for generating nice HTML snippets from F# source code called F# Web Snippets. The most interesting thing about the tool is that it also generates tool tips with type information for F# identifiers. This way, the readers of your blog get almost the same user experience as when reading F# code in Visual Studio. The additional information makes the code much easier to follow. You can see some examples of formatted F# code in this article and also in my three recent articles on parallel programming. To use the tool, you can either try a (somewhat limited and slow) web based version or download a standalone WinForms application (see links below). If you want to use the tool on your blog, you'll need to add a simple JavaScript and CSS snippets to your blog template (you can get those below too).

The second part of the article also talked briefly about the implementation - the tool invokes F# compiler service under the cover. This is done using Reflection, because the services are internal, but it provides a reasonably comfortable way of implementing colorization or IntelliSense tools for F#. I demonstrated how to initialize the service and how to use it to get tool tip information - hopefully, you can use this information to build some interesting F# tools yourself!

References & source code

namespace System
namespace System.IO
namespace System.Net
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Control
module WebExtensions

from Microsoft.FSharp.Control
val downloadUrl : string -> Async<string>

Full name: Untitled.downloadUrl

Asynchronously download the content of a web page
val url : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
val req : WebRequest

  type: WebRequest
  implements: Runtime.Serialization.ISerializable
  inherits: MarshalByRefObject
type HttpWebRequest =
  class
    inherit System.Net.WebRequest
    member Abort : unit -> unit
    member Accept : string with get, set
    member AddRange : int -> unit
    member AddRange : int * int -> unit
    member AddRange : string * int -> unit
    member AddRange : string * int * int -> unit
    member Address : System.Uri
    member AllowAutoRedirect : bool with get, set
    member AllowWriteStreamBuffering : bool with get, set
    member AutomaticDecompression : System.Net.DecompressionMethods with get, set
    member BeginGetRequestStream : System.AsyncCallback * obj -> System.IAsyncResult
    member BeginGetResponse : System.AsyncCallback * obj -> System.IAsyncResult
    member ClientCertificates : System.Security.Cryptography.X509Certificates.X509CertificateCollection with get, set
    member Connection : string with get, set
    member ConnectionGroupName : string with get, set
    member ContentLength : int64 with get, set
    member ContentType : string with get, set
    member ContinueDelegate : System.Net.HttpContinueDelegate with get, set
    member CookieContainer : System.Net.CookieContainer with get, set
    member Credentials : System.Net.ICredentials with get, set
    member EndGetRequestStream : System.IAsyncResult -> System.IO.Stream
    member EndGetRequestStream : System.IAsyncResult * System.Net.TransportContext -> System.IO.Stream
    member EndGetResponse : System.IAsyncResult -> System.Net.WebResponse
    member Expect : string with get, set
    member GetRequestStream : unit -> System.IO.Stream
    member GetRequestStream : System.Net.TransportContext -> System.IO.Stream
    member GetResponse : unit -> System.Net.WebResponse
    member HaveResponse : bool
    member Headers : System.Net.WebHeaderCollection with get, set
    member IfModifiedSince : System.DateTime with get, set
    member KeepAlive : bool with get, set
    member MaximumAutomaticRedirections : int with get, set
    member MaximumResponseHeadersLength : int with get, set
    member MediaType : string with get, set
    member Method : string with get, set
    member Pipelined : bool with get, set
    member PreAuthenticate : bool with get, set
    member ProtocolVersion : System.Version with get, set
    member Proxy : System.Net.IWebProxy with get, set
    member ReadWriteTimeout : int with get, set
    member Referer : string with get, set
    member RequestUri : System.Uri
    member SendChunked : bool with get, set
    member ServicePoint : System.Net.ServicePoint
    member Timeout : int with get, set
    member TransferEncoding : string with get, set
    member UnsafeAuthenticatedConnectionSharing : bool with get, set
    member UseDefaultCredentials : bool with get, set
    member UserAgent : string with get, set
    static member DefaultCachePolicy : System.Net.Cache.RequestCachePolicy with get, set
    static member DefaultMaximumErrorResponseLength : int with get, set
    static member DefaultMaximumResponseHeadersLength : int with get, set
  end

Full name: System.Net.HttpWebRequest

  type: HttpWebRequest
  implements: Runtime.Serialization.ISerializable
  inherits: WebRequest
  inherits: MarshalByRefObject
Multiple overloads
WebRequest.Create(requestUri: Uri) : WebRequest
WebRequest.Create(requestUriString: string) : WebRequest
type Uri =
  class
    new : string -> System.Uri
    new : string * bool -> System.Uri
    new : string * System.UriKind -> System.Uri
    new : System.Uri * string -> System.Uri
    new : System.Uri * string * bool -> System.Uri
    new : System.Uri * System.Uri -> System.Uri
    member AbsolutePath : string
    member AbsoluteUri : string
    member Authority : string
    member DnsSafeHost : string
    member Equals : obj -> bool
    member Fragment : string
    member GetComponents : System.UriComponents * System.UriFormat -> string
    member GetHashCode : unit -> int
    member GetLeftPart : System.UriPartial -> string
    member Host : string
    member HostNameType : System.UriHostNameType
    member IsAbsoluteUri : bool
    member IsBaseOf : System.Uri -> bool
    member IsDefaultPort : bool
    member IsFile : bool
    member IsLoopback : bool
    member IsUnc : bool
    member IsWellFormedOriginalString : unit -> bool
    member LocalPath : string
    member MakeRelative : System.Uri -> string
    member MakeRelativeUri : System.Uri -> System.Uri
    member OriginalString : string
    member PathAndQuery : string
    member Port : int
    member Query : string
    member Scheme : string
    member Segments : string []
    member ToString : unit -> string
    member UserEscaped : bool
    member UserInfo : string
    static val UriSchemeFile : string
    static val UriSchemeFtp : string
    static val UriSchemeGopher : string
    static val UriSchemeHttp : string
    static val UriSchemeHttps : string
    static val UriSchemeMailto : string
    static val UriSchemeNews : string
    static val UriSchemeNntp : string
    static val UriSchemeNetTcp : string
    static val UriSchemeNetPipe : string
    static val SchemeDelimiter : string
    static member CheckHostName : string -> System.UriHostNameType
    static member CheckSchemeName : string -> bool
    static member Compare : System.Uri * System.Uri * System.UriComponents * System.UriFormat * System.StringComparison -> int
    static member EscapeDataString : string -> string
    static member EscapeUriString : string -> string
    static member FromHex : char -> int
    static member HexEscape : char -> string
    static member HexUnescape : string * int -> char
    static member IsHexDigit : char -> bool
    static member IsHexEncoding : string * int -> bool
    static member IsWellFormedUriString : string * System.UriKind -> bool
    static member TryCreate : string * System.UriKind * System.Uri -> bool
    static member TryCreate : System.Uri * string * System.Uri -> bool
    static member TryCreate : System.Uri * System.Uri * System.Uri -> bool
    static member UnescapeDataString : string -> string
  end

Full name: System.Uri

  type: Uri
  implements: Runtime.Serialization.ISerializable
val resp : WebResponse

  type: WebResponse
  implements: Runtime.Serialization.ISerializable
  implements: IDisposable
  inherits: MarshalByRefObject
member WebRequest.AsyncGetResponse : unit -> Async<WebResponse>
val stream : Stream

  type: Stream
  implements: IDisposable
  inherits: MarshalByRefObject
WebResponse.GetResponseStream() : Stream
val reader : StreamReader

  type: StreamReader
  implements: IDisposable
  inherits: TextReader
  inherits: MarshalByRefObject
type StreamReader =
  class
    inherit System.IO.TextReader
    new : System.IO.Stream -> System.IO.StreamReader
    new : System.IO.Stream * bool -> System.IO.StreamReader
    new : System.IO.Stream * System.Text.Encoding -> System.IO.StreamReader
    new : System.IO.Stream * System.Text.Encoding * bool -> System.IO.StreamReader
    new : System.IO.Stream * System.Text.Encoding * bool * int -> System.IO.StreamReader
    new : string -> System.IO.StreamReader
    new : string * bool -> System.IO.StreamReader
    new : string * System.Text.Encoding -> System.IO.StreamReader
    new : string * System.Text.Encoding * bool -> System.IO.StreamReader
    new : string * System.Text.Encoding * bool * int -> System.IO.StreamReader
    member BaseStream : System.IO.Stream
    member Close : unit -> unit
    member CurrentEncoding : System.Text.Encoding
    member DiscardBufferedData : unit -> unit
    member EndOfStream : bool
    member Peek : unit -> int
    member Read : unit -> int
    member Read : char [] * int * int -> int
    member ReadLine : unit -> string
    member ReadToEnd : unit -> string
    static val Null : System.IO.StreamReader
  end

Full name: System.IO.StreamReader

  type: StreamReader
  implements: IDisposable
  inherits: TextReader
  inherits: MarshalByRefObject
member StreamReader.AsyncReadToEnd : unit -> Async<string>
val getTotalLength : string list -> Async<int>

Full name: Untitled.getTotalLength

Download specified pages and add their lengths
val urls : string list

  type: string list
  implements: Collections.IStructuralEquatable
  implements: IComparable<List<string>>
  implements: IComparable
  implements: Collections.IStructuralComparable
  implements: Collections.Generic.IEnumerable<string>
  implements: Collections.IEnumerable
val texts : string []

  type: string []
  implements: ICloneable
  implements: Collections.IList
  implements: Collections.ICollection
  implements: Collections.Generic.IList<string>
  implements: Collections.Generic.ICollection<string>
  implements: seq<string>
  implements: Collections.IEnumerable
  inherits: Array
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------

type List<'T> =
  | ( [] )
  | ( :: ) of 'T * 'T list
  with
    interface Collections.IEnumerable
    interface Collections.Generic.IEnumerable<'T>
    member Head : 'T
    member IsEmpty : bool
    member Item : index:int -> 'T with get
    member Length : int
    member Tail : 'T list
    static member Cons : head:'T * tail:'T list -> 'T list
    static member Empty : 'T list
  end

Full name: Microsoft.FSharp.Collections.List<_>

  type: List<'T>
  implements: Collections.IStructuralEquatable
  implements: IComparable<List<'T>>
  implements: IComparable
  implements: Collections.IStructuralComparable
  implements: Collections.Generic.IEnumerable<'T>
  implements: Collections.IEnumerable
val map : ('T -> 'U) -> 'T list -> 'U list

Full name: Microsoft.FSharp.Collections.List.map
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

--------------------

type Async
with
  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 AwaitWaitHandle : waitHandle:Threading.WaitHandle * ?millisecondsTimeout:int -> Async<bool>
  static member CancelDefaultToken : unit -> unit
  static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
  static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
  static member Ignore : computation:Async<'T> -> Async<unit>
  static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
  static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
  static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
  static member Sleep : millisecondsDueTime:int -> Async<unit>
  static member Start : computation:Async<unit> * ?cancellationToken:Threading.CancellationToken -> unit
  static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
  static member StartImmediate : computation:Async<unit> * ?cancellationToken:Threading.CancellationToken -> unit
  static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:Threading.CancellationToken -> unit
  static member SwitchToContext : syncContext:Threading.SynchronizationContext -> Async<unit>
  static member SwitchToNewThread : unit -> Async<unit>
  static member SwitchToThreadPool : unit -> Async<unit>
  static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
  static member CancellationToken : Async<Threading.CancellationToken>
  static member DefaultCancellationToken : Threading.CancellationToken
end

Full name: Microsoft.FSharp.Control.Async
static member Async.Parallel : computations:seq<Async<'T>> -> Async<'T []>
module Seq

from Microsoft.FSharp.Collections
val sumBy : ('T -> 'U) -> seq<'T> -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.Seq.sumBy
type String =
  class
    new : char -> string
    new : char * int * int -> string
    new : System.SByte -> string
    new : System.SByte * int * int -> string
    new : System.SByte * int * int * System.Text.Encoding -> string
    new : char [] * int * int -> string
    new : char [] -> string
    new : char * int -> string
    member Chars : int -> char
    member Clone : unit -> obj
    member CompareTo : obj -> int
    member CompareTo : string -> int
    member Contains : string -> bool
    member CopyTo : int * char [] * int * int -> unit
    member EndsWith : string -> bool
    member EndsWith : string * System.StringComparison -> bool
    member EndsWith : string * bool * System.Globalization.CultureInfo -> bool
    member Equals : obj -> bool
    member Equals : string -> bool
    member Equals : string * System.StringComparison -> bool
    member GetEnumerator : unit -> System.CharEnumerator
    member GetHashCode : unit -> int
    member GetTypeCode : unit -> System.TypeCode
    member IndexOf : char -> int
    member IndexOf : string -> int
    member IndexOf : char * int -> int
    member IndexOf : string * int -> int
    member IndexOf : string * System.StringComparison -> int
    member IndexOf : char * int * int -> int
    member IndexOf : string * int * int -> int
    member IndexOf : string * int * System.StringComparison -> int
    member IndexOf : string * int * int * System.StringComparison -> int
    member IndexOfAny : char [] -> int
    member IndexOfAny : char [] * int -> int
    member IndexOfAny : char [] * int * int -> int
    member Insert : int * string -> string
    member IsNormalized : unit -> bool
    member IsNormalized : System.Text.NormalizationForm -> bool
    member LastIndexOf : char -> int
    member LastIndexOf : string -> int
    member LastIndexOf : char * int -> int
    member LastIndexOf : string * int -> int
    member LastIndexOf : string * System.StringComparison -> int
    member LastIndexOf : char * int * int -> int
    member LastIndexOf : string * int * int -> int
    member LastIndexOf : string * int * System.StringComparison -> int
    member LastIndexOf : string * int * int * System.StringComparison -> int
    member LastIndexOfAny : char [] -> int
    member LastIndexOfAny : char [] * int -> int
    member LastIndexOfAny : char [] * int * int -> int
    member Length : int
    member Normalize : unit -> string
    member Normalize : System.Text.NormalizationForm -> string
    member PadLeft : int -> string
    member PadLeft : int * char -> string
    member PadRight : int -> string
    member PadRight : int * char -> string
    member Remove : int -> string
    member Remove : int * int -> string
    member Replace : char * char -> string
    member Replace : string * string -> string
    member Split : char [] -> string []
    member Split : char [] * int -> string []
    member Split : char [] * System.StringSplitOptions -> string []
    member Split : string [] * System.StringSplitOptions -> string []
    member Split : char [] * int * System.StringSplitOptions -> string []
    member Split : string [] * int * System.StringSplitOptions -> string []
    member StartsWith : string -> bool
    member StartsWith : string * System.StringComparison -> bool
    member StartsWith : string * bool * System.Globalization.CultureInfo -> bool
    member Substring : int -> string
    member Substring : int * int -> string
    member ToCharArray : unit -> char []
    member ToCharArray : int * int -> char []
    member ToLower : unit -> string
    member ToLower : System.Globalization.CultureInfo -> string
    member ToLowerInvariant : unit -> string
    member ToString : unit -> string
    member ToString : System.IFormatProvider -> string
    member ToUpper : unit -> string
    member ToUpper : System.Globalization.CultureInfo -> string
    member ToUpperInvariant : unit -> string
    member Trim : unit -> string
    member Trim : char [] -> string
    member TrimEnd : char [] -> string
    member TrimStart : char [] -> string
    static val Empty : string
    static member Compare : string * string -> int
    static member Compare : string * string * bool -> int
    static member Compare : string * string * System.StringComparison -> int
    static member Compare : string * string * System.Globalization.CultureInfo * System.Globalization.CompareOptions -> int
    static member Compare : string * string * bool * System.Globalization.CultureInfo -> int
    static member Compare : string * int * string * int * int -> int
    static member Compare : string * int * string * int * int * bool -> int
    static member Compare : string * int * string * int * int * System.StringComparison -> int
    static member Compare : string * int * string * int * int * System.Globalization.CultureInfo * System.Globalization.CompareOptions -> int
    static member Compare : string * int * string * int * int * bool * System.Globalization.CultureInfo -> int
    static member CompareOrdinal : string * string -> int
    static member CompareOrdinal : string * int * string * int * int -> int
    static member Concat : obj -> string
    static member Concat : obj [] -> string
    static member Concat : string [] -> string
    static member Concat : obj * obj -> string
    static member Concat : string * string -> string
    static member Concat : obj * obj * obj -> string
    static member Concat : string * string * string -> string
    static member Concat : obj * obj * obj * obj -> string
    static member Concat : string * string * string * string -> string
    static member Copy : string -> string
    static member Equals : string * string -> bool
    static member Equals : string * string * System.StringComparison -> bool
    static member Format : string * obj -> string
    static member Format : string * obj [] -> string
    static member Format : string * obj * obj -> string
    static member Format : System.IFormatProvider * string * obj [] -> string
    static member Format : string * obj * obj * obj -> string
    static member Intern : string -> string
    static member IsInterned : string -> string
    static member IsNullOrEmpty : string -> bool
    static member Join : string * string [] -> string
    static member Join : string * string [] * int * int -> string
  end

Full name: System.String

  type: String
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val length : string -> int

Full name: Microsoft.FSharp.Core.String.length
async {
  let req = HttpWebRequest.Create(Uri(url))
  let! resp = req.AsyncGetResponse()
  let stream = resp.GetResponseStream()
  let reader = new StreamReader(stream)
  return! reader.AsyncReadToEnd() }
type InteractiveChecker =
  class
    new : wrapped:obj -> InteractiveChecker
    member GetCheckOptionsFromScriptRoot : filename:string * source:string -> CheckOptions
    member StartBackgroundCompile : options:CheckOptions -> 'a
    member TryGetRecentTypeCheckResultsForFile : filename:string * options:CheckOptions -> (UntypedParseInfo * TypeCheckResults * int) option
    member TypeCheckSource : parsed:UntypedParseInfo * filename:string * fileversion:int * source:string * options:CheckOptions * IsResultObsolete -> TypeCheckAnswer
    member UntypedParse : filename:string * source:string * options:CheckOptions -> UntypedParseInfo
    static member Create : dirty:FileTypeCheckStateIsDirty -> InteractiveChecker
  end

Full name: Untitled.SourceCodeServices.InteractiveChecker
val wrapped : obj
type obj = Object

Full name: Microsoft.FSharp.Core.obj
static member InteractiveChecker.Create : dirty:FileTypeCheckStateIsDirty -> InteractiveChecker

Full name: Untitled.SourceCodeServices.InteractiveChecker.Create

Crate a new instance of a wrapped InteractiveChecker object
val dirty : FileTypeCheckStateIsDirty
type FileTypeCheckStateIsDirty = string -> unit

Full name: Untitled.SourceCodeServices.FileTypeCheckStateIsDirty
type FSharpCompiler =
  class
    private new : unit -> FSharpCompiler
    static member CheckOptions : Type
    static member InteractiveChecker : Type
    static member IsResultObsolete : Type
    static member SourceTokenizer : Type
    static member TokenInformation : Type
  end

Full name: Untitled.Reflection.FSharpCompiler

Wrapper type for the 'FSharp.Compiler.dll' assembly - expose types we use
property FSharpCompiler.InteractiveChecker: Type
val x : InteractiveChecker
member InteractiveChecker.UntypedParse : filename:string * source:string * options:CheckOptions -> UntypedParseInfo

Full name: Untitled.SourceCodeServices.InteractiveChecker.UntypedParse

Parse a source code file, returning a handle that can be used for obtaining navigation
 bar information; to get the full information, call 'TypeCheckSource' method on the result

val filename : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
Multiple items
val string : 'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------

type string = String

Full name: Microsoft.FSharp.Core.string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val source : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val options : CheckOptions
type CheckOptions =
  class
    new : wrapped:obj -> CheckOptions
    member WithProjectOptions : options:string [] -> CheckOptions
    member IsIncompleteTypeCheckEnvironment : bool
    member ProjectFileName : string
    member ProjectFileNames : string array
    member ProjectOptions : string array
    member UseScriptResolutionRules : bool
    member Wrapped : obj
    static member Create : fileName:string * fileNames:string [] * options:string [] * incomplete:bool * scriptRes:bool -> CheckOptions
  end

Full name: Untitled.SourceCodeServices.CheckOptions
type UntypedParseInfo =
  class
    new : wrapped:obj -> UntypedParseInfo
    member Wrapped : obj
  end

Full name: Untitled.SourceCodeServices.UntypedParseInfo
property CheckOptions.Wrapped: obj
member InteractiveChecker.TypeCheckSource : parsed:UntypedParseInfo * filename:string * fileversion:int * source:string * options:CheckOptions * IsResultObsolete -> TypeCheckAnswer

Full name: Untitled.SourceCodeServices.InteractiveChecker.TypeCheckSource

Typecheck a source code file, returning a handle to the results of the parse including
 the reconstructed types in the file. Returns 'None' if the background builder is not yet
 done preparing the type check results for the antecedent to the file.

val parsed : UntypedParseInfo
val fileversion : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
Multiple items
val int : 'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------

type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>

  type: int<'Measure>
  implements: IComparable
  implements: IConvertible
  implements: IFormattable
  implements: IComparable<int<'Measure>>
  implements: IEquatable<int<'Measure>>
  inherits: ValueType


--------------------

type int = int32

Full name: Microsoft.FSharp.Core.int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
Multiple items
union case IsResultObsolete.IsResultObsolete: (unit -> bool) -> IsResultObsolete

--------------------

type IsResultObsolete = | IsResultObsolete of (unit -> bool)

Full name: Untitled.SourceCodeServices.IsResultObsolete

Callback that indicates whether a requested result has become obsolete.
val f : (unit -> bool)
TypeCheckAnswer
  ( wrapped?TypeCheckSource
      ( parsed.Wrapped, filename, fileversion, source, options.Wrapped,
        FSharpCompiler.IsResultObsolete?NewIsResultObsolete(f) ) : obj)
member InteractiveChecker.TryGetRecentTypeCheckResultsForFile : filename:string * options:CheckOptions -> (UntypedParseInfo * TypeCheckResults * int) option

Full name: Untitled.SourceCodeServices.InteractiveChecker.TryGetRecentTypeCheckResultsForFile

Try to get recent type check results for a file. This may arbitrarily refuse to
 return any results if the 'InteractiveChecker' would like a chance to recheck the
 file, in which case 'UntypedParse' and 'TypeCheckSource' should be called. If the
 source of the file has changed the results returned by this function may be out
 of date, though may still be usable for generating intellsense menus and information.

val res : obj
union case Option.None: Option<'T>
val tuple : obj
union case Option.Some: 'T -> Option<'T>
type TypeCheckResults =
  class
    new : wrapped:obj -> TypeCheckResults
    member Errors : ErrorInfo array
    member TypeCheckInfo : TypeCheckInfo option
  end

Full name: Untitled.SourceCodeServices.TypeCheckResults

A handle to the results of TypeCheckSource
type SourceFile =
  class
    new : file:string * source:string * lines:string [] * ?options:string * ?defines:string -> SourceFile
    member ProcessSourceTokens : checkInfo:TypeCheckInfo * source:(int * (string * TokenInformation) list) list -> SnippetInfo list
    member RunTypeCheck : ?timeout:int -> TypeCheckInfo * seq<ErrorInfo>
    member TokenizeSource : unit -> (int * (string * TokenInformation) list) list
  end

Full name: Untitled.SourceFile

Parses the specified file using F# compiler (by calling 'TokenizeSource'),
 performs type checking (using 'RunTypeCheck') and then creates information
 for the formatter (using 'ProcessSourceTokens')

val file : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val source : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val lines : string []

  type: string []
  implements: ICloneable
  implements: Collections.IList
  implements: Collections.ICollection
  implements: IList<string>
  implements: ICollection<string>
  implements: seq<string>
  implements: Collections.IEnumerable
  inherits: Array
Multiple items
val string : 'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------

type string = String

Full name: Microsoft.FSharp.Core.string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val options : string option

  type: string option
  implements: Collections.IStructuralEquatable
  implements: IComparable<Option<string>>
  implements: IComparable
  implements: Collections.IStructuralComparable
val defines : string option

  type: string option
  implements: Collections.IStructuralEquatable
  implements: IComparable<Option<string>>
  implements: IComparable
  implements: Collections.IStructuralComparable
  
// Create an instance of an InteractiveChecker (which does background analysis
// in a typical IntelliSense editor integration for F#)
let checker = InteractiveChecker.Create(ignore)
// Get options for a standalone script file (this adds some
// default references and doesn't require full project information)
let opts = checker.GetCheckOptionsFromScriptRoot(file, source)

// Print additional information for debugging
let trace = false
  
// Parse command line options - split string by space, but if there is something
// enclosed in double quotes "..." then ignore spaces in the quoted text
let rec parseOptions (str:string) i opts current =
  let opts =
    if i < str.Length && str.[i] <> ' ' then opts
    else (String(current |> List.rev |> Array.ofSeq))::opts
  if i = str.Length then opts
  elif str.[i] = ' ' then parseOptions str (i+1) opts []
  elif str.[i] = '"' then
    let endp = str.IndexOf('"', i+1)
    let chars = str.Substring(i+1, endp - i - 1) |> List.ofSeq |> List.rev
    parseOptions str (endp + 1) opts (chars @@ current)
  else parseOptions str (i + 1) opts (str.[i] :: current)
    
// Override default options if the user specified something
let opts =
  match options with
  | Some(str:string) when not(String.IsNullOrEmpty(str)) ->
      opts.WithProjectOptions(parseOptions str 0 [] [] |> Array.ofSeq)
  | _ -> opts

// Creates an empty "Identifier" token (we need it when getting ToolTip)
let identToken = 176
val untypedInfo : UntypedParseInfo
val checker : InteractiveChecker
member InteractiveChecker.UntypedParse : filename:string * source:string * options:CheckOptions -> UntypedParseInfo

Parse a source code file, returning a handle that can be used for obtaining navigation bar information
 To get the full information, call 'TypeCheckSource' method on the result

val opts : CheckOptions
val getTypeCheckInfo : (unit -> Async<TypeCheckInfo * seq<ErrorInfo>>)

Type-checking takes some time and doesn't return information on the
 first call, so this function creates workflow that tries repeatedly

val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
val obs : IsResultObsolete
Multiple items
union case IsResultObsolete.IsResultObsolete: (unit -> bool) -> IsResultObsolete

--------------------

type IsResultObsolete = | IsResultObsolete of (unit -> bool)

Full name: Microsoft.FSharp.Compiler.SourceCodeServices.IsResultObsolete

Callback that indicates whether a requested result has become obsolete.
val info : TypeCheckAnswer
member InteractiveChecker.TypeCheckSource : parsed:UntypedParseInfo * filename:string * fileversion:int * source:string * options:CheckOptions * IsResultObsolete -> TypeCheckAnswer

Typecheck a source code file, returning a handle to the results of the parse including
 the reconstructed types in the file.

 Return None if the background builder is not yet done prepring the type check results for the antecedent to the
 file.

Multiple items
val TypeCheckSucceeded : TypeCheckResults -> TypeCheckAnswer

Full name: Microsoft.FSharp.Compiler.SourceCodeServices.TypeCheckSucceeded

--------------------

active recognizer TypeCheckSucceeded: TypeCheckAnswer -> Choice<unit,unit,TypeCheckResults>

Full name: Microsoft.FSharp.Compiler.SourceCodeServices.( |NoAntecedant|Aborted|TypeCheckSucceeded| )
val res : TypeCheckResults
property TypeCheckResults.TypeCheckInfo: TypeCheckInfo option

A handle to type information gleaned from typechecking the file.
property Option.IsSome: bool
val errs : seq<ErrorInfo>

  type: seq<ErrorInfo>
  inherits: Collections.IEnumerable
seq { for e in res.Errors ->
        { StartColumn = e.StartColumn; StartLine = e.StartLine
          Message = e.Message; IsError = e.Severity = Error } }
property Option.Value: TypeCheckInfo
Multiple items
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>

--------------------

type Async
with
  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 AwaitWaitHandle : waitHandle:Threading.WaitHandle * ?millisecondsTimeout:int -> Async<bool>
  static member CancelDefaultToken : unit -> unit
  static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
  static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
  static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
  static member Ignore : computation:Async<'T> -> Async<unit>
  static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
  static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
  static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
  static member Sleep : millisecondsDueTime:int -> Async<unit>
  static member Start : computation:Async<unit> * ?cancellationToken:Threading.CancellationToken -> unit
  static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
  static member StartImmediate : computation:Async<unit> * ?cancellationToken:Threading.CancellationToken -> unit
  static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:Threading.CancellationToken -> unit
  static member SwitchToContext : syncContext:Threading.SynchronizationContext -> Async<unit>
  static member SwitchToNewThread : unit -> Async<unit>
  static member SwitchToThreadPool : unit -> Async<unit>
  static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
  static member CancellationToken : Async<Threading.CancellationToken>
  static member DefaultCancellationToken : Threading.CancellationToken
end

Full name: Microsoft.FSharp.Control.Async
static member Async.Sleep : millisecondsDueTime:int -> Async<unit>
val x : SourceFile
member SourceFile.RunTypeCheck : ?timeout:int -> TypeCheckInfo * seq<ErrorInfo>

Full name: Untitled.SourceFile.RunTypeCheck

Runs type checking and allows specifying a timeout
val timeout : int option

  type: int option
  implements: Collections.IStructuralEquatable
  implements: IComparable<Option<int>>
  implements: IComparable
  implements: Collections.IStructuralComparable
static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:Threading.CancellationToken -> 'T
val processLine : (string list -> (string * TokenInformation) list -> seq<TokenInfo>)
val island : string list

  type: string list
  implements: Collections.IStructuralEquatable
  implements: IComparable<List<string>>
  implements: IComparable
  implements: Collections.IStructuralComparable
  implements: IEnumerable<string>
  implements: Collections.IEnumerable
val tokens : (string * TokenInformation) list

  type: (string * TokenInformation) list
  implements: Collections.IStructuralEquatable
  implements: IComparable<List<string * TokenInformation>>
  implements: IComparable
  implements: Collections.IStructuralComparable
  implements: IEnumerable<string * TokenInformation>
  implements: Collections.IEnumerable
Multiple items
val seq : seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------

type seq<'T> = IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>

  type: seq<'T>
  inherits: Collections.IEnumerable
val str : string

  type: string
  implements: IComparable
  implements: ICloneable
  implements: IConvertible
  implements: IComparable<string>
  implements: seq<char>
  implements: Collections.IEnumerable
  implements: IEquatable<string>
val tok : TokenInformation
type TokenInformation =
  class
    new : wrapped:obj -> TokenInformation
    member WithRightColumn : rightColumn:int -> TokenInformation
    member WithTokenName : tokenName:string -> TokenInformation
    member CharClass : TokenCharKind
    member ColorClass : TokenColorKind
    member LeftColumn : int
    member RightColumn : int
    member Tag : int
    member TokenName : string
    member TriggerClass : TriggerClass
  end

Full name: Microsoft.FSharp.Compiler.SourceCodeServices.TokenInformation
val rest : (string * TokenInformation) list

  type: (string * TokenInformation) list
  implements: Collections.IStructuralEquatable
  implements: IComparable<List<string * TokenInformation>>
  implements: IComparable
  implements: Collections.IStructuralComparable
  implements: IEnumerable<string * TokenInformation>
  implements: Collections.IEnumerable
// Update the current identifier island
// (long identifier e.g. Collections.List.map)
let island =
  match tok.TokenName with
  | "DOT" -> island // keep what we have found so far
  | "IDENT" -> str::island // add current identifier
  | _ -> [] // drop everything - not in island
            
val tip : ToolTip option

  type: ToolTip option
  implements: Collections.IStructuralEquatable
  implements: IComparable<Option<ToolTip>>
  implements: IComparable
  implements: Collections.IStructuralComparable
property TokenInformation.TokenName: string
type List<'T> =
  class
    new : unit -> System.Collections.Generic.List<'T>
    new : int -> System.Collections.Generic.List<'T>
    new : System.Collections.Generic.IEnumerable<'T> -> System.Collections.Generic.List<'T>
    member Add : 'T -> unit
    member AddRange : System.Collections.Generic.IEnumerable<'T> -> unit
    member AsReadOnly : unit -> System.Collections.ObjectModel.ReadOnlyCollection<'T>
    member BinarySearch : 'T -> int
    member BinarySearch : 'T * System.Collections.Generic.IComparer<'T> -> int
    member BinarySearch : int * int * 'T * System.Collections.Generic.IComparer<'T> -> int
    member Capacity : int with get, set
    member Clear : unit -> unit
    member Contains : 'T -> bool
    member ConvertAll<'TOutput> : System.Converter<'T,'TOutput> -> System.Collections.Generic.List<'TOutput>
    member CopyTo : 'T [] -> unit
    member CopyTo : 'T [] * int -> unit
    member CopyTo : int * 'T [] * int * int -> unit
    member Count : int
    member Exists : System.Predicate<'T> -> bool
    member Find : System.Predicate<'T> -> 'T
    member FindAll : System.Predicate<'T> -> System.Collections.Generic.List<'T>
    member FindIndex : System.Predicate<'T> -> int
    member FindIndex : int * System.Predicate<'T> -> int
    member FindIndex : int * int * System.Predicate<'T> -> int
    member FindLast : System.Predicate<'T> -> 'T
    member FindLastIndex : System.Predicate<'T> -> int
    member FindLastIndex : int * System.Predicate<'T> -> int
    member FindLastIndex : int * int * System.Predicate<'T> -> int
    member ForEach : System.Action<'T> -> unit
    member GetEnumerator : unit -> Enumerator<'T>
    member GetRange : int * int -> System.Collections.Generic.List<'T>
    member IndexOf : 'T -> int
    member IndexOf : 'T * int -> int
    member IndexOf : 'T * int * int -> int
    member Insert : int * 'T -> unit
    member InsertRange : int * System.Collections.Generic.IEnumerable<'T> -> unit
    member Item : int -> 'T with get, set
    member LastIndexOf : 'T -> int
    member LastIndexOf : 'T * int -> int
    member LastIndexOf : 'T * int * int -> int
    member Remove : 'T -> bool
    member RemoveAll : System.Predicate<'T> -> int
    member RemoveAt : int -> unit
    member RemoveRange : int * int -> unit
    member Reverse : unit -> unit
    member Reverse : int * int -> unit
    member Sort : unit -> unit
    member Sort : System.Collections.Generic.IComparer<'T> -> unit
    member Sort : System.Comparison<'T> -> unit
    member Sort : int * int * System.Collections.Generic.IComparer<'T> -> unit
    member ToArray : unit -> 'T []
    member TrimExcess : unit -> unit
    member TrueForAll : System.Predicate<'T> -> bool
    type Enumerator =
      struct
        member Current : 'T
        member Dispose : unit -> unit
        member MoveNext : unit -> bool
      end
  end

Full name: System.Collections.Generic.List<_>

  type: List<'T>
  implements: IList<'T>
  implements: ICollection<'T>
  implements: seq<'T>
  implements: Collections.IList
  implements: Collections.ICollection
  implements: Collections.IEnumerable
val rev : 'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.rev
val pos : int * int
val line : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
property TokenInformation.LeftColumn: int
val tip : DataTipText
val checkInfo : TypeCheckInfo
member TypeCheckInfo.GetDataTipText : pos:Position * line:string * names:Names * tokentag:int -> DataTipText

Resolve the names at the given location to give a data tip
val identToken : int

  type: int
  implements: IComparable
  implements: IFormattable
  implements: IConvertible
  implements: IComparable<int>
  implements: IEquatable<int>
  inherits: ValueType
type ToolTip =
  class
    private new : str:string -> ToolTip
    member ToolTipHtml : string
    static member FromString : str:string -> ToolTip
    static member TryCreate : tip:DataTipText -> ToolTip option
  end

Full name: Untitled.ToolTip

Stores information about tool tip for an identifier
static member ToolTip.TryCreate : tip:DataTipText -> ToolTip option

Creates a tool tip - returns 'None' if it contains no data
union case Option.Some: 'T -> Option<'T>
val res : ToolTip option

  type: ToolTip option
  implements: Collections.IStructuralEquatable
  implements: IComparable<Option<ToolTip>>
  implements: IComparable
  implements: Collections.IStructuralComparable
property List.Length: int
// Try to find some information about the last part of the identifier
let pos = (line, tok.LeftColumn + 2)
let tip = checkInfo.GetDataTipText(pos, lines.[line], [ str ], identToken)
ToolTip.TryCreate(tip)
union case Option.None: Option<'T>
Multiple overloads
String.StartsWith(value: string) : bool
String.StartsWith(value: string, comparisonType: StringComparison) : bool
String.StartsWith(value: string, ignoreCase: bool, culture: Globalization.CultureInfo) : bool
// Special omit tag - add tool tip stored in token name
Some(ToolTip.FromString(tok.TokenName.Substring(4)))
val color : string option

  type: string option
  implements: Collections.IStructuralEquatable
  implements: IComparable<Option<string>>
  implements: IComparable
  implements: Collections.IStructuralComparable
module Colors

from Untitled

A mapping from kinds of tokens to CSS classes used by the formatter
val colorMap : Map<TokenColorKind,string>

Full name: Untitled.Colors.colorMap

  type: Map<TokenColorKind,string>
  implements: IComparable
  implements: IDictionary<TokenColorKind,string>
  implements: ICollection<KeyValuePair<TokenColorKind,string>>
  implements: seq<KeyValuePair<TokenColorKind,string>>
  implements: Collections.IEnumerable
property TokenInformation.ColorClass: TokenColorKind
namespace System.Text

Published: Monday, 18 October 2010, 1:42 AM
Author: Tomas Petricek
Typos: Send me a pull request!
Tags: functional, f#