提交 b0292b8a 编写于 作者: D Don Syme 提交者: Phillip Carter

Anonymous record support for expressions in FCS (#6257)

* fix flakey test (?)

* use runsettings

* same fix for FCS tests2

* anonymous record support for expressions in FCS

* anonymous record support for expressions in FCS

* add tests for anonymous records and fix service testing with F# interactive

* fix FCS docs

* fix build

* add diagnostics

* update other baseline

* fix final parallel case

* try again to fix test

* update test fixes
上级 78c7b173
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Notes on the FSharpChecker caches
=================================================
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Hosted Compiler
===============
......@@ -55,7 +55,9 @@ let x = 3 + 4
Now invoke the compiler:
*)
let errors1, exitCode1 = checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
let errors1, exitCode1 =
checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
|> Async.RunSynchronously
(**
......@@ -68,7 +70,9 @@ module M
let x = 1.0 + "" // a type error
""")
let errors1b, exitCode1b = checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
let errors1b, exitCode1b =
checker.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
|> Async.RunSynchronously
(**
......@@ -85,10 +89,12 @@ The 'None' option indicates that the initiatlization code for the assembly is no
*)
let errors2, exitCode2, dynAssembly2 =
checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None)
|> Async.RunSynchronously
(*
Passing 'Some' for the 'execute' parameter executes the initiatlization code for the assembly.
*)
let errors3, exitCode3, dynAssembly3 =
checker.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr))
|> Async.RunSynchronously
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Notes on FSharp.Core.dll
=================================================
......@@ -13,14 +13,11 @@ include a copy of FSharp.Core.dll as part of your application.
For example, if you build a ``HostedCompiler.exe``, you will normally place an FSharp.Core.dll (say 4.3.1.0) alongside
your ``HostedCompiler.exe``.
If doing dynamic compilation and execution you may also need to include
an FSharp.Core.optdata and FSharp.Core.sigdata, see below for guidance.
Binding redirects for your application
--------------------------------------
The FSharp.Compiler.Service.dll component depends on FSharp.Core 4.4.0.0. Normally your application will target
a later version of FSharp.Core, and you will need a [binding redirect](http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.110).aspx) to ensure
a later version of FSharp.Core, and you may need a [binding redirect](http://msdn.microsoft.com/en-us/library/7wd6ex19(v=vs.110).aspx) to ensure
that other versions of FSharp.Core forward to the final version of FSharp.Core.dll your application uses.
Binding redirect files are normally generated automatically by build tools. If not, you can use one like this
(if your tool is called ``HostedCompiler.exe``, the binding redirect file is called ``HostedCompiler.exe.config``)
......@@ -80,27 +77,12 @@ by the following choice:
2. If there is no static reference to FSharp.Core in the host assembly, then
- For FSharp.Compiler.Service 0.x series, a reference to FSharp.Core version 4.3.0.0 is added
- For FSharp.Compiler.Service 1.3.1.x (F# 3.1 series), a reference to FSharp.Core version 4.3.1.0 is added
- For FSharp.Compiler.Service 1.4.0.x (F# 4.0 series), a reference to FSharp.Core version 4.4.0.0 is added
- For FSharp.Compiler.Service 1.4.0.x above (F# 4.0 series), a reference to FSharp.Core version 4.4.0.0 is added
Do I need to include FSharp.Core.optdata and FSharp.Core.sigdata?
--------------------------------------
If your compilation arguments explicitly reference an FSharp.Core.dll from an SDK location, then FSharp.Core.sigdata and FSharp.Core.optdata should be alongside the DLL
(if these files are not installed, then that's a bug in the F# SDK installation). If your compilation
arguments are always making an explicit reference, then you should _not_ include FSharp.Core.optdata and FSharp.Core.sigdata as part of your application.
If you are relying on an implicit reference (e.g. for script processing, see above), this means your tool may reference the FSharp.Core.dll
that is part of your application. In this case, you may either get an error that FSharp.Core.optdata and FSharp.Core.sigdata are not
found alongside FSharp.Core.dll. **If you want to implicitly reference the FSharp.Core.dll you are including in your application,
then also add FSharp.Core.sigdata and FSharp.Core.optdata as two additional files to your application**. When using ``CompileToDynamicAssembly``, this problem
can also manifest itself as [a stack overflow during assembly resolution](https://github.com/fsharp/FSharp.Compiler.Service/issues/258).
Tools that dynamically compile and execute code (e.g. a ``HostedExecution.exe``) often make an implicit
reference to FSharp.Core.dll, which means they normally also include FSharp.Core.optdata and FSharp.Core.sigdata.
No, unless you are doing something with very old FSharp.Core.dll.
Summary
-------
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Editor services
==================================
......@@ -52,7 +52,7 @@ let input =
let inputLines = input.Split('\n')
let file = "/home/user/Test.fsx"
let projOptions =
let projOptions, errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......@@ -131,7 +131,7 @@ open FSharp.Compiler
let identToken = FSharpTokenTag.Identifier
// Get tool tip at the specified location
let tip = checkFileResults.GetToolTipTextAlternate(4, 7, inputLines.[1], ["foo"], identToken)
let tip = checkFileResults.GetToolTipText(4, 7, inputLines.[1], ["foo"], identToken)
printfn "%A" tip
(**
......@@ -165,7 +165,7 @@ where we need to perform the completion.
// Get declarations (autocomplete) for a location
let decls =
checkFileResults.GetDeclarationListInfo
(Some parseFileResults, 7, 23, inputLines.[6], [], "msg", fun _ -> false)
(Some parseFileResults, 7, inputLines.[6], PartialLongName.Empty 23, (fun () -> []), fun _ -> false)
|> Async.RunSynchronously
// Print the names of available items
......@@ -197,7 +197,7 @@ changes):
*)
// Get overloads of the String.Concat method
let methods =
checkFileResults.GetMethodsAlternate(5, 27, inputLines.[4], Some ["String"; "Concat"])
checkFileResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"])
|> Async.RunSynchronously
// Print concatenated parameter lists
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Virtualized File System
==========================================
......@@ -59,18 +59,26 @@ let B = File1.A + File1.A"""
// Implement the service related to temporary paths and file time stamps
member __.GetTempPathShim() =
defaultFileSystem.GetTempPathShim()
member __.GetLastWriteTimeShim(fileName) =
defaultFileSystem.GetLastWriteTimeShim(fileName)
member __.GetFullPathShim(fileName) =
defaultFileSystem.GetFullPathShim(fileName)
member __.IsInvalidPathShim(fileName) =
defaultFileSystem.IsInvalidPathShim(fileName)
member __.IsPathRootedShim(fileName) =
defaultFileSystem.IsPathRootedShim(fileName)
member __.IsStableFileHeuristic(fileName) =
defaultFileSystem.IsStableFileHeuristic(fileName)
// Implement the service related to file existence and deletion
member __.SafeExists(fileName) =
files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName)
member __.FileDelete(fileName) =
defaultFileSystem.FileDelete(fileName)
......@@ -78,6 +86,7 @@ let B = File1.A + File1.A"""
// and for F# interactive.
member __.AssemblyLoadFrom(fileName) =
defaultFileSystem.AssemblyLoadFrom fileName
member __.AssemblyLoad(assemblyName) =
defaultFileSystem.AssemblyLoad assemblyName
......@@ -131,7 +140,11 @@ let projectOptions =
yield "-r:" + r |]
{ ProjectFileName = @"c:\mycode\compilation.fsproj" // Make a name that is unique in this directory.
ProjectFileNames = [| fileName1; fileName2 |]
ProjectId = None
SourceFiles = [| fileName1; fileName2 |]
OriginalLoadReferences = []
ExtraProjectInfo=None
Stamp = None
OtherOptions = allFlags
ReferencedProjects = [| |]
IsIncompleteTypeCheckEnvironment = false
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Interactive Service: Embedding F# Interactive
=============================================
......@@ -211,7 +211,9 @@ fsiSession.EvalInteraction "let xxx = 1 + 1"
Now you want to typecheck the partially complete code `xxx + xx`
*)
let parseResults, checkResults, checkProjectResults = fsiSession.ParseAndCheckInteraction("xxx + xx")
let parseResults, checkResults, checkProjectResults =
fsiSession.ParseAndCheckInteraction("xxx + xx")
|> Async.RunSynchronously
(**
The `parseResults` and `checkResults` have types `ParseFileResults` and `CheckFileResults`
......@@ -228,7 +230,7 @@ You can also request declaration list information, tooltip text and symbol resol
open FSharp.Compiler
// get a tooltip
checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT)
checkResults.GetToolTipText(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT)
checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // symbol xxx
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラの組み込み
====================
......@@ -18,10 +18,10 @@
*)
#r "FSharp.Compiler.Service.dll"
open FSharp.Compiler.SimpleSourceCodeServices
open FSharp.Compiler.SourceCodeServices
open System.IO
let scs = SimpleSourceCodeServices()
let scs = FSharpChecker.Create()
(**
次に、一時ファイルへコンテンツを書き込みます:
......@@ -44,7 +44,7 @@ let x = 3 + 4
そしてコンパイラを呼び出します:
*)
let errors1, exitCode1 = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
let errors1, exitCode1 = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) |> Async.RunSynchronously
(**
......@@ -57,7 +57,7 @@ module M
let x = 1.0 + "" // a type error
""")
let errors1b, exitCode1b = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |])
let errors1b, exitCode1b = scs.Compile([| "fsc.exe"; "-o"; fn3; "-a"; fn2 |]) |> Async.RunSynchronously
if exitCode1b <> 0 then
errors1b
......@@ -79,11 +79,11 @@ if exitCode1b <> 0 then
'execute' 引数に 'None' を指定するとアセンブリ用の初期化コードが実行されません。
*)
let errors2, exitCode2, dynAssembly2 =
scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None)
scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], execute=None) |> Async.RunSynchronously
(**
'Some' を指定するとアセンブリ用の初期化コードが実行されます。
*)
let errors3, exitCode3, dynAssembly3 =
scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr))
scs.CompileToDynamicAssembly([| "-o"; fn3; "-a"; fn2 |], Some(stdout,stderr)) |> Async.RunSynchronously
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラサービス: FSharp.Core.dll についてのメモ
==================================================
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラサービス: エディタサービス
====================================
......@@ -44,7 +44,7 @@ let checker = FSharpChecker.Create()
*)
// サンプルの入力となる複数行文字列
let input =
"""
"""
open System
let foo() =
......@@ -56,9 +56,9 @@ printfn "%s" msg.
let inputLines = input.Split('\n')
let file = "/home/user/Test.fsx"
let projOptions = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously
let projOptions, _errors1 = checker.GetProjectOptionsFromScript(file, input) |> Async.RunSynchronously
let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOptions)
let parsingOptions, _errors2 = checker.GetParsingOptionsFromProjectOptions(projOptions)
(**
......@@ -73,8 +73,8 @@ let parsingOptions, _errors = checker.GetParsingOptionsFromProjectOptions(projOp
*)
// パースを実行
let parseFileResults =
checker.ParseFile(file, input, parsingOptions)
|> Async.RunSynchronously
checker.ParseFile(file, input, parsingOptions)
|> Async.RunSynchronously
(**
`TypeCheckResults` に備えられた興味深い機能の紹介に入る前に、
サンプル入力に対して型チェッカーを実行する必要があります。
......@@ -84,25 +84,25 @@ F#コードにエラーがあった場合も何らかの型チェックの結果
// 型チェックを実行
let checkFileAnswer =
checker.CheckFileInProject(parseFileResults, file, 0, input, projOptions)
|> Async.RunSynchronously
checker.CheckFileInProject(parseFileResults, file, 0, input, projOptions)
|> Async.RunSynchronously
(**
あるいは `ParseAndCheckFileInProject` を使用すれば1つの操作で両方のチェックを行うことができます:
*)
let parseResults2, checkFileAnswer2 =
checker.ParseAndCheckFileInProject(file, 0, input, projOptions)
|> Async.RunSynchronously
checker.ParseAndCheckFileInProject(file, 0, input, projOptions)
|> Async.RunSynchronously
(**
この返り値は `CheckFileAnswer` 型で、この型に機能的に興味深いものが揃えられています...
*)
let checkFileResults =
match checkFileAnswer with
| FSharpCheckFileAnswer.Succeeded(res) -> res
| res -> failwithf "パースが完了していません... (%A)" res
match checkFileAnswer with
| FSharpCheckFileAnswer.Succeeded(res) -> res
| res -> failwithf "パースが完了していません... (%A)" res
(**
......@@ -138,10 +138,9 @@ match checkFileAnswer with
*)
// 最後の引数に指定する、IDENTトークンのタグを取得
open FSharp.Compiler
let identToken = Parser.tagOfToken(Parser.token.IDENT(""))
// 特定の位置におけるツールチップを取得
let tip = checkFileResults.GetToolTipTextAlternate(4, 7, inputLines.[1], ["foo"], identToken)
let tip = checkFileResults.GetToolTipText(4, 7, inputLines.[1], ["foo"], FSharpTokenTag.Identifier)
printfn "%A" tip
(**
......@@ -178,13 +177,13 @@ printfn "%A" tip
*)
// 特定の位置における宣言(自動補完)を取得する
let decls =
checkFileResults.GetDeclarationListInfo
(Some parseFileResults, 7, 23, inputLines.[6], [], "msg", fun _ -> false)
|> Async.RunSynchronously
checkFileResults.GetDeclarationListInfo
(Some parseFileResults, 7, inputLines.[6], PartialLongName.Empty 23, (fun _ -> []), fun _ -> false)
|> Async.RunSynchronously
// 利用可能な項目を表示
for item in decls.Items do
printfn " - %s" item.Name
printfn " - %s" item.Name
(**
> **注意:** `GetDeclarationListInfo` は古い関数 `GetDeclarations` に代わるものです。
......@@ -214,13 +213,13 @@ printfn " - %s" item.Name
*)
//String.Concatメソッドのオーバーロードを取得する
let methods =
checkFileResults.GetMethodsAlternate(5, 27, inputLines.[4], Some ["String"; "Concat"]) |> Async.RunSynchronously
checkFileResults.GetMethods(5, 27, inputLines.[4], Some ["String"; "Concat"]) |> Async.RunSynchronously
// 連結された引数リストを表示
for mi in methods.Methods do
[ for p in mi.Parameters -> p.Display ]
|> String.concat ", "
|> printfn "%s(%s)" methods.MethodName
[ for p in mi.Parameters -> p.Display ]
|> String.concat ", "
|> printfn "%s(%s)" methods.MethodName
(**
ここでは `Display` プロパティを使用することで各引数に対する
アノテーションを取得しています。
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラサービス: ファイルシステム仮想化
==========================================
......@@ -48,6 +48,9 @@ let B = File1.A + File1.A"""
member __.FileStreamCreateShim(fileName) =
defaultFileSystem.FileStreamCreateShim(fileName)
member __.IsStableFileHeuristic(fileName) =
defaultFileSystem.IsStableFileHeuristic(fileName)
member __.FileStreamWriteExistingShim(fileName) =
defaultFileSystem.FileStreamWriteExistingShim(fileName)
......@@ -59,18 +62,23 @@ let B = File1.A + File1.A"""
// 一時パスおよびファイルのタイムスタンプに関連する機能を実装
member __.GetTempPathShim() =
defaultFileSystem.GetTempPathShim()
member __.GetLastWriteTimeShim(fileName) =
defaultFileSystem.GetLastWriteTimeShim(fileName)
member __.GetFullPathShim(fileName) =
defaultFileSystem.GetFullPathShim(fileName)
member __.IsInvalidPathShim(fileName) =
defaultFileSystem.IsInvalidPathShim(fileName)
member __.IsPathRootedShim(fileName) =
defaultFileSystem.IsPathRootedShim(fileName)
// ファイルの存在確認および削除に関連する機能を実装
member __.SafeExists(fileName) =
files.ContainsKey(fileName) || defaultFileSystem.SafeExists(fileName)
member __.FileDelete(fileName) =
defaultFileSystem.FileDelete(fileName)
......@@ -78,6 +86,7 @@ let B = File1.A + File1.A"""
// 型プロバイダやF# Interactiveで使用される。
member __.AssemblyLoadFrom(fileName) =
defaultFileSystem.AssemblyLoadFrom fileName
member __.AssemblyLoad(assemblyName) =
defaultFileSystem.AssemblyLoad assemblyName
......@@ -114,7 +123,11 @@ let projectOptions =
yield "-r:" + r |]
{ ProjectFileName = @"c:\mycode\compilation.fsproj" // 現在のディレクトリで一意な名前を指定
ProjectFileNames = [| fileName1; fileName2 |]
ProjectId = None
SourceFiles = [| fileName1; fileName2 |]
OriginalLoadReferences = []
ExtraProjectInfo=None
Stamp = None
OtherOptions = allFlags
ReferencedProjects=[| |]
IsIncompleteTypeCheckEnvironment = false
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
インタラクティブサービス: F# Interactiveの組み込み
==================================================
......@@ -226,7 +226,8 @@ fsiSession.EvalInteraction "let xxx = 1 + 1"
次に部分的に完全な `xxx + xx` というコードの型チェックを実行したいとします:
*)
let parseResults, checkResults, checkProjectResults = fsiSession.ParseAndCheckInteraction("xxx + xx")
let parseResults, checkResults, checkProjectResults =
fsiSession.ParseAndCheckInteraction("xxx + xx") |> Async.RunSynchronously
(**
`parseResults` と `checkResults` はそれぞれ [エディタ](editor.html)
......@@ -246,7 +247,7 @@ checkResults.Errors.Length // 1
open FSharp.Compiler
// ツールチップを取得する
checkResults.GetToolTipTextAlternate(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT)
checkResults.GetToolTipText(1, 2, "xxx + xx", ["xxx"], FSharpTokenTag.IDENT)
checkResults.GetSymbolUseAtLocation(1, 2, "xxx + xx", ["xxx"]) // シンボル xxx
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラサービス: プロジェクトの分析
======================================
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラサービス: シンボルの処理
==================================
......@@ -34,7 +34,7 @@ let checker = FSharpChecker.Create()
let parseAndTypeCheckSingleFile (file, input) =
// スタンドアロンの(スクリプト)ファイルを表すコンテキストを取得
let projOptions =
let projOptions, _errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......@@ -113,8 +113,8 @@ fnVal.CurriedParameterGroups.[0].[0].Name // "x"
fnVal.CurriedParameterGroups.[0].[1].Name // "y"
fnVal.DeclarationLocation.StartLine // 3
fnVal.DisplayName // "foo"
fnVal.DeclaringEntity.DisplayName // "Test"
fnVal.DeclaringEntity.DeclarationLocation.StartLine // 1
fnVal.DeclaringEntity.Value.DisplayName // "Test"
fnVal.DeclaringEntity.Value.DeclarationLocation.StartLine // 1
fnVal.GenericParameters.Count // 0
fnVal.InlineAnnotation // FSharpInlineAnnotation.OptionalInline
fnVal.IsActivePattern // false
......@@ -203,7 +203,7 @@ for assembly in projectContext.GetReferencedAssemblies() do
構成することもできます。
*)
let parseAndCheckScript (file, input) =
let projOptions =
let projOptions, errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラサービス:F#トークナイザを使用する
============================================
......@@ -124,7 +124,7 @@ let rec tokenizeLines state count lines =
*)
lines
|> List.ofSeq
|> tokenizeLines 0L 1
|> tokenizeLines FSharpTokenizerLexState.Initial 1
(**
重要ではない部分(各行の先頭にある空白文字や、1行目のように空白文字しかない行)
を除けば、このコードを実行すると以下のような出力になります:
......
(*** hide ***)
#I "../../../../debug/bin/net45/"
#I "../../../../artifacts/bin/fcs/net45"
(**
コンパイラサービス:型無し構文木の処理
======================================
......@@ -69,7 +69,7 @@ ASTを取得するために、ファイル名とソースコードを受け取
let getUntypedTree (file, input) =
// 1つのスクリプトファイルから推測される「プロジェクト」用の
// コンパイラオプションを取得する
let projectOptions =
let projOptions, errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Project Analysis
==================================
......@@ -306,22 +306,27 @@ correctly and then analyze each project in turn.
*)
(**
Cracking a project file
Cracking a legacy project file
-----------------------------
F# projects normally use the '.fsproj' project file format.
A project cracking facility is provided as a separate NuGet package:
FSharp.Compiler.Service.ProjectCracker. This NuGet package contains a
library FSharp.Compiler.Service.ProjectCracker.dll, which should be
A project cracking facility for legacy old-style .fsproj is provided as a separate NuGet package:
FSharp.Compiler.Service.ProjectCracker.
Projecet cracking for modern project files should be done using a library such as DotNetProjInfo.
See FsAutoComplete for example code.
The legacy NuGet package `FSharp.Compiler.Service.ProjectCracker` contains a
library `FSharp.Compiler.Service.ProjectCracker.dll`, which should be
referenced by your application directly, and an executable
FSharp.Compiler.Service.ProjectCrackerTool.exe, which should be copied
`FSharp.Compiler.Service.ProjectCrackerTool.exe`, which should be copied
into the output folder of your application by the build process. If
you install using Paket or NuGet, then this will be configured for you
automatically. If not, you should reference the provided `.targets`
file manually in your application. This can be found in the NuGet
package at `build/net45/FSharp.Compiler.Service.ProjectCrackerTool.targets`.
The reason for this split is so that the analysis of an F# project
The reason for this split was so the analysis of an F# project
file is performed out of process, in order that the necessary assembly
binding redirects can be applied without requiring the caller to
arrange this. In this way MSBuild versions from 4 up to 14 can be
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Notes on the FSharpChecker operations queue
=================================================
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Reacting to Changes
============================================
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Working with symbols
============================================
......@@ -31,7 +31,7 @@ We now perform type checking on the specified input:
let parseAndTypeCheckSingleFile (file, input) =
// Get context representing a stand-alone (script) file
let projOptions =
let projOptions, errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......@@ -109,8 +109,8 @@ fnVal.CurriedParameterGroups.[0].[0].Name // "x"
fnVal.CurriedParameterGroups.[0].[1].Name // "y"
fnVal.DeclarationLocation.StartLine // 3
fnVal.DisplayName // "foo"
fnVal.DeclaringEntity.DisplayName // "Test"
fnVal.DeclaringEntity.DeclarationLocation.StartLine // 1
fnVal.DeclaringEntity.Value.DisplayName // "Test"
fnVal.DeclaringEntity.Value.DeclarationLocation.StartLine // 1
fnVal.GenericParameters.Count // 0
fnVal.InlineAnnotation // FSharpInlineAnnotation.OptionalInline
fnVal.IsActivePattern // false
......@@ -193,7 +193,7 @@ the project for a single script. By specifying a different "projOptions" you can
a specification of a larger project.
*)
let parseAndCheckScript (file, input) =
let projOptions =
let projOptions, errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Using the F# tokenizer
=========================================
......@@ -111,7 +111,7 @@ state and `1` as the number of the first line:
*)
lines
|> List.ofSeq
|> tokenizeLines 0L 1
|> tokenizeLines FSharpTokenizerLexState.Initial 1
(**
Ignoring some unimportant details (like whitespace at the beginning of each line and
the first line which is just whitespace), the code generates the following output:
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Processing typed expression tree
=================================================
......@@ -41,7 +41,7 @@ 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 =
let projOptions, _errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......@@ -203,6 +203,8 @@ let rec visitExpr f (e:FSharpExpr) =
visitExprs f argExprs
| BasicPatterns.NewRecord(recordType, argExprs) ->
visitExprs f argExprs
| BasicPatterns.NewAnonRecord(recordType, argExprs) ->
visitExprs f argExprs
| BasicPatterns.NewTuple(tupleType, argExprs) ->
visitExprs f argExprs
| BasicPatterns.NewUnionCase(unionType, unionCase, argExprs) ->
......@@ -211,6 +213,8 @@ let rec visitExpr f (e:FSharpExpr) =
visitExpr f quotedExpr
| BasicPatterns.FSharpFieldGet(objExprOpt, recordOrClassType, fieldInfo) ->
visitObjArg f objExprOpt
| BasicPatterns.AnonRecordGet(objExpr, recordOrClassType, fieldInfo) ->
visitExpr f objExpr
| BasicPatterns.FSharpFieldSet(objExprOpt, recordOrClassType, fieldInfo, argExpr) ->
visitObjArg f objExprOpt; visitExpr f argExpr
| BasicPatterns.Sequential(firstExpr, secondExpr) ->
......
(*** hide ***)
#I "../../bin/v4.5/"
#I "../../../artifacts/bin/fcs/net45"
(**
Compiler Services: Processing untyped syntax tree
=================================================
......@@ -56,7 +56,7 @@ return the `ParseTree` property:
/// Get untyped tree for a specified input
let getUntypedTree (file, input) =
// Get compiler options for the 'project' implied by a single script file
let projOptions =
let projOptions, errors =
checker.GetProjectOptionsFromScript(file, input)
|> Async.RunSynchronously
......
......@@ -51,8 +51,11 @@ module ExprTranslationImpl =
member env.BindSubstVal v e =
{ env with substVals = env.substVals.Add v e }
member env.BindVals vs = (env, vs) ||> List.fold (fun env v -> env.BindVal v)
member env.BindCurriedVals vsl = (env, vsl) ||> List.fold (fun env vs -> env.BindVals vs)
member env.BindVals vs =
(env, vs) ||> List.fold (fun env v -> env.BindVal v)
member env.BindCurriedVals vsl =
(env, vsl) ||> List.fold (fun env vs -> env.BindVals vs)
exception IgnoringPartOfQuotedTermWarning of string * Range.range
......@@ -81,6 +84,8 @@ type E =
| FSharpFieldGet of FSharpExpr option * FSharpType * FSharpField
| FSharpFieldSet of FSharpExpr option * FSharpType * FSharpField * FSharpExpr
| NewUnionCase of FSharpType * FSharpUnionCase * FSharpExpr list
| NewAnonRecord of FSharpType * FSharpExpr list
| AnonRecordGet of FSharpExpr * FSharpType * int
| UnionCaseGet of FSharpExpr * FSharpType * FSharpUnionCase * FSharpField
| UnionCaseSet of FSharpExpr * FSharpType * FSharpUnionCase * FSharpField * FSharpExpr
| UnionCaseTag of FSharpExpr * FSharpType
......@@ -134,6 +139,8 @@ and [<Sealed>] FSharpExpr (cenv, f: (unit -> FSharpExpr) option, e: E, m:range,
| E.Let ((_bindingVar, bindingExpr), b) -> [bindingExpr;b]
| E.LetRec (ves, b) -> (List.map snd ves) @ [b]
| E.NewRecord (_recordType, es) -> es
| E.NewAnonRecord (_recordType, es) -> es
| E.AnonRecordGet (e, _recordType, _n) -> [e]
| E.NewUnionCase (_unionType, _unionCase, es) -> es
| E.NewTuple (_tupleType, es) -> es
| E.TupleGet (_tupleType, _itemIndex, tupleExpr) -> [tupleExpr]
......@@ -559,6 +566,11 @@ module FSharpExprConvert =
let argsR = ConvExprs cenv env args
E.NewUnionCase(typR, mkR, argsR)
| TOp.AnonRecd anonInfo, _, _ ->
let typR = ConvType cenv (mkAnyAnonRecdTy cenv.g anonInfo tyargs)
let argsR = ConvExprs cenv env args
E.NewAnonRecord(typR, argsR)
| TOp.Tuple tupInfo, tyargs, _ ->
let tyR = ConvType cenv (mkAnyTupledTy cenv.g tupInfo tyargs)
let argsR = ConvExprs cenv env args
......@@ -575,6 +587,10 @@ module FSharpExprConvert =
let projR = FSharpField(cenv, ucref, n)
E.UnionCaseGet(ConvExpr cenv env e1, typR, mkR, projR)
| TOp.AnonRecdGet (anonInfo, n), tyargs, [e1] ->
let typR = ConvType cenv (mkAnyAnonRecdTy cenv.g anonInfo tyargs)
E.AnonRecordGet(ConvExpr cenv env e1, typR, n)
| TOp.UnionCaseFieldSet (ucref, n), tyargs, [e1;e2] ->
let mkR = ConvUnionCaseRef cenv ucref
let typR = ConvType cenv (mkAppTy ucref.TyconRef tyargs)
......@@ -1277,12 +1293,14 @@ module BasicPatterns =
let (|Let|_|) (e:FSharpExpr) = match e.E with E.Let ((v, e), b) -> Some ((v, e), b) | _ -> None
let (|LetRec|_|) (e:FSharpExpr) = match e.E with E.LetRec (ves, b) -> Some (ves, b) | _ -> None
let (|NewRecord|_|) (e:FSharpExpr) = match e.E with E.NewRecord (ty, es) -> Some (ty, es) | _ -> None
let (|NewAnonRecord|_|) (e:FSharpExpr) = match e.E with E.NewAnonRecord (ty, es) -> Some (ty, es) | _ -> None
let (|NewUnionCase|_|) (e:FSharpExpr) = match e.E with E.NewUnionCase (e, tys, es) -> Some (e, tys, es) | _ -> None
let (|NewTuple|_|) (e:FSharpExpr) = match e.E with E.NewTuple (ty, es) -> Some (ty, es) | _ -> None
let (|TupleGet|_|) (e:FSharpExpr) = match e.E with E.TupleGet (ty, n, es) -> Some (ty, n, es) | _ -> None
let (|Call|_|) (e:FSharpExpr) = match e.E with E.Call (a, b, c, d, e) -> Some (a, b, c, d, e) | _ -> None
let (|NewObject|_|) (e:FSharpExpr) = match e.E with E.NewObject (a, b, c) -> Some (a, b, c) | _ -> None
let (|FSharpFieldGet|_|) (e:FSharpExpr) = match e.E with E.FSharpFieldGet (a, b, c) -> Some (a, b, c) | _ -> None
let (|AnonRecordGet|_|) (e:FSharpExpr) = match e.E with E.AnonRecordGet (a, b, c) -> Some (a, b, c) | _ -> None
let (|FSharpFieldSet|_|) (e:FSharpExpr) = match e.E with E.FSharpFieldSet (a, b, c, d) -> Some (a, b, c, d) | _ -> None
let (|UnionCaseGet|_|) (e:FSharpExpr) = match e.E with E.UnionCaseGet (a, b, c, d) -> Some (a, b, c, d) | _ -> None
let (|UnionCaseTag|_|) (e:FSharpExpr) = match e.E with E.UnionCaseTag (a, b) -> Some (a, b) | _ -> None
......
......@@ -127,6 +127,13 @@ module public BasicPatterns =
/// Matches record expressions
val (|NewRecord|_|) : FSharpExpr -> (FSharpType * FSharpExpr list) option
/// Matches anonymous record expressions
val (|NewAnonRecord|_|) : FSharpExpr -> (FSharpType * FSharpExpr list) option
/// Matches expressions getting a field from an anonymous record. The integer represents the
/// index into the sorted fields of the anonymous record.
val (|AnonRecordGet|_|) : FSharpExpr -> (FSharpExpr * FSharpType * int) option
/// Matches expressions which get a field from a record or class
val (|FSharpFieldGet|_|) : FSharpExpr -> (FSharpExpr option * FSharpType * FSharpField) option
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......

#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../bin/v4.5/CSharp_Analysis.dll"
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
......@@ -19,8 +19,8 @@
// Use F# Interactive. This only works for FSHarp.Compiler.Service.dll which has a public API
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......

#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../debug/fcs/net45/FSharp.Compiler.Service.ProjectCracker.dll"
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.ProjectCracker.dll"
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......@@ -49,10 +49,14 @@ module internal Utils =
| BasicPatterns.NewRecord(v,args) ->
let fields = v.TypeDefinition.FSharpFields
"{" + ((fields, args) ||> Seq.map2 (fun f a -> f.Name + " = " + printExpr 0 a) |> String.concat "; ") + "}"
| BasicPatterns.NewAnonRecord(v,args) ->
let fields = v.AnonRecordTypeDetails.SortedFieldNames
"{" + ((fields, args) ||> Seq.map2 (fun f a -> f+ " = " + printExpr 0 a) |> String.concat "; ") + "}"
| BasicPatterns.NewTuple(v,args) -> printTupledArgs args
| BasicPatterns.NewUnionCase(ty,uc,args) -> uc.CompiledName + printTupledArgs args
| BasicPatterns.Quote(e1) -> "quote" + printTupledArgs [e1]
| BasicPatterns.FSharpFieldGet(obj, ty,f) -> printObjOpt obj + f.Name
| BasicPatterns.AnonRecordGet(obj, ty, n) -> printExpr 0 obj + "." + ty.AnonRecordTypeDetails.SortedFieldNames.[n]
| BasicPatterns.FSharpFieldSet(obj, ty,f,arg) -> printObjOpt obj + f.Name + " <- " + printExpr 0 arg
| BasicPatterns.Sequential(e1,e2) -> "(" + printExpr 0 e1 + "; " + printExpr 0 e2 + ")"
| BasicPatterns.ThisValue _ -> "this"
......@@ -535,6 +539,8 @@ module LetLambda =
let letLambdaRes = [ 1, 2 ] |> List.map (fun (a, b) -> LetLambda.f a b)
let anonRecd = {| X = 1; Y = 2 |}
let anonRecdGet = (anonRecd.X, anonRecd.Y)
"""
File.WriteAllText(fileName1, fileSource1)
......@@ -732,6 +738,8 @@ let ``Test Unoptimized Declarations Project1`` () =
"type LetLambda";
"let f = ((); fun a -> fun b -> Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (a,b)) @ (246,8--247,24)";
"let letLambdaRes = Operators.op_PipeRight<(Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int) Microsoft.FSharp.Collections.list,Microsoft.FSharp.Core.int Microsoft.FSharp.Collections.list> (Cons((1,2),Empty()),let mapping: Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int -> Microsoft.FSharp.Core.int = fun tupledArg -> let a: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b: Microsoft.FSharp.Core.int = tupledArg.Item1 in (LetLambda.f () a) b in fun list -> ListModule.Map<Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (mapping,list)) @ (249,19--249,71)";
"let anonRecd = {X = 1; Y = 2} @ (251,15--251,33)"
"let anonRecdGet = (M.anonRecd ().X,M.anonRecd ().Y) @ (252,19--252,41)"
]
let expected2 = [
......@@ -870,6 +878,8 @@ let ``Test Optimized Declarations Project1`` () =
"type LetLambda";
"let f = fun a -> fun b -> Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (a,b) @ (247,8--247,24)";
"let letLambdaRes = ListModule.Map<Microsoft.FSharp.Core.int * Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (fun tupledArg -> let a: Microsoft.FSharp.Core.int = tupledArg.Item0 in let b: Microsoft.FSharp.Core.int = tupledArg.Item1 in (LetLambda.f () a) b,Cons((1,2),Empty())) @ (249,19--249,71)";
"let anonRecd = {X = 1; Y = 2} @ (251,15--251,33)"
"let anonRecdGet = (M.anonRecd ().X,M.anonRecd ().Y) @ (252,19--252,41)"
]
let expected2 = [
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......

#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......

#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......

#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../debug/fcs/net45/FSharp.Compiler.Service.ProjectCracker.dll"
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.ProjectCracker.dll"
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......

#if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#r "../../artifacts/bin/fcs/net46/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net46/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
......
......@@ -86,11 +86,9 @@
<Compile Include="..\..\..\tests\service\InteractiveCheckerTests.fs">
<Link>CompilerService\InteractiveCheckerTests.fs</Link>
</Compile>
<!-- TODO: Fix this test
<Compile Include="..\..\..\tests\service\ExprTests.fs">
<Link>CompilerService\ExprTests.fs</Link>
</Compile>
-->
<Compile Include="..\..\..\tests\service\CSharpProjectAnalysis.fs">
<Link>CompilerService\CSharpProjectAnalysis.fs</Link>
</Compile>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册