cross-platform wrapper around memory-backed memorymappedfile creation (#8403)

* cross-platform wrapper around memory-backed memorymappedfile creation

* reenable FCS tests on non-windows platforms

* publish test results on non-windows platforms

* ensure correct .net sdk versions are installed regardless of VM image preloads

* simple workaround for missing mscorlib versions to TFMs

* publish per-framework xml results and report them in AZDO

* rework mono fixes to use ByteArrayMemory directly

* move runningOnMono call to bytes.fs and patch up callsites

* revert to build-only on mono-containing platforms

another MR will be required to fix the underlying logic before those can be changed to run tests again

* trigger ci
This commit is contained in:
Chet Husk 2020-02-05 09:44:55 -06:00 коммит произвёл GitHub
Родитель e71fd0365e
Коммит ff20f70d4d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
22 изменённых файлов: 214 добавлений и 115 удалений

Просмотреть файл

@ -342,6 +342,11 @@ stages:
steps:
- checkout: self
clean: true
- task: UseDotNet@2
displayName: 'Use .NET Core sdk'
inputs:
useGlobalJson: true
workingDirectory: fcs
- script: fcs\build.cmd TestAndNuget
displayName: Build / Test
- task: PublishTestResults@2
@ -350,6 +355,7 @@ stages:
testResultsFormat: 'NUnit'
testResultsFiles: '*.xml'
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/Release'
publishRunAttachments: true
continueOnError: true
condition: always()
@ -362,20 +368,48 @@ stages:
steps:
- checkout: self
clean: true
- task: UseDotNet@2
displayName: 'Use .NET Core sdk'
inputs:
useGlobalJson: true
workingDirectory: fcs
- script: ./fcs/build.sh
displayName: Build
displayName: Build / Test
- task: PublishTestResults@2
displayName: Publish Test Results
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '*.xml'
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/Release'
publishRunAttachments: true
continueOnError: true
condition: always()
# - job: MacOS_FCS
# pool:
# vmImage: macOS-latest
# variables:
# - name: _SignType
# value: Test
# steps:
# - checkout: self
# clean: true
# - script: ./fcs/build.sh
# displayName: Build
- job: MacOS_FCS
pool:
vmImage: macOS-latest
variables:
- name: _SignType
value: Test
steps:
- checkout: self
clean: true
- task: UseDotNet@2
displayName: 'Use .NET Core sdk'
inputs:
useGlobalJson: true
workingDirectory: fcs
- script: ./fcs/build.sh
displayName: Build / Test
- task: PublishTestResults@2
displayName: Publish Test Results
inputs:
testResultsFormat: 'NUnit'
testResultsFiles: '*.xml'
searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/Release'
publishRunAttachments: true
continueOnError: true
condition: always()
#---------------------------------------------------------------------------------------------------------------------#
# Post Build #

Просмотреть файл

@ -183,7 +183,7 @@
<NUnitVersion>3.11.0</NUnitVersion>
<NUnit3TestAdapterVersion>3.11.2</NUnit3TestAdapterVersion>
<NUnitLiteVersion>3.11.0</NUnitLiteVersion>
<NunitXmlTestLoggerVersion>2.1.36</NunitXmlTestLoggerVersion>
<NunitXmlTestLoggerVersion>2.1.41</NunitXmlTestLoggerVersion>
<RoslynToolsSignToolVersion>1.0.0-beta2-dev3</RoslynToolsSignToolVersion>
<StrawberryPerlVersion>5.28.0.1</StrawberryPerlVersion>
<StreamJsonRpcVersion>2.0.187</StreamJsonRpcVersion>

Просмотреть файл

@ -1,5 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\netfx.props" />
<Import Project="..\..\eng\Versions.props"/> <!-- keep our test deps in line with the overall compiler -->
<PropertyGroup>
<TargetFrameworks>$(FcsTargetNetFxFramework);netcoreapp3.0</TargetFrameworks>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
@ -60,6 +61,9 @@
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\TreeVisitorTests.fs">
<Link>TreeVisitorTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\ScriptOptionsTests.fs">
<Link>ScriptOptionsTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\Program.fs" Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<Link>Program.fs</Link>
</Compile>
@ -71,10 +75,10 @@
<ItemGroup>
<PackageReference Include="FSharp.Core" Version="$(FcsFSharpCorePkgVersion)" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
<PackageReference Include="NUnit" Version="3.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
<PackageReference Include="NunitXml.TestLogger" Version="2.1.36" />
<PackageReference Include="Dotnet.ProjInfo" Version="0.20.0" />
<PackageReference Include="NUnit" Version="$(NUnitVersion)" />
<PackageReference Include="NUnit3TestAdapter" Version="$(NUnit3TestAdapterVersion)" />
<PackageReference Include="NunitXml.TestLogger" Version="$(NunitXmlTestLoggerVersion)" />
<ProjectReference Include="..\FSharp.Compiler.Service\FSharp.Compiler.Service.fsproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(FcsTargetNetFxFramework)'">

Просмотреть файл

@ -73,9 +73,9 @@ Target.create "Test" (fun _ ->
// This project file is used for the netcoreapp2.0 tests to work out reference sets
runDotnet __SOURCE_DIRECTORY__ "build" "../tests/projects/Sample_NETCoreSDK_FSharp_Library_netstandard2_0/Sample_NETCoreSDK_FSharp_Library_netstandard2_0.fsproj -nodereuse:false -v n /restore /p:DisableCompilerRedirection=true"
// Now run the tests
let logFilePath = Path.Combine(__SOURCE_DIRECTORY__, "..", "artifacts", "TestResults", "Release", "FSharp.Compiler.Service.Test.xml")
runDotnet __SOURCE_DIRECTORY__ "test" (sprintf "FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj --no-restore --no-build -nodereuse:false -v n -c Release --test-adapter-path . --logger \"nunit;LogFilePath=%s\"" logFilePath)
// Now run the tests (different output files per TFM)
let logFilePath = Path.Combine(__SOURCE_DIRECTORY__, "..", "artifacts", "TestResults", "Release", "FSharp.Compiler.Service.Test.{framework}.xml")
runDotnet __SOURCE_DIRECTORY__ "test" (sprintf "FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj --no-restore --no-build -nodereuse:false -v n -c Release --logger \"nunit;LogFilePath=%s\"" logFilePath)
)
Target.create "NuGet" (fun _ ->

Просмотреть файл

@ -8,7 +8,7 @@ open System.IO
open System.Reflection
open System.Runtime.CompilerServices
open FSharp.Compiler.SourceCodeServices
open FSharp.Compiler.AbstractIL.IL // runningOnMono
open FSharp.Compiler.AbstractIL.Internal.Utils // runningOnMono
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.ErrorLogger

Просмотреть файл

@ -12,6 +12,25 @@ open FSharp.NativeInterop
#nowarn "9"
module Utils =
let runningOnMono =
#if ENABLE_MONO_SUPPORT
// Officially supported way to detect if we are running on Mono.
// See http://www.mono-project.com/FAQ:_Technical
// "How can I detect if am running in Mono?" section
try
System.Type.GetType ("Mono.Runtime") <> null
with _ ->
// Must be robust in the case that someone else has installed a handler into System.AppDomain.OnTypeResolveEvent
// that is not reliable.
// This is related to bug 5506--the issue is actually a bug in VSTypeResolutionService.EnsurePopulated which is
// called by OnTypeResolveEvent. The function throws a NullReferenceException. I'm working with that team to get
// their issue fixed but we need to be robust here anyway.
false
#else
false
#endif
module internal Bytes =
let b0 n = (n &&& 0xFF)
let b1 n = ((n >>> 8) &&& 0xFF)
@ -296,65 +315,72 @@ type ByteMemory with
member x.AsReadOnly() = ReadOnlyByteMemory x
static member CreateMemoryMappedFile(bytes: ReadOnlyByteMemory) =
let length = int64 bytes.Length
let mmf =
if Utils.runningOnMono
then
// mono's MemoryMappedFile implementation throws with null `mapName`, so we use byte arrays instead: https://github.com/mono/mono/issues/10245
ByteArrayMemory.FromArray (bytes.ToArray()) :> ByteMemory
else
let length = int64 bytes.Length
let mmf =
MemoryMappedFile.CreateNew(
null,
length,
MemoryMappedFileAccess.ReadWrite,
MemoryMappedFileOptions.None,
HandleInheritability.None)
use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite)
bytes.CopyTo stream
mmf
let mmf = MemoryMappedFile.CreateNew(null, length, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.None, HandleInheritability.None)
use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite)
bytes.CopyTo stream
mmf
let accessor = mmf.CreateViewAccessor(0L, length, MemoryMappedFileAccess.ReadWrite)
RawByteMemory.FromUnsafePointer(accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int length, (mmf, accessor))
let accessor = mmf.CreateViewAccessor(0L, length, MemoryMappedFileAccess.ReadWrite)
RawByteMemory.FromUnsafePointer(accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int length, (mmf, accessor))
static member FromFile(path, access, ?canShadowCopy: bool) =
let canShadowCopy = defaultArg canShadowCopy false
let memoryMappedFileAccess =
match access with
| FileAccess.Read -> MemoryMappedFileAccess.Read
| FileAccess.Write -> MemoryMappedFileAccess.Write
| _ -> MemoryMappedFileAccess.ReadWrite
if Utils.runningOnMono
then
// mono's MemoryMappedFile implementation throws with null `mapName`, so we use byte arrays instead: https://github.com/mono/mono/issues/10245
let bytes = File.ReadAllBytes path
ByteArrayMemory.FromArray bytes
else
let memoryMappedFileAccess =
match access with
| FileAccess.Read -> MemoryMappedFileAccess.Read
| FileAccess.Write -> MemoryMappedFileAccess.Write
| _ -> MemoryMappedFileAccess.ReadWrite
let mmf, accessor, length =
let fileStream = File.Open(path, FileMode.Open, access, FileShare.Read)
let length = fileStream.Length
let mmf =
if canShadowCopy then
let mmf =
MemoryMappedFile.CreateNew(
null,
length,
MemoryMappedFileAccess.ReadWrite,
MemoryMappedFileOptions.None,
HandleInheritability.None)
use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite)
fileStream.CopyTo(stream)
fileStream.Dispose()
mmf
else
MemoryMappedFile.CreateFromFile(
fileStream,
null,
length,
memoryMappedFileAccess,
HandleInheritability.None,
leaveOpen=false)
mmf, mmf.CreateViewAccessor(0L, length, memoryMappedFileAccess), length
// Validate MMF with the access that was intended.
match access with
| FileAccess.Read when not accessor.CanRead -> invalidOp "Cannot read file"
| FileAccess.Write when not accessor.CanWrite -> invalidOp "Cannot write file"
| FileAccess.ReadWrite when not accessor.CanRead || not accessor.CanWrite -> invalidOp "Cannot read or write file"
| _ -> ()
let mmf, accessor, length =
let mmf =
if canShadowCopy then
let mmf =
MemoryMappedFile.CreateNew(
null,
length,
MemoryMappedFileAccess.ReadWrite,
MemoryMappedFileOptions.None,
HandleInheritability.None)
use stream = mmf.CreateViewStream(0L, length, MemoryMappedFileAccess.ReadWrite)
fileStream.CopyTo(stream)
fileStream.Dispose()
mmf
else
MemoryMappedFile.CreateFromFile(
fileStream,
null,
length,
memoryMappedFileAccess,
HandleInheritability.None,
leaveOpen=false)
mmf, mmf.CreateViewAccessor(0L, length, memoryMappedFileAccess), length
RawByteMemory.FromUnsafePointer(accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int length, (mmf, accessor))
// Validate MMF with the access that was intended.
match access with
| FileAccess.Read when not accessor.CanRead -> invalidOp "Cannot read file"
| FileAccess.Write when not accessor.CanWrite -> invalidOp "Cannot write file"
| FileAccess.ReadWrite when not accessor.CanRead || not accessor.CanWrite -> invalidOp "Cannot read or write file"
| _ -> ()
RawByteMemory.FromUnsafePointer(accessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), int length, (mmf, accessor))
static member FromUnsafePointer(addr, length, holder: obj) =
RawByteMemory(NativePtr.ofNativeInt addr, length, holder) :> ByteMemory

Просмотреть файл

@ -5,10 +5,11 @@ namespace FSharp.Compiler.AbstractIL.Internal
open System.IO
open Internal.Utilities
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.Internal
module Utils =
val runningOnMono: bool
module internal Bytes =
/// returned int will be 0 <= x <= 255

Просмотреть файл

@ -25,24 +25,6 @@ open Internal.Utilities
let logging = false
let runningOnMono =
#if ENABLE_MONO_SUPPORT
// Officially supported way to detect if we are running on Mono.
// See http://www.mono-project.com/FAQ:_Technical
// "How can I detect if am running in Mono?" section
try
System.Type.GetType ("Mono.Runtime") <> null
with e->
// Must be robust in the case that someone else has installed a handler into System.AppDomain.OnTypeResolveEvent
// that is not reliable.
// This is related to bug 5506--the issue is actually a bug in VSTypeResolutionService.EnsurePopulated which is
// called by OnTypeResolveEvent. The function throws a NullReferenceException. I'm working with that team to get
// their issue fixed but we need to be robust here anyway.
false
#else
false
#endif
let _ = if logging then dprintn "* warning: Il.logging is on"
let int_order = LanguagePrimitives.FastGenericComparer<int>

Просмотреть файл

@ -2012,8 +2012,6 @@ type ILPropertyRef =
member Name: string
interface System.IComparable
val runningOnMono: bool
type ILReferences =
{ AssemblyReferences: ILAssemblyRef list
ModuleReferences: ILModuleRef list }

Просмотреть файл

@ -20,12 +20,13 @@ open System.Text
open Internal.Utilities
open Internal.Utilities.Collections
open FSharp.NativeInterop
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.Support
open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.BinaryConstants
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Support
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Range
open System.Reflection

Просмотреть файл

@ -17,6 +17,7 @@ open System.Collections.Generic
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.ErrorLogger

Просмотреть файл

@ -3,9 +3,9 @@
module internal FSharp.Compiler.AbstractIL.Internal.Support
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.NativeRes
open FSharp.Compiler.AbstractIL.Internal.Utils
#if FX_NO_CORHOST_SIGNER
open FSharp.Compiler.AbstractIL.Internal.StrongNameSign
#endif
@ -1287,7 +1287,7 @@ let getICLRStrongName () =
| Some sn -> sn
let signerGetPublicKeyForKeyPair kp =
if IL.runningOnMono then
if runningOnMono then
let snt = System.Type.GetType("Mono.Security.StrongName")
let sn = System.Activator.CreateInstance(snt, [| box kp |])
snt.InvokeMember("PublicKey", (BindingFlags.GetProperty ||| BindingFlags.Instance ||| BindingFlags.Public), null, sn, [| |], Globalization.CultureInfo.InvariantCulture) :?> byte[]
@ -1319,7 +1319,7 @@ let signerCloseKeyContainer kc =
iclrSN.StrongNameKeyDelete kc |> ignore
let signerSignatureSize (pk: byte[]) =
if IL.runningOnMono then
if runningOnMono then
if pk.Length > 32 then pk.Length - 32 else 128
else
let mutable pSize = 0u
@ -1328,7 +1328,7 @@ let signerSignatureSize (pk: byte[]) =
int pSize
let signerSignFileWithKeyPair fileName kp =
if IL.runningOnMono then
if runningOnMono then
let snt = System.Type.GetType("Mono.Security.StrongName")
let sn = System.Activator.CreateInstance(snt, [| box kp |])
let conv (x: obj) = if (unbox x: bool) then 0 else -1

Просмотреть файл

@ -6,12 +6,13 @@ open System.Collections.Generic
open System.IO
open Internal.Utilities
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.BinaryConstants
open FSharp.Compiler.AbstractIL.Internal.Support
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.BinaryConstants
open FSharp.Compiler.AbstractIL.Internal.Support
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.AbstractIL.ILPdbWriter
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Range

Просмотреть файл

@ -15,6 +15,7 @@ open Internal.Utilities
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Internal.Support
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.ErrorLogger
open FSharp.Compiler.Range
@ -244,7 +245,7 @@ let pdbGetDebugInfo (contentId: byte[]) (timestamp: int32) (filepath: string)
// This function takes output file name and returns debug file name.
let getDebugFileName outfile (portablePDB: bool) =
#if ENABLE_MONO_SUPPORT
if IL.runningOnMono && not portablePDB then
if runningOnMono && not portablePDB then
outfile + ".mdb"
else
#else

Просмотреть файл

@ -20,6 +20,7 @@ open FSharp.Compiler.AbstractIL.ILBinaryReader
open FSharp.Compiler.AbstractIL.ILPdbWriter
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.AbstractIL.Extensions.ILX
open FSharp.Compiler.AbstractIL.Diagnostics

Просмотреть файл

@ -8,10 +8,11 @@ open Internal.Utilities
open System
open System.IO
open FSharp.Compiler
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILPdbWriter
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.AbstractIL.Extensions.ILX
open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.CompileOps

Просмотреть файл

@ -115,13 +115,19 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies
let desktopProductVersionMonikers = [|
// major, minor, build, revision, moniker
4, 8, 3815, 0, "net48"
4, 8, 3761, 0, "net48"
4, 7, 3190, 0, "net472"
4, 7, 3062, 0, "net472"
4, 7, 2600, 0, "net471"
4, 7, 2558, 0, "net471"
4, 7, 2053, 0, "net47"
4, 7, 2046, 0, "net47"
4, 6, 1590, 0, "net462"
4, 6, 57, 0, "net462"
4, 6, 1055, 0, "net461"
4, 6, 81, 0, "net46"
4, 0, 30319, 34209, "net452"
4, 0, 30319, 17020, "net452"
4, 0, 30319, 18408, "net451"
4, 0, 30319, 17929, "net45"
4, 0, 30319, 1, "net4"
@ -138,14 +144,17 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies
with _ -> defaultMscorlibVersion
// Get the ProductVersion of this framework compare with table yield compatible monikers
let _, _, _, _, moniker =
desktopProductVersionMonikers
|> Array.find (fun (major, minor, build, revision, _) ->
(majorPart >= major) &&
(minorPart >= minor) &&
(buildPart >= build) &&
(privatePart >= revision))
moniker
match desktopProductVersionMonikers
|> Array.tryFind (fun (major, minor, build, revision, _) ->
(majorPart >= major) &&
(minorPart >= minor) &&
(buildPart >= build) &&
(privatePart >= revision)) with
| Some (_,_,_,_,moniker) ->
moniker
| None ->
// no TFM could be found, assume latest stable?
"net48"
/// Gets the tfm E.g netcore3.0, net472
let executionTfm =

Просмотреть файл

@ -344,7 +344,7 @@ module LegacyMSBuildReferenceResolver
#if ENABLE_MONO_SUPPORT
// The properties TargetedRuntimeVersion and CopyLocalDependenciesWhenParentReferenceInGac
// are not available on Mono. So we only set them if available (to avoid a compile-time dependency).
if not FSharp.Compiler.AbstractIL.IL.runningOnMono then
if not FSharp.Compiler.AbstractIL.Internal.Utils.runningOnMono then
typeof<ResolveAssemblyReference>.InvokeMember("TargetedRuntimeVersion",(BindingFlags.Instance ||| BindingFlags.SetProperty ||| BindingFlags.Public),null,rar,[| box targetedRuntimeVersionValue |]) |> ignore
typeof<ResolveAssemblyReference>.InvokeMember("CopyLocalDependenciesWhenParentReferenceInGac",(BindingFlags.Instance ||| BindingFlags.SetProperty ||| BindingFlags.Public),null,rar,[| box true |]) |> ignore
#else

Просмотреть файл

@ -29,8 +29,9 @@ open FSharp.Compiler
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILBinaryReader
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.IlxGen

Просмотреть файл

@ -29,6 +29,7 @@ open FSharp.Compiler.AbstractIL.Diagnostics
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILBinaryReader
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.AbstractIL.ILRuntimeWriter
open FSharp.Compiler.Lib
open FSharp.Compiler.AccessibilityLogic

Просмотреть файл

@ -12,7 +12,8 @@ open FSharp.Compiler
open FSharp.Compiler.AbstractIL
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.ILBinaryReader
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.AbstractIL.Internal.Utils
open FSharp.Compiler.Ast
open FSharp.Compiler.CompileOps

Просмотреть файл

@ -0,0 +1,36 @@
#if INTERACTIVE
#r "../../artifacts/bin/fcs/net461/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/net461/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
module Tests.Service.ScriptOptions
#endif
open NUnit.Framework
open FsUnit
open System
open FSharp.Compiler
open FSharp.Compiler.SourceCodeServices
open FSharp.Compiler.Service.Tests.Common
// Add additional imports/constructs into this script text to verify that common scenarios
// for FCS script typechecking can be supported
let scriptSource = """
open System
let pi = Math.PI
"""
[<TestCase(true, false, [| "--targetprofile:mscorlib" |])>]
[<TestCase(false, true, [| "--targetprofile:netcore" |])>]
[<Test>]
let ``can generate options for different frameworks regardless of execution environment``(assumeNetFx, useSdk, flags) =
let path = IO.Path.GetTempPath()
let file = IO.Path.GetTempFileName()
let tempFile = IO.Path.Combine(path, file)
let (options, errors) =
checker.GetProjectOptionsFromScript(tempFile, Text.SourceText.ofString scriptSource, assumeDotNetFramework = assumeNetFx, useSdkRefs = useSdk, otherFlags = flags)
|> Async.RunSynchronously
match errors with
| [] -> ()
| errors -> failwithf "Error while parsing script with assumeDotNetFramework:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" assumeNetFx useSdk flags errors