Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve netcore reference selection #7263

Merged
merged 2 commits into from
Jul 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 74 additions & 13 deletions tests/fsharp/Compiler/CompilerAssert.fs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,76 @@ module CompilerAssert =

let private config = TestFramework.initializeSuite ()


// Do a one time dotnet sdk build to compute the proper set of reference assemblies to pass to the compiler
#if !NETCOREAPP
#else
let projectFile = """
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<ItemGroup><Compile Include="Program.fs" /></ItemGroup>

<Target Name="WriteFrameworkReferences" AfterTargets="AfterBuild">
<WriteLinesToFile File="FrameworkReferences.txt" Lines="@(ReferencePath)" Overwrite="true" WriteOnlyWhenDifferent="true" />
</Target>

</Project>"""

let programFs = """
open System

[<EntryPoint>]
let main argv = 0"""

let getNetCoreAppReferences =
let mutable output = ""
let mutable errors = ""
let mutable cleanUp = true
let projectDirectory = Path.Combine(Path.GetTempPath(), "netcoreapp2.1", Path.GetRandomFileName())
try
try
Directory.CreateDirectory(projectDirectory) |> ignore
let projectFileName = Path.Combine(projectDirectory, "ProjectFile.fsproj")
let programFsFileName = Path.Combine(projectDirectory, "Program.fs")
let frameworkReferencesFileName = Path.Combine(projectDirectory, "FrameworkReferences.txt")

File.WriteAllText(projectFileName, projectFile)
File.WriteAllText(programFsFileName, programFs)

let pInfo = ProcessStartInfo ()

pInfo.FileName <- config.DotNetExe
pInfo.Arguments <- "build"
pInfo.WorkingDirectory <- projectDirectory
pInfo.RedirectStandardOutput <- true
pInfo.RedirectStandardError <- true
pInfo.UseShellExecute <- false

let p = Process.Start(pInfo)
p.WaitForExit()

output <- p.StandardOutput.ReadToEnd ()
errors <- p.StandardError.ReadToEnd ()
if not (String.IsNullOrWhiteSpace errors) then Assert.Fail errors

if p.ExitCode <> 0 then Assert.Fail(sprintf "Program exited with exit code %d" p.ExitCode)

File.ReadLines(frameworkReferencesFileName) |> Seq.toArray
with | e ->
cleanUp <- false
printfn "%s" output
printfn "%s" errors
raise (new Exception (sprintf "An error occured getting netcoreapp references: %A" e))
finally
if cleanUp then
try Directory.Delete(projectDirectory) with | _ -> ()
#endif

let private defaultProjectOptions =
{
ProjectFileName = "Z:\\test.fsproj"
Expand All @@ -41,14 +111,7 @@ module CompilerAssert =
OtherOptions = [|"--preferreduilang:en-US";|]
#else
OtherOptions =
// Hack: Currently a hack to get the runtime assemblies for netcore in order to compile.
let assemblies =
typeof<obj>.Assembly.Location
|> Path.GetDirectoryName
|> Directory.EnumerateFiles
|> Seq.toArray
|> Array.filter (fun x -> x.ToLowerInvariant().Contains("system."))
|> Array.map (fun x -> sprintf "-r:%s" x)
let assemblies = getNetCoreAppReferences |> Array.map (fun x -> sprintf "-r:%s" x)
Array.append [|"--preferreduilang:en-US"; "--targetprofile:netcore"; "--noframework"|] assemblies
#endif
ReferencedProjects = [||]
Expand All @@ -60,7 +123,7 @@ module CompilerAssert =
ExtraProjectInfo = None
Stamp = None
}

let private gate = obj ()

let private compile isExe source f =
Expand Down Expand Up @@ -110,8 +173,6 @@ module CompilerAssert =

Assert.IsEmpty(typeCheckResults.Errors, sprintf "Type Check errors: %A" typeCheckResults.Errors)



let TypeCheckWithErrors (source: string) expectedTypeErrors =
lock gate <| fun () ->
let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunSynchronously
Expand Down Expand Up @@ -141,7 +202,7 @@ module CompilerAssert =
TypeCheckWithErrors (source: string) [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]

let CompileExe (source: string) =
compile true source (fun (errors, _) ->
compile true source (fun (errors, _) ->
if errors.Length > 0 then
Assert.Fail (sprintf "Compile had warnings and/or errors: %A" errors))

Expand Down Expand Up @@ -216,7 +277,7 @@ module CompilerAssert =
||> Seq.iter2 (fun expectedErrorMessage errorMessage ->
Assert.AreEqual(expectedErrorMessage, errorMessage)
)

let ParseWithErrors (source: string) expectedParseErrors =
let parseResults = checker.ParseFile("test.fs", SourceText.ofString source, FSharpParsingOptions.Default) |> Async.RunSynchronously

Expand Down
124 changes: 62 additions & 62 deletions tests/fsharp/Compiler/Language/SpanOptimizationTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -27,45 +27,45 @@ let test () =
verifier.VerifyIL
[
""".method public static void test() cil managed
{
.maxstack 5
.locals init (valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object> V_0,
int32 V_1,
valuetype [System.Private.CoreLib]System.Int32 V_2,
class [System.Private.CoreLib]System.Object& V_3)
IL_0000: call valuetype [System.Private.CoreLib]System.Span`1<!0> valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object>::get_Empty()
IL_0005: stloc.0
IL_0006: ldc.i4.0
IL_0007: stloc.2
IL_0008: ldloca.s V_0
IL_000a: call instance int32 valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object>::get_Length()
IL_000f: ldc.i4.1
IL_0010: sub
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: ldloc.2
IL_0014: blt.s IL_0034

IL_0016: ldloca.s V_0
IL_0018: ldloc.2
IL_0019: call instance !0& valuetype [System.Private.CoreLib]System.Span`1<class [System.Private.CoreLib]System.Object>::get_Item(int32)
IL_001e: stloc.3
IL_001f: ldloc.3
IL_0020: ldobj [System.Private.CoreLib]System.Object
IL_0025: call void [System.Console]System.Console::WriteLine(object)
IL_002a: ldloc.2
IL_002b: ldc.i4.1
IL_002c: add
IL_002d: stloc.2
IL_002e: ldloc.2
IL_002f: ldloc.1
IL_0030: ldc.i4.1
IL_0031: add
IL_0032: bne.un.s IL_0016

IL_0034: ret
} """
{

.maxstack 5
.locals init (valuetype [System.Runtime]System.Span`1<object> V_0,
int32 V_1,
int32 V_2,
object& V_3)
IL_0000: call valuetype [System.Runtime]System.Span`1<!0> valuetype [System.Runtime]System.Span`1<object>::get_Empty()
IL_0005: stloc.0
IL_0006: ldc.i4.0
IL_0007: stloc.2
IL_0008: ldloca.s V_0
IL_000a: call instance int32 valuetype [System.Runtime]System.Span`1<object>::get_Length()
IL_000f: ldc.i4.1
IL_0010: sub
IL_0011: stloc.1
IL_0012: ldloc.1
IL_0013: ldloc.2
IL_0014: blt.s IL_0034

IL_0016: ldloca.s V_0
IL_0018: ldloc.2
IL_0019: call instance !0& valuetype [System.Runtime]System.Span`1<object>::get_Item(int32)
IL_001e: stloc.3
IL_001f: ldloc.3
IL_0020: ldobj [System.Runtime]System.Object
IL_0025: call void [System.Console]System.Console::WriteLine(object)
IL_002a: ldloc.2
IL_002b: ldc.i4.1
IL_002c: add
IL_002d: stloc.2
IL_002e: ldloc.2
IL_002f: ldloc.1
IL_0030: ldc.i4.1
IL_0031: add
IL_0032: bne.un.s IL_0016

IL_0034: ret
}"""
])

[<Test>]
Expand All @@ -88,18 +88,18 @@ let test () =
[
""".method public static void test() cil managed
{

.maxstack 5
.locals init (valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object> V_0,
.locals init (valuetype [System.Runtime]System.ReadOnlySpan`1<object> V_0,
int32 V_1,
valuetype [System.Private.CoreLib]System.Int32 V_2,
class [System.Private.CoreLib]System.Object& V_3)
IL_0000: call valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<!0> valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object>::get_Empty()
int32 V_2,
object& V_3)
IL_0000: call valuetype [System.Runtime]System.ReadOnlySpan`1<!0> valuetype [System.Runtime]System.ReadOnlySpan`1<object>::get_Empty()
IL_0005: stloc.0
IL_0006: ldc.i4.0
IL_0007: stloc.2
IL_0008: ldloca.s V_0
IL_000a: call instance int32 valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object>::get_Length()
IL_000a: call instance int32 valuetype [System.Runtime]System.ReadOnlySpan`1<object>::get_Length()
IL_000f: ldc.i4.1
IL_0010: sub
IL_0011: stloc.1
Expand All @@ -109,10 +109,10 @@ let test () =

IL_0016: ldloca.s V_0
IL_0018: ldloc.2
IL_0019: call instance !0& modreq([System.Private.CoreLib]System.Runtime.InteropServices.InAttribute) valuetype [System.Private.CoreLib]System.ReadOnlySpan`1<class [System.Private.CoreLib]System.Object>::get_Item(int32)
IL_0019: call instance !0& modreq([System.Runtime]System.Runtime.InteropServices.InAttribute) valuetype [System.Runtime]System.ReadOnlySpan`1<object>::get_Item(int32)
IL_001e: stloc.3
IL_001f: ldloc.3
IL_0020: ldobj [System.Private.CoreLib]System.Object
IL_0020: ldobj [System.Runtime]System.Object
IL_0025: call void [System.Console]System.Console::WriteLine(object)
IL_002a: ldloc.2
IL_002b: ldc.i4.1
Expand Down Expand Up @@ -176,54 +176,54 @@ module Test =
[
""".method public static void test() cil managed
{

.maxstack 3
.locals init (valuetype System.Span`1<class [System.Private.CoreLib]System.Object> V_0,
class [System.Private.CoreLib]System.Collections.IEnumerator V_1,
.locals init (valuetype System.Span`1<object> V_0,
class [System.Runtime]System.Collections.IEnumerator V_1,
class [FSharp.Core]Microsoft.FSharp.Core.Unit V_2,
class [System.Private.CoreLib]System.IDisposable V_3)
class [System.Runtime]System.IDisposable V_3)
IL_0000: ldc.i4.0
IL_0001: newarr [System.Private.CoreLib]System.Object
IL_0006: newobj instance void valuetype System.Span`1<class [System.Private.CoreLib]System.Object>::.ctor(!0[])
IL_0001: newarr [System.Runtime]System.Object
IL_0006: newobj instance void valuetype System.Span`1<object>::.ctor(!0[])
IL_000b: stloc.0
IL_000c: ldloc.0
IL_000d: box valuetype System.Span`1<class [System.Private.CoreLib]System.Object>
IL_0012: unbox.any [System.Private.CoreLib]System.Collections.IEnumerable
IL_0017: callvirt instance class [System.Private.CoreLib]System.Collections.IEnumerator [System.Private.CoreLib]System.Collections.IEnumerable::GetEnumerator()
IL_000d: box valuetype System.Span`1<object>
IL_0012: unbox.any [System.Runtime]System.Collections.IEnumerable
IL_0017: callvirt instance class [System.Runtime]System.Collections.IEnumerator [System.Runtime]System.Collections.IEnumerable::GetEnumerator()
IL_001c: stloc.1
.try
{
IL_001d: ldloc.1
IL_001e: callvirt instance bool [System.Private.CoreLib]System.Collections.IEnumerator::MoveNext()
IL_001e: callvirt instance bool [System.Runtime]System.Collections.IEnumerator::MoveNext()
IL_0023: brfalse.s IL_0032

IL_0025: ldloc.1
IL_0026: callvirt instance object [System.Private.CoreLib]System.Collections.IEnumerator::get_Current()
IL_0026: callvirt instance object [System.Runtime]System.Collections.IEnumerator::get_Current()
IL_002b: call void [System.Console]System.Console::WriteLine(object)
IL_0030: br.s IL_001d

IL_0032: ldnull
IL_0033: stloc.2
IL_0034: leave.s IL_004c

}
}
finally
{
IL_0036: ldloc.1
IL_0037: isinst [System.Private.CoreLib]System.IDisposable
IL_0037: isinst [System.Runtime]System.IDisposable
IL_003c: stloc.3
IL_003d: ldloc.3
IL_003e: brfalse.s IL_0049

IL_0040: ldloc.3
IL_0041: callvirt instance void [System.Private.CoreLib]System.IDisposable::Dispose()
IL_0041: callvirt instance void [System.Runtime]System.IDisposable::Dispose()
IL_0046: ldnull
IL_0047: pop
IL_0048: endfinally
IL_0049: ldnull
IL_004a: pop
IL_004b: endfinally
}
}
IL_004c: ldloc.2
IL_004d: pop
IL_004e: ret
Expand Down