From 30339f4a950f7e8e313c5b833524f4910ec9e98c Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Thu, 8 Feb 2024 12:58:32 -0800 Subject: [PATCH 1/2] Update framework --- .../BasicGrammarElements/MethodResolution.fs | 21 ++--- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 3 +- .../EmittedIL/ByRefTests.fs | 17 ++-- .../CompilerGeneratedAttributeOnAccessors.fs | 14 +-- .../Interop/StaticsInInterfaces.fs | 15 +-- tests/FSharp.Test.Utilities/Compiler.fs | 92 ++++++++++++------- tests/FSharp.Test.Utilities/CompilerAssert.fs | 38 ++++++++ .../DirectoryAttribute.fs | 2 +- .../FSharp.Test.Utilities.fsproj | 1 + tests/FSharp.Test.Utilities/ILChecker.fs | 23 ++++- .../FSharp.Test.Utilities/ReflectionHelper.fs | 8 +- tests/FSharp.Test.Utilities/Utilities.fs | 3 +- .../Compiler/CodeGen/EmittedIL/CeEdiThrow.fs | 3 +- .../Compiler/CodeGen/EmittedIL/Mutation.fs | 30 ++---- .../EmittedIL/ReferenceAssemblyTests.fs | 69 +++++--------- .../CodeGen/EmittedIL/TaskGeneratedCode.fs | 3 +- 16 files changed, 184 insertions(+), 158 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs index af9a6eb8d0b..613001af658 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MethodResolution.fs @@ -76,8 +76,7 @@ extends [runtime]System.Object } - .method assembly specialname static class [runtime]System.Tuple`2 - get_patternInput@9() cil managed + .method assembly specialname static class [runtime]System.Tuple`2 get_patternInput@9() cil managed { .maxstack 8 @@ -85,8 +84,7 @@ extends [runtime]System.Object IL_0005: ret } - .method assembly specialname static int32 - get_outArg@9() cil managed + .method assembly specialname static int32 get_outArg@9() cil managed { .maxstack 8 @@ -94,8 +92,7 @@ extends [runtime]System.Object IL_0005: ret } - .method assembly specialname static void - set_outArg@9(int32 'value') cil managed + .method assembly specialname static void set_outArg@9(int32 'value') cil managed { .maxstack 8 @@ -104,8 +101,7 @@ extends [runtime]System.Object IL_0006: ret } - .method assembly specialname static class [runtime]System.Tuple`2 - 'get_patternInput@10-1'() cil managed + .method assembly specialname static class [runtime]System.Tuple`2 'get_patternInput@10-1'() cil managed { .maxstack 8 @@ -113,8 +109,7 @@ extends [runtime]System.Object IL_0005: ret } - .method assembly specialname static int32 - 'get_outArg@10-1'() cil managed + .method assembly specialname static int32 'get_outArg@10-1'() cil managed { .maxstack 8 @@ -122,8 +117,7 @@ extends [runtime]System.Object IL_0005: ret } - .method assembly specialname static void - 'set_outArg@10-1'(int32 'value') cil managed + .method assembly specialname static void 'set_outArg@10-1'(int32 'value') cil managed { .maxstack 8 @@ -174,8 +168,7 @@ extends [runtime]System.Object .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method private specialname rtspecialname static - void .cctor() cil managed + .method private specialname rtspecialname static void .cctor() cil managed { .maxstack 4 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index 7a5b9991113..d3d7be2cf36 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -723,8 +723,7 @@ let main _ = |> shouldSucceed |> verifyIL [ """ - .method public specialname static class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 - '|GoodPotato|_|'<(class [Potato]Potato.Lib/IPotato`1) T>(!!T x) cil managed + .method public specialname static class [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1 '|GoodPotato|_|'<(class [Potato]Potato.Lib/IPotato`1) T>(!!T x) cil managed { .maxstack 8 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs index 2cd6057ac66..133e67e45a7 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs @@ -325,8 +325,7 @@ type C() = extends [System.Runtime]System.Attribute { .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .custom instance void [netstandard]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [netstandard]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -366,8 +365,7 @@ type C() = .get instance int32& modreq([netstandard]System.Runtime.InteropServices.InAttribute) System.Runtime.CompilerServices.C::get_X() }""" - let verifyMethod = """.method public hidebysig specialname instance int32& modreq([netstandard]System.Runtime.InteropServices.InAttribute) - get_X() cil managed + let verifyMethod = """.method public hidebysig specialname instance int32& modreq([netstandard]System.Runtime.InteropServices.InAttribute) get_X() cil managed { .param [0] .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" @@ -377,8 +375,7 @@ type C() = extends [netstandard]System.Attribute { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -408,8 +405,7 @@ type C<'T>() = member _.X<'U>(): inref<'T> = &x """ - let verifyMethod = """.method public hidebysig instance !T& modreq([runtime]System.Runtime.InteropServices.InAttribute) - X() cil managed + let verifyMethod = """.method public hidebysig instance !T& modreq([runtime]System.Runtime.InteropServices.InAttribute) X() cil managed { .param [0] .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" @@ -435,8 +431,7 @@ module Test = member _.X<'U>(): inref<'T> = &x """ - let verifyMethod = """.method public hidebysig instance !T& modreq([netstandard]System.Runtime.InteropServices.InAttribute) - X() cil managed + let verifyMethod = """.method public hidebysig instance !T& modreq([netstandard]System.Runtime.InteropServices.InAttribute) X() cil managed { .param [0] .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" @@ -463,7 +458,7 @@ type C<'T>() = X() cil managed { .param [0] - .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) """ + .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" FSharp src |> compile diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CompilerGeneratedAttributeOnAccessors.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CompilerGeneratedAttributeOnAccessors.fs index b90ad6a95d4..ec17c961cf2 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CompilerGeneratedAttributeOnAccessors.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CompilerGeneratedAttributeOnAccessors.fs @@ -41,8 +41,7 @@ module ``Auto-generated accessors have CompilerGenerated attribute`` = |> compile |> verifyIL [ """ - .method public hidebysig specialname - instance int32 get_Age() cil managed + .method public hidebysig specialname instance int32 get_Age() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -53,8 +52,7 @@ module ``Auto-generated accessors have CompilerGenerated attribute`` = IL_0006: ret } - .method public hidebysig specialname - instance void set_Age(int32 v) cil managed + .method public hidebysig specialname instance void set_Age(int32 v) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -84,8 +82,7 @@ module ``Auto-generated accessors have CompilerGenerated attribute`` = |> compile |> verifyIL [ """ - .method public specialname static int32 - get_Age() cil managed + .method public specialname static int32 get_Age() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -103,8 +100,7 @@ module ``Auto-generated accessors have CompilerGenerated attribute`` = IL_0016: ret } - .method public specialname static void - set_Age(int32 v) cil managed + .method public specialname static void set_Age(int32 v) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -202,5 +198,5 @@ module ``Let bindings in classes shoulnd't have DebuggerNonUserCodeAttribute`` = """ |> compileAssembly |> getType "Test+User" - |> getPrivateMethod "moo" + |> getPrivateInstanceMethod "moo" |> shouldn't haveAttribute "DebuggerNonUserCodeAttribute" diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/StaticsInInterfaces.fs b/tests/FSharp.Compiler.ComponentTests/Interop/StaticsInInterfaces.fs index 903e7832065..b16f787ba23 100644 --- a/tests/FSharp.Compiler.ComponentTests/Interop/StaticsInInterfaces.fs +++ b/tests/FSharp.Compiler.ComponentTests/Interop/StaticsInInterfaces.fs @@ -193,8 +193,7 @@ extends [runtime]System.Object implements class [csLib]StaticsInInterfaces.IGetNext`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .method public specialname rtspecialname -instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -205,8 +204,7 @@ instance void .ctor() cil managed IL_0008: ret } - .method public hidebysig static class StaticsTesting/MyRepeatSequence -'StaticsInInterfaces.IGetNext.Next'(class StaticsTesting/MyRepeatSequence other) cil managed + .method public hidebysig static class StaticsTesting/MyRepeatSequence 'StaticsInInterfaces.IGetNext.Next'(class StaticsTesting/MyRepeatSequence other) cil managed { .override method !0 class [csLib]StaticsInInterfaces.IGetNext`1::Next(!0) @@ -222,8 +220,7 @@ extends [runtime]System.Object implements class [csLib]StaticsInInterfaces.IGetNext`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .method public specialname rtspecialname -instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -234,8 +231,7 @@ instance void .ctor() cil managed IL_0008: ret } - .method public static class StaticsTesting/MyRepeatSequence2 -Next(class StaticsTesting/MyRepeatSequence2 other) cil managed + .method public static class StaticsTesting/MyRepeatSequence2 Next(class StaticsTesting/MyRepeatSequence2 other) cil managed { .maxstack 8 @@ -243,8 +239,7 @@ Next(class StaticsTesting/MyRepeatSequence2 other) cil managed IL_0001: ret } - .method public hidebysig static class StaticsTesting/MyRepeatSequence2 -'StaticsInInterfaces.IGetNext.Next'(class StaticsTesting/MyRepeatSequence2 other) cil managed + .method public hidebysig static class StaticsTesting/MyRepeatSequence2 'StaticsInInterfaces.IGetNext.Next'(class StaticsTesting/MyRepeatSequence2 other) cil managed { .override method !0 class [csLib]StaticsInInterfaces.IGetNext`1::Next(!0) diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 46462d0a473..44e2b9f6608 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -207,7 +207,7 @@ module rec Compiler = | Arm = 5 | Arm64 = 6 - let private defaultOptions : string list = [] + let public defaultOptions : string list = [] let normalizePathSeparator (text:string) = text.Replace(@"\", "/") @@ -1112,7 +1112,9 @@ Actual: let private createBaselineErrors (baselineFile: BaselineFile) (actualErrors: string) : unit = printfn $"creating baseline error file for convenience: {baselineFile.FilePath}, expected: {baselineFile.BslSource}" - FileSystem.OpenFileForWriteShim(baselineFile.FilePath).Write(actualErrors) + let file = FileSystem.OpenFileForWriteShim(baselineFile.FilePath) + file.SetLength(0) + file.WriteAllText(actualErrors) let private verifyFSBaseline fs : unit = match fs.Baseline with @@ -1156,30 +1158,48 @@ Actual: | Some p -> func p il | CompilationResult.Failure f -> failwith $"Result should be \"Success\" in order to get IL. Failure: {Environment.NewLine}{f}" + let withILContains expected result : CompilationResult = + match result with + | CompilationResult.Success s -> + match s.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> + match ILChecker.verifyILAndReturnActual [] p expected with + | true, _, _ -> result + | false, errorMsg, _actualIL -> CompilationResult.Failure( {s with Output = Some (ExecutionOutput { StdOut = errorMsg; ExitCode = 0; StdErr = "" })} ) + + | CompilationResult.Failure f -> failwith $"Result should be \"Success\" in order to get IL. Failure: {Environment.NewLine}{f}" + let verifyIL = doILCheck ILChecker.checkIL let verifyILNotPresent = doILCheck ILChecker.checkILNotPresent let verifyILBinary (il: string list) (dll: string)= ILChecker.checkIL dll il - let private verifyFSILBaseline (baseline: Baseline) (result: CompilationOutput) : unit = - match result.OutputPath with - | None -> failwith "Operation didn't produce any output!" - | Some p -> - let expectedIL = - match baseline.ILBaseline.Content with - | Some b -> b - | None -> String.Empty - let success, errorMsg, actualIL = ILChecker.verifyILAndReturnActual p expectedIL - - if not success then - // Failed try update baselines if required - // If we are here then the il file has been produced we can write it back to the baseline location - // if the environment variable TEST_UPDATE_BSL has been set - updateBaseLineIfEnvironmentSaysSo baseline.ILBaseline - createBaselineErrors baseline.ILBaseline actualIL - let errorMsg = (convenienceBaselineInstructions baseline.ILBaseline expectedIL actualIL) + errorMsg - Assert.Fail(errorMsg) + let private verifyFSILBaseline (baseline: Baseline option) (result: CompilationOutput) : unit = + match baseline with + | None -> failwith "Baseline was not provided." + | Some bsl -> + match result.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> + let expectedIL = + match bsl.ILBaseline.Content with + | Some b -> b + | None -> String.Empty + let (success, errorMsg, actualIL) = ILChecker.verifyILAndReturnActual [] p [expectedIL] + + match success, baseline with + | false, Some baseline -> + // Failed try update baselines if required + // If we are here then the il file has been produced we can write it back to the baseline location + // if the environment variable TEST_UPDATE_BSL has been set + updateBaseLineIfEnvironmentSaysSo baseline.ILBaseline + createBaselineErrors baseline.ILBaseline actualIL + let errorMsg = (convenienceBaselineInstructions baseline.ILBaseline expectedIL actualIL) + errorMsg + Assert.Fail(errorMsg) + | false, None -> Assert.Fail("No baseline provided") + | _, _ -> () let verifyILBaseline (cUnit: CompilationUnit) : CompilationUnit = match cUnit with @@ -1195,7 +1215,7 @@ Actual: File.WriteAllText(baseline.ILBaseline.BslSource, "") else failwith $"Build failure empty baseline at {baseline.ILBaseline.BslSource}: {a}" - | CompilationResult.Success s, Some baseline -> verifyFSILBaseline baseline s + | CompilationResult.Success s, Some baseline -> verifyFSILBaseline (Some baseline) s | _, None -> failwithf $"Baseline was not provided." | _ -> failwith "Baseline tests are only supported for F#." @@ -1348,7 +1368,6 @@ Actual: if documents <> expectedDocuments then failwith $"Expected documents are different from PDB.\nExpected: %A{expectedDocuments}\nActual: %A{documents}" - let private verifyPdbOptions reader options = for option in options do match option with @@ -1418,7 +1437,7 @@ Actual: let private getErrorInfo (info: ErrorInfo) : string = sprintf "%A %A" info.Error info.Message - let inline private assertErrorsLength (source: ErrorInfo list) (expected: 'a list) : unit = + let private assertErrorsLength (source: ErrorInfo list) (expected: 'a list) : unit = if (List.length source) <> (List.length expected) then failwith (sprintf "Expected list of issues differ from compilation result:\nExpected:\n %A\nActual:\n %A" expected (List.map getErrorInfo source)) () @@ -1546,8 +1565,6 @@ Actual: let withResult (expectedResult: SimpleErrorInfo ) (result: CompilationResult) : CompilationResult = withResults [expectedResult] result - - module TextBasedDiagnosticAsserts = open FSharp.Compiler.Text.Range @@ -1674,26 +1691,35 @@ Actual: | _ -> failwith "Cannot check exit code on this run result." result - let private checkOutput (category: string) (substring: string) (selector: ExecutionOutput -> string) (result: CompilationResult) : CompilationResult = + let private checkOutputInOrder (category: string) (substrings: string list) (selector: ExecutionOutput -> string) (result: CompilationResult) : CompilationResult = match result.RunOutput with | None -> failwith (sprintf "Execution output is missing cannot check \"%A\"" category) | Some o -> match o with | ExecutionOutput e -> let where = selector e - if not (where.Contains(substring)) then - failwith (sprintf "\nThe following substring:\n %A\nwas not found in the %A\nOutput:\n %A" substring category where) + let mutable searchPos = 0 + for substring in substrings do + match where.IndexOf(substring, searchPos) with + | -1 -> failwith (sprintf "\nThe following substring:\n %A\nwas not found in the %A\nOutput:\n %A" substring category where) + | pos -> searchPos <- pos + substring.Length | _ -> failwith "Cannot check output on this run result." result - let withOutputContains (substring: string) (result: CompilationResult) : CompilationResult = - checkOutput "STDERR/STDOUT" substring (fun o -> o.StdOut + "\n" + o.StdErr) result + let withOutputContainsAllInOrder (substrings: string list) (result: CompilationResult) : CompilationResult = + checkOutputInOrder "STDERR/STDOUT" substrings (fun o -> o.StdOut + "\n" + o.StdErr) result let withStdOutContains (substring: string) (result: CompilationResult) : CompilationResult = - checkOutput "STDOUT" substring (fun o -> o.StdOut) result + checkOutputInOrder "STDOUT" [substring] (fun o -> o.StdOut) result + + let withStdOutContainsAllInOrder (substrings: string list) (result: CompilationResult) : CompilationResult = + checkOutputInOrder "STDOUT" substrings (fun o -> o.StdOut) result + + let withStdErrContainsAllInOrder (substrings: string list) (result: CompilationResult) : CompilationResult = + checkOutputInOrder "STDERR" substrings (fun o -> o.StdErr) result let withStdErrContains (substring: string) (result: CompilationResult) : CompilationResult = - checkOutput "STDERR" substring (fun o -> o.StdErr) result + checkOutputInOrder "STDERR" [substring] (fun o -> o.StdErr) result let private assertEvalOutput (selector: FsiValue -> 'T) (value: 'T) (result: CompilationResult) : CompilationResult = match result.RunOutput with @@ -1752,5 +1778,3 @@ Actual: match hash with | Some h -> h | None -> failwith "Implied signature hash returned 'None' which should not happen" - - \ No newline at end of file diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index 7951ba31d5d..f482764de82 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -5,6 +5,7 @@ namespace FSharp.Test #nowarn "57" open System +open System.Globalization open System.IO open System.Text open System.Reflection @@ -24,6 +25,42 @@ open NUnit.Framework open TestFramework open System.Collections.Immutable + +#if !NETCOREAPP +module AssemblyResolver = + + let probingPaths = [| + AppDomain.CurrentDomain.BaseDirectory + Path.GetDirectoryName(typeof.Assembly.Location) + |] + + let addResolver () = + AppDomain.CurrentDomain.add_AssemblyResolve(fun h args -> + let found () = + (probingPaths ) |> Seq.tryPick(fun p -> + try + let name = AssemblyName(args.Name) + let codebase = Path.GetFullPath(Path.Combine(p, name.Name)) + if File.Exists(codebase + ".dll") then + name.CodeBase <- codebase + ".dll" + name.CultureInfo <- Unchecked.defaultof + name.Version <- Unchecked.defaultof + Some (name) + elif File.Exists(codebase + ".exe") then + name.CodeBase <- codebase + ".exe" + name.CultureInfo <- Unchecked.defaultof + name.Version <- Unchecked.defaultof + Some (name) + else None + with | _ -> None + ) + match found() with + | None -> Unchecked.defaultof + | Some name -> Assembly.Load(name) ) + + do addResolver() +#endif + [] type ILVerifier (dllFilePath: string) = @@ -621,6 +658,7 @@ module rec CompilerAssertHelpers = let timeout = 30000 let exitCode, output, errors = Commands.executeProcess (Some fileName) arguments (Path.GetDirectoryName(outputFilePath)) timeout (exitCode, output |> String.concat "\n", errors |> String.concat "\n") + open CompilerAssertHelpers [] diff --git a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs index 5365abdbdb5..c1561fa6c9b 100644 --- a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs +++ b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs @@ -92,7 +92,7 @@ type DirectoryAttribute(dir: string) = FSBaseline = { FilePath = fsOutFilePath; BslSource = fsBslFilePath; Content = fsBslSource } ILBaseline = { FilePath = ilOutFilePath; BslSource = ilBslFilePath; Content = ilBslSource } } - Options = [] + Options = Compiler.defaultOptions OutputType = Library Name = Some filename IgnoreWarnings = false diff --git a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj index 5cfcba98ca7..607d3fb1c4d 100644 --- a/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj +++ b/tests/FSharp.Test.Utilities/FSharp.Test.Utilities.fsproj @@ -90,6 +90,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs index 8164f876a52..0db96f449ee 100644 --- a/tests/FSharp.Test.Utilities/ILChecker.fs +++ b/tests/FSharp.Test.Utilities/ILChecker.fs @@ -29,12 +29,17 @@ module ILChecker = (fun me -> String.Empty) ) - let private normalizeILText assemblyName (ilCode: string) = + let normalizeILText assemblyName (ilCode: string) = let blockComments = @"/\*(.*?)\*/" let lineComments = @"//(.*?)\r?\n" let lineCommentsEof = @"//(.*?)$" let strings = @"""((\\[^\n]|[^""\n])*)""" let verbatimStrings = @"@(""[^""]*"")+" + let methodSingleLine = "^(\s*\.method.*)(?: \s*)$[\r?\n?]^(\s*\{)" + let methodMultiLine = "^(\s*\.method.*)(?: \s*)$[\r?\n?]^(?: \s*)(.*)\s*$[\r?\n?]^(\s*\{)" + + let normalizeNewLines (text: string) = text.Replace("\r\n", "\n").Replace("\r\n", "\r") + let stripComments (text:string) = Regex.Replace(text, $"{blockComments}|{lineComments}|{lineCommentsEof}|{strings}|{verbatimStrings}", @@ -45,6 +50,11 @@ module ILChecker = me.Value), RegexOptions.Singleline) |> filterSpecialComment + let unifyMethodLine (text:string) = + let text1 = Regex.Replace(text, $"{methodSingleLine}", (fun me -> $"{me.Groups[1].Value}\n{me.Groups[2].Value}"), RegexOptions.Multiline) + let text2 = Regex.Replace(text1, $"{methodMultiLine}", (fun me -> $"{me.Groups[1].Value} {me.Groups[2].Value}\n{me.Groups[3].Value}"), RegexOptions.Multiline) + text2 + let replace input (pattern, replacement: string) = Regex.Replace(input, pattern, replacement, RegexOptions.Singleline) let unifyRuntimeAssemblyName ilCode = @@ -62,8 +72,11 @@ module ILChecker = |> unifyRuntimeAssemblyName |> unifyImageBase - ilCode.Trim() |> stripComments |> unifyingAssemblyNames - + ilCode.Trim() + |> normalizeNewLines + |> stripComments + |> unifyingAssemblyNames + |> unifyMethodLine let private generateIlFile dllFilePath ildasmArgs = let ilFilePath = Path.ChangeExtension(dllFilePath, ".il") @@ -165,8 +178,8 @@ module ILChecker = let verifyIL (dllFilePath: string) (expectedIL: string) = checkIL dllFilePath [expectedIL] - let verifyILAndReturnActual (dllFilePath: string) (expectedIL: string) = - checkILPrim [] dllFilePath [expectedIL] + let verifyILAndReturnActual args dllFilePath expectedIL = + checkILPrim args dllFilePath expectedIL let checkILNotPresent dllFilePath unexpectedIL = let actualIL = generateIL dllFilePath [] diff --git a/tests/FSharp.Test.Utilities/ReflectionHelper.fs b/tests/FSharp.Test.Utilities/ReflectionHelper.fs index c5c5db2ca72..f14d474be56 100644 --- a/tests/FSharp.Test.Utilities/ReflectionHelper.fs +++ b/tests/FSharp.Test.Utilities/ReflectionHelper.fs @@ -33,7 +33,13 @@ let getMethod methodName (ty: Type) = | methodInfo -> methodInfo /// Gets a type's private method -let getPrivateMethod methodName (ty: Type) = +let getPublicInstanceMethod methodName (ty: Type) = + match ty.GetMethod(methodName, BindingFlags.Public ||| BindingFlags.Instance) with + | null -> failwith $"Error: Type did not contain public method %s{methodName}" + | methodInfo -> methodInfo + +/// Gets a type's private method +let getPrivateInstanceMethod methodName (ty: Type) = match ty.GetMethod(methodName, BindingFlags.NonPublic ||| BindingFlags.Instance) with | null -> failwith $"Error: Type did not contain private method %s{methodName}" | methodInfo -> methodInfo diff --git a/tests/FSharp.Test.Utilities/Utilities.fs b/tests/FSharp.Test.Utilities/Utilities.fs index d434d837485..897837c6bce 100644 --- a/tests/FSharp.Test.Utilities/Utilities.fs +++ b/tests/FSharp.Test.Utilities/Utilities.fs @@ -38,6 +38,7 @@ type FactForDESKTOPAttribute() = do base.Skip <- "NETCOREAPP is not supported runtime for this kind of test, it is intended for DESKTOP only" #endif + // This file mimics how Roslyn handles their compilation references for compilation testing module Utilities = @@ -306,7 +307,7 @@ let main argv = 0""" File.WriteAllText(directoryBuildPropsFileName, directoryBuildProps) File.WriteAllText(directoryBuildTargetsFileName, directoryBuildTargets) - let timeout = 30000 + let timeout = 120000 let exitCode, dotnetoutput, dotneterrors = Commands.executeProcess (Some config.DotNetExe) "build" projectDirectory timeout if exitCode <> 0 || errors.Length > 0 then diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/CeEdiThrow.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/CeEdiThrow.fs index 85108186587..cf9f65fecbb 100644 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/CeEdiThrow.fs +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/CeEdiThrow.fs @@ -29,8 +29,7 @@ let foo = Try(){ """, (fun verifier -> verifier.VerifyIL [ """ - .method public strict virtual instance int32 - Invoke(class [runtime]System.Exception _arg1) cil managed + .method public strict virtual instance int32 Invoke(class [runtime]System.Exception _arg1) cil managed { .maxstack 5 diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs index d2f071fcb04..2f7eb6de700 100644 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/Mutation.fs @@ -56,8 +56,7 @@ x.ToString() """, (fun verifier -> verifier.VerifyIL [ """ - .method public specialname static valuetype [mscorlib]System.TimeSpan - get_x() cil managed + .method public specialname static valuetype [mscorlib]System.TimeSpan get_x() cil managed { .maxstack 8 @@ -106,8 +105,7 @@ x.Day """, (fun verifier -> verifier.VerifyIL [ """ - .method public specialname static valuetype [mscorlib]System.DateTime - get_x() cil managed + .method public specialname static valuetype [mscorlib]System.DateTime get_x() cil managed { .maxstack 8 @@ -155,8 +153,7 @@ x.ToString() """, (fun verifier -> verifier.VerifyIL [ """ - .method public specialname static valuetype [mscorlib]System.Decimal - get_x() cil managed + .method public specialname static valuetype [mscorlib]System.Decimal get_x() cil managed { .maxstack 8 @@ -221,8 +218,7 @@ type StaticC() = .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) .field assembly int32 x .custom instance void [FSharp.Core]Microsoft.FSharp.Core.VolatileFieldAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -237,8 +233,7 @@ type StaticC() = IL_0011: ret } - .method public hidebysig specialname - instance int32 get_X() cil managed + .method public hidebysig specialname instance int32 get_X() cil managed { .maxstack 8 @@ -248,8 +243,7 @@ type StaticC() = IL_0008: ret } - .method public hidebysig specialname - instance void set_X(int32 v) cil managed + .method public hidebysig specialname instance void set_X(int32 v) cil managed { .maxstack 8 @@ -275,8 +269,7 @@ type StaticC() = .field static assembly int32 x .custom instance void [FSharp.Core]Microsoft.FSharp.Core.VolatileFieldAttribute::.ctor() = ( 01 00 00 00 ) .field static assembly int32 init@10 - .method public specialname rtspecialname - instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -287,8 +280,7 @@ type StaticC() = IL_0008: ret } - .method public specialname static int32 - get_X() cil managed + .method public specialname static int32 get_X() cil managed { .maxstack 8 @@ -309,8 +301,7 @@ type StaticC() = IL_001c: ret } - .method public specialname static void - set_X(int32 v) cil managed + .method public specialname static void set_X(int32 v) cil managed { .maxstack 8 @@ -332,8 +323,7 @@ type StaticC() = IL_001d: ret } - .method private specialname rtspecialname static - void .cctor() cil managed + .method private specialname rtspecialname static void .cctor() cil managed { .maxstack 8 diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs index b20315ffce3..0a932212df8 100644 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs @@ -757,8 +757,7 @@ type [] MySecondRecord = { Name: string } .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 02 00 00 00 00 00 ) - .method public hidebysig specialname instance string - get_Name() cil managed + .method public hidebysig specialname instance string get_Name() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -768,8 +767,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public hidebysig specialname instance void - set_Name(string 'value') cil managed + .method public hidebysig specialname instance void set_Name(string 'value') cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -779,8 +777,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public specialname rtspecialname - instance void .ctor(string name) cil managed + .method public specialname rtspecialname instance void .ctor(string name) cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 20 4E 65 74 37 46 53 68 61 72 @@ -792,8 +789,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public specialname rtspecialname - instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -801,8 +797,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -827,8 +822,7 @@ type [] MySecondRecord = { Name: string } .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 02 00 00 00 00 00 ) - .method public hidebysig specialname instance string - get_Name() cil managed + .method public hidebysig specialname instance string get_Name() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -838,8 +832,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public hidebysig specialname instance void - set_Name(string 'value') cil managed + .method public hidebysig specialname instance void set_Name(string 'value') cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -849,8 +842,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public specialname rtspecialname - instance void .ctor(string name) cil managed + .method public specialname rtspecialname instance void .ctor(string name) cil managed { .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 20 4E 65 74 37 46 53 68 61 72 @@ -862,8 +854,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public specialname rtspecialname - instance void .ctor() cil managed + .method public specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -871,8 +862,7 @@ type [] MySecondRecord = { Name: string } IL_0001: throw } - .method public strict virtual instance string - ToString() cil managed + .method public strict virtual instance string ToString() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -1170,8 +1160,7 @@ type Person(name : string, age : int) = .custom instance void [FSharp.Core]Microsoft.FSharp.Core.SealedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) .field assembly bool smth - .method public specialname rtspecialname - instance void .ctor(bool smth) cil managed + .method public specialname rtspecialname instance void .ctor(bool smth) cil managed { .maxstack 8 @@ -1179,8 +1168,7 @@ type Person(name : string, age : int) = IL_0001: throw } - .method assembly specialname rtspecialname - instance void .ctor() cil managed + .method assembly specialname rtspecialname instance void .ctor() cil managed { .maxstack 8 @@ -1188,8 +1176,7 @@ type Person(name : string, age : int) = IL_0001: throw } - .method public hidebysig specialname - instance bool get_Something() cil managed + .method public hidebysig specialname instance bool get_Something() cil managed { .maxstack 8 @@ -1217,8 +1204,7 @@ type Person(name : string, age : int) = IL_0001: throw } - .method public hidebysig specialname - instance string get_Name() cil managed + .method public hidebysig specialname instance string get_Name() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -1228,8 +1214,7 @@ type Person(name : string, age : int) = IL_0001: throw } - .method public hidebysig specialname - instance void set_Name(string v) cil managed + .method public hidebysig specialname instance void set_Name(string v) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -1239,8 +1224,7 @@ type Person(name : string, age : int) = IL_0001: throw } - .method public hidebysig specialname - instance int32 get_Age() cil managed + .method public hidebysig specialname instance int32 get_Age() cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -1250,8 +1234,7 @@ type Person(name : string, age : int) = IL_0001: throw } - .method public hidebysig specialname - instance void set_Age(int32 v) cil managed + .method public hidebysig specialname instance void set_Age(int32 v) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) @@ -1441,19 +1424,16 @@ type CompilerGoesBoom<'a>() = """.class interface public abstract auto ansi serializable beforefieldinit Foobar.IHasStaticAbstractBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .method public hidebysig abstract virtual - instance !a BoomInstance() cil managed + .method public hidebysig abstract virtual instance !a BoomInstance() cil managed { } - .method public hidebysig static abstract virtual - !a BoomStatic() cil managed + .method public hidebysig static abstract virtual !a BoomStatic() cil managed { } }""" - """.method private hidebysig newslot virtual - instance !a 'Foobar.IHasStaticAbstractBase<\'a>.BoomInstance'() cil managed + """.method private hidebysig newslot virtual instance !a 'Foobar.IHasStaticAbstractBase<\'a>.BoomInstance'() cil managed { .override method instance !0 class Foobar.IHasStaticAbstractBase`1::BoomInstance() @@ -1509,19 +1489,16 @@ type CompilerGoesBoom<'a>() = """.class interface public abstract auto ansi serializable beforefieldinit Foobar.IHasStaticAbstractBase`1 { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .method public hidebysig abstract virtual - instance !a BoomInstance() cil managed + .method public hidebysig abstract virtual instance !a BoomInstance() cil managed { } - .method public hidebysig static abstract virtual - !a BoomStatic() cil managed + .method public hidebysig static abstract virtual !a BoomStatic() cil managed { } }""" - """.method private hidebysig newslot virtual - instance !a 'Foobar.IHasStaticAbstractBase<\'a>.BoomInstance'() cil managed + """.method private hidebysig newslot virtual instance !a 'Foobar.IHasStaticAbstractBase<\'a>.BoomInstance'() cil managed { .override method instance !0 class Foobar.IHasStaticAbstractBase`1::BoomInstance() diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/TaskGeneratedCode.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/TaskGeneratedCode.fs index dc9c9cdd377..492bb64bfc4 100644 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/TaskGeneratedCode.fs +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/TaskGeneratedCode.fs @@ -37,8 +37,7 @@ let testTask() = task { return 1 } """, (fun verifier -> verifier.VerifyIL [ """ -.method public strict virtual instance void -MoveNext() cil managed +.method public strict virtual instance void MoveNext() cil managed { .override [runtime]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext From a87699288097c0b011d218a40f0566eac1e0e461 Mon Sep 17 00:00:00 2001 From: KevinRansom Date: Fri, 9 Feb 2024 01:26:13 -0800 Subject: [PATCH 2/2] feedback --- tests/FSharp.Test.Utilities/Compiler.fs | 46 +++++++++++-------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 44e2b9f6608..c29d0958801 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -1176,30 +1176,24 @@ Actual: let verifyILBinary (il: string list) (dll: string)= ILChecker.checkIL dll il - let private verifyFSILBaseline (baseline: Baseline option) (result: CompilationOutput) : unit = - match baseline with - | None -> failwith "Baseline was not provided." - | Some bsl -> - match result.OutputPath with - | None -> failwith "Operation didn't produce any output!" - | Some p -> - let expectedIL = - match bsl.ILBaseline.Content with - | Some b -> b - | None -> String.Empty - let (success, errorMsg, actualIL) = ILChecker.verifyILAndReturnActual [] p [expectedIL] - - match success, baseline with - | false, Some baseline -> - // Failed try update baselines if required - // If we are here then the il file has been produced we can write it back to the baseline location - // if the environment variable TEST_UPDATE_BSL has been set - updateBaseLineIfEnvironmentSaysSo baseline.ILBaseline - createBaselineErrors baseline.ILBaseline actualIL - let errorMsg = (convenienceBaselineInstructions baseline.ILBaseline expectedIL actualIL) + errorMsg - Assert.Fail(errorMsg) - | false, None -> Assert.Fail("No baseline provided") - | _, _ -> () + let private verifyFSILBaseline (baseline: Baseline) (result: CompilationOutput) : unit = + match result.OutputPath with + | None -> failwith "Operation didn't produce any output!" + | Some p -> + let expectedIL = + match baseline.ILBaseline.Content with + | Some b -> b + | None -> String.Empty + let success, errorMsg, actualIL = ILChecker.verifyILAndReturnActual [] p [expectedIL] + + if not success then + // Failed try update baselines if required + // If we are here then the il file has been produced we can write it back to the baseline location + // if the environment variable TEST_UPDATE_BSL has been set + updateBaseLineIfEnvironmentSaysSo baseline.ILBaseline + createBaselineErrors baseline.ILBaseline actualIL + let errorMsg = (convenienceBaselineInstructions baseline.ILBaseline expectedIL actualIL) + errorMsg + Assert.Fail(errorMsg) let verifyILBaseline (cUnit: CompilationUnit) : CompilationUnit = match cUnit with @@ -1215,7 +1209,7 @@ Actual: File.WriteAllText(baseline.ILBaseline.BslSource, "") else failwith $"Build failure empty baseline at {baseline.ILBaseline.BslSource}: {a}" - | CompilationResult.Success s, Some baseline -> verifyFSILBaseline (Some baseline) s + | CompilationResult.Success s, Some baseline -> verifyFSILBaseline baseline s | _, None -> failwithf $"Baseline was not provided." | _ -> failwith "Baseline tests are only supported for F#." @@ -1437,7 +1431,7 @@ Actual: let private getErrorInfo (info: ErrorInfo) : string = sprintf "%A %A" info.Error info.Message - let private assertErrorsLength (source: ErrorInfo list) (expected: 'a list) : unit = + let inline private assertErrorsLength (source: ErrorInfo list) (expected: 'a list) : unit = if (List.length source) <> (List.length expected) then failwith (sprintf "Expected list of issues differ from compilation result:\nExpected:\n %A\nActual:\n %A" expected (List.map getErrorInfo source)) ()