diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index cb175b2f067..b446e3a9986 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -240,6 +240,8 @@
+
+
@@ -269,7 +271,7 @@
-
+
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions.fs b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions.fs
new file mode 100644
index 00000000000..2b3d490293e
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions.fs
@@ -0,0 +1,83 @@
+module TypeChecks.typeextensions
+open System
+open System.IO
+open Xunit
+open FSharp.Test
+open FSharp.Test.Compiler
+open FSharp.Compiler.IO
+open NUnit.Framework
+let private verifyFSXBaseline (cu) : unit =
+ match cu with
+ | FS fs ->
+ match fs.Baseline with
+ | None -> failwith "Baseline was not provided."
+ | Some bsl ->
+ let errorsExpectedBaseLine =
+ match bsl.FSBaseline.Content with
+ | Some b -> b.Replace("\r\n","\n")
+ | None -> String.Empty
+ let errorsActual =
+ match fs.Source with
+ | SourceCodeFileKind.Fsx _->
+ //let fsxScriptFile = FileInfo fs.Source.GetSourceFileName
+ //let dir = fsxScriptFile.Directory
+ //RunRealScriptWithOptionsAndReturnResult
+ //let cfg = testConfig fsxScriptFile.Directory.FullName
+ let version = ScriptHelpers.LangVersion.Preview
+ let _r = Miscellaneous.FsharpSuiteMigrated.ScriptRunner.runScriptFile version cu
+ //let result = TestFramework.fsi cfg "%s" cfg.fsi_flags []
+ //let fsxResult = CompilerAssert.RunRealScriptWithOptionsAndReturnResult [||] fsxScriptFile
+
+ //snd fsxResult |> sanitizeFsxOutput
+ "()"
+ | _ -> failwith $"not supposed to check %A{fs.Source}"
+
+ if errorsExpectedBaseLine <> errorsActual then
+ fs.CreateOutputDirectory()
+ createBaselineErrors bsl.FSBaseline errorsActual
+ elif FileSystem.FileExistsShim(bsl.FSBaseline.FilePath) then
+ FileSystem.FileDeleteShim(bsl.FSBaseline.FilePath)
+
+ Assert.AreEqual(errorsExpectedBaseLine, errorsActual, $"\nExpected:\n{errorsExpectedBaseLine}\nActual:\n{errorsActual}")
+ | _ -> failwith $"not supposed to check %A{cu}"
+
+[]
+let ``issue.16034`` () =
+ let scriptPath = Path.Combine(
+ __SOURCE_DIRECTORY__
+ , "typeextensions"
+ , "issue.16034"
+ , "issue.16034.fsx"
+ )
+ RealFsxFromPath scriptPath
+ |> withBaseLine
+ |> verifyILBaseline
+ |> compileAndRun
+ |> verifyOutputWithDefaultBaseline
+
+[]
+let ``issue.16034.check1`` () =
+
+ let scriptPath = Path.Combine(
+ __SOURCE_DIRECTORY__
+ , "typeextensions"
+ , "issue.16034"
+ , "issue.16034.check1.fsx"
+ )
+ RealFsxFromPath scriptPath
+ |> withBaseLine
+ |> verifyFSXBaseline
+
+[]
+let ``issue.16034.check2`` () =
+ let scriptPath = Path.Combine(
+ __SOURCE_DIRECTORY__
+ , "typeextensions"
+ , "issue.16034"
+ , "issue.16034.check2.fsx"
+ )
+ RealFsxFromPath scriptPath
+ |> withBaseLine
+ |> verifyFSXBaseline
+
+
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check1.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check1.fsx
new file mode 100644
index 00000000000..c8c6bd6bc4f
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check1.fsx
@@ -0,0 +1,4 @@
+#load "issue.16034.fsx"
+open Issue.``16034``
+open Issue.``16034``.Extensions
+t.indexed1(aa1="nok") <- 1 // error FS0073: internal error: The input must be non-negative. (Parameter 'n') (ArgumentException)
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check1.fsx.actual.fsc.stdout.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check1.fsx.actual.fsc.stdout.bsl
new file mode 100644
index 00000000000..a691cf858db
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check1.fsx.actual.fsc.stdout.bsl
@@ -0,0 +1,25 @@
+
+
+Copyright (c) Microsoft Corporation. All Rights Reserved.
+
+For help type #help;;
+
+> [Loading /tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx
+ Loading /tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx]
+module FSI_0001.Issue.16034
+val mutable i: int
+type T =
+ new: unit -> T
+ member indexed1: a1: obj -> int with get
+ member indexed1: a1: obj -> int with set
+module Extensions =
+ val mutable j: int
+ type T with
+ member indexed1: aa1: obj -> int with get
+ type T with
+ member indexed1: aa1: obj -> int with set
+val t: T
+
+module FSI_0001.Issue.16034.check2
+
+error FS0073: internal error: The input must be non-negative. (Parameter 'n') (ArgumentException)
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx
new file mode 100644
index 00000000000..66bdbc2c992
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx
@@ -0,0 +1,4 @@
+#load "issue.16034.fsx"
+open Issue.``16034``
+open Issue.``16034``.Extensions
+t.indexed1(a1="nok") <- 1 // error FS0073: internal error: The input must be non-negative. (Parameter 'n') (ArgumentException)
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx.actual.fsc.stdout.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx.actual.fsc.stdout.bsl
new file mode 100644
index 00000000000..a691cf858db
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx.actual.fsc.stdout.bsl
@@ -0,0 +1,25 @@
+
+
+Copyright (c) Microsoft Corporation. All Rights Reserved.
+
+For help type #help;;
+
+> [Loading /tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx
+ Loading /tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.check2.fsx]
+module FSI_0001.Issue.16034
+val mutable i: int
+type T =
+ new: unit -> T
+ member indexed1: a1: obj -> int with get
+ member indexed1: a1: obj -> int with set
+module Extensions =
+ val mutable j: int
+ type T with
+ member indexed1: aa1: obj -> int with get
+ type T with
+ member indexed1: aa1: obj -> int with set
+val t: T
+
+module FSI_0001.Issue.16034.check2
+
+error FS0073: internal error: The input must be non-negative. (Parameter 'n') (ArgumentException)
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx
new file mode 100644
index 00000000000..cc76d018c9c
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx
@@ -0,0 +1,49 @@
+let mutable i = 0
+type T() =
+ member x.indexed1
+ with get (a1: obj) =
+ i <- i + 1
+ printfn $"T().indexed1 %A{a1} !\t%03i{i}"
+ 1
+ and set (a1: obj) (value: int) =
+ i <- i + 1
+ printfn $"T().indexed1 %A{a1} <- %i{value} !\t%03i{i}"
+
+module Extensions =
+ let mutable j = 0
+ type T with
+ member x.indexed1
+ with get (aa1: obj) =
+ i <- i + 1
+ j <- j + 1
+ printfn $"type extensions aa1 %A{aa1} !\t%03i{i}\t%03i{j}"
+ 1
+ and set (aa1: obj) (value: int) =
+ i <- i + 1
+ j <- j + 1
+ printfn $"type extension aa1 %A{aa1} <- %i{value}!\t%03i{i}\t%03i{j}"
+let t = T()
+t.indexed1 ["ok"] <- 1 // calls the intrinsic property
+t.indexed1 ("ok") <- 2 // calls the intrinsic property
+t.indexed1 "ok" <- 3 // calls the intrinsic property
+t.indexed1 "ok" // calls the intrinsic property
+t.get_indexed1 "ok" // calls the intrinsic property
+t.set_indexed1 (a1="ok",value=1) // calls the intrinsic property
+
+open Extensions
+
+t.indexed1 "nok" // calls the intrinsic property?
+t.indexed1 (a1="ok") // calls the intrinsic property
+t.indexed1 (aa1="ok") // calls the type extension property
+t.indexed1 ["nok"] <- 1 // calls the intrinsic property?
+t.indexed1 ("nok") <- 2 // calls the intrinsic property?
+t.indexed1 "nok" <- 3 // calls the intrinsic property?
+
+t.get_indexed1 ("nok") // calls the intrinsic property?
+t.get_indexed1 ["nok"] // calls the intrinsic property?
+t.get_indexed1 "nok" // calls the intrinsic property?
+
+t.set_indexed1 ("nok_015",1) // calls the intrinsic property?
+t.set_indexed1 ("nok_016",value=2) // calls the intrinsic property?
+t.set_indexed1 (a1="ok_017",value=1) // calls the intrinsic property
+t.set_indexed1 (aa1="ok_018",value=1) // calls the type extension property
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx.il.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx.il.bsl
new file mode 100644
index 00000000000..31b7175bb04
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx.il.bsl
@@ -0,0 +1,426 @@
+
+
+
+
+
+.assembly extern runtime { }
+.assembly extern FSharp.Core { }
+.assembly assembly
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32,
+ int32,
+ int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 )
+ .hash algorithm 0x00008004
+ .ver 0:0:0:0
+}
+.mresource public FSharpSignatureData.assembly
+{
+
+
+}
+.mresource public FSharpOptimizationData.assembly
+{
+
+
+}
+.module assembly.dll
+
+.imagebase {value}
+.file alignment 0x00000200
+.stackreserve 0x00100000
+.subsystem 0x0003
+.corflags 0x00000001
+
+
+
+
+
+.class public abstract auto ansi sealed Issue.'16034'
+ extends [runtime]System.Object
+{
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .class auto ansi serializable nested public T
+ extends [runtime]System.Object
+ {
+ .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
+ {
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: callvirt instance void [runtime]System.Object::.ctor()
+ IL_0006: ldarg.0
+ IL_0007: pop
+ IL_0008: ret
+ }
+
+ .method public hidebysig specialname
+ instance int32 get_indexed1(object a1) cil managed
+ {
+
+ .maxstack 7
+ IL_0000: call int32 Issue.'16034'::get_i()
+ IL_0005: ldc.i4.1
+ IL_0006: add
+ IL_0007: call void Issue.'16034'::set_i(int32)
+ IL_000c: ldstr "T().indexed1 %P() !\t%03i%P()"
+ IL_0011: ldc.i4.2
+ IL_0012: newarr [runtime]System.Object
+ IL_0017: dup
+ IL_0018: ldc.i4.0
+ IL_0019: ldarg.1
+ IL_001a: box [runtime]System.Object
+ IL_001f: stelem [runtime]System.Object
+ IL_0024: dup
+ IL_0025: ldc.i4.1
+ IL_0026: call int32 Issue.'16034'::get_i()
+ IL_002b: box [runtime]System.Int32
+ IL_0030: stelem [runtime]System.Object
+ IL_0035: ldnull
+ IL_0036: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5>::.ctor(string,
+ object[],
+ class [runtime]System.Type[])
+ IL_003b: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_0040: pop
+ IL_0041: ldc.i4.1
+ IL_0042: ret
+ }
+
+ .method public hidebysig specialname
+ instance void set_indexed1(object a1,
+ int32 'value') cil managed
+ {
+
+ .maxstack 7
+ IL_0000: call int32 Issue.'16034'::get_i()
+ IL_0005: ldc.i4.1
+ IL_0006: add
+ IL_0007: call void Issue.'16034'::set_i(int32)
+ IL_000c: ldstr "T().indexed1 %P() <- %P() !\t%03i%P()"
+ IL_0011: ldc.i4.3
+ IL_0012: newarr [runtime]System.Object
+ IL_0017: dup
+ IL_0018: ldc.i4.0
+ IL_0019: ldarg.1
+ IL_001a: box [runtime]System.Object
+ IL_001f: stelem [runtime]System.Object
+ IL_0024: dup
+ IL_0025: ldc.i4.1
+ IL_0026: ldarg.2
+ IL_0027: box [runtime]System.Int32
+ IL_002c: stelem [runtime]System.Object
+ IL_0031: dup
+ IL_0032: ldc.i4.2
+ IL_0033: call int32 Issue.'16034'::get_i()
+ IL_0038: box [runtime]System.Int32
+ IL_003d: stelem [runtime]System.Object
+ IL_0042: ldnull
+ IL_0043: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5>::.ctor(string,
+ object[],
+ class [runtime]System.Type[])
+ IL_0048: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_004d: pop
+ IL_004e: ret
+ }
+
+ .property instance int32 indexed1(object)
+ {
+ .set instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ .get instance int32 Issue.'16034'/T::get_indexed1(object)
+ }
+ }
+
+ .class abstract auto ansi sealed nested public Extensions
+ extends [runtime]System.Object
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
+ .method public specialname static int32
+ get_j() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldsfld int32 '.$Issue'.'16034$fsx'::j@13
+ IL_0005: ret
+ }
+
+ .method public specialname static void
+ set_j(int32 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: stsfld int32 '.$Issue'.'16034$fsx'::j@13
+ IL_0006: ret
+ }
+
+ .method public static int32 T.get_indexed1(class Issue.'16034'/T x,
+ object aa1) cil managed
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 )
+
+ .maxstack 7
+ IL_0000: call int32 Issue.'16034'::get_i()
+ IL_0005: ldc.i4.1
+ IL_0006: add
+ IL_0007: call void Issue.'16034'::set_i(int32)
+ IL_000c: call int32 Issue.'16034'/Extensions::get_j()
+ IL_0011: ldc.i4.1
+ IL_0012: add
+ IL_0013: call void Issue.'16034'/Extensions::set_j(int32)
+ IL_0018: ldstr "type extensions aa1 %P() !\t%03i%P()\t%03i%P()"
+ IL_001d: ldc.i4.3
+ IL_001e: newarr [runtime]System.Object
+ IL_0023: dup
+ IL_0024: ldc.i4.0
+ IL_0025: ldarg.1
+ IL_0026: box [runtime]System.Object
+ IL_002b: stelem [runtime]System.Object
+ IL_0030: dup
+ IL_0031: ldc.i4.1
+ IL_0032: call int32 Issue.'16034'::get_i()
+ IL_0037: box [runtime]System.Int32
+ IL_003c: stelem [runtime]System.Object
+ IL_0041: dup
+ IL_0042: ldc.i4.2
+ IL_0043: call int32 Issue.'16034'/Extensions::get_j()
+ IL_0048: box [runtime]System.Int32
+ IL_004d: stelem [runtime]System.Object
+ IL_0052: ldnull
+ IL_0053: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5>::.ctor(string,
+ object[],
+ class [runtime]System.Type[])
+ IL_0058: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_005d: pop
+ IL_005e: ldc.i4.1
+ IL_005f: ret
+ }
+
+ .method public static void T.set_indexed1(class Issue.'16034'/T x,
+ object aa1,
+ int32 'value') cil managed
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 02 00 00 00 00 00 )
+
+ .maxstack 7
+ IL_0000: call int32 Issue.'16034'::get_i()
+ IL_0005: ldc.i4.1
+ IL_0006: add
+ IL_0007: call void Issue.'16034'::set_i(int32)
+ IL_000c: call int32 Issue.'16034'/Extensions::get_j()
+ IL_0011: ldc.i4.1
+ IL_0012: add
+ IL_0013: call void Issue.'16034'/Extensions::set_j(int32)
+ IL_0018: ldstr "type extension aa1 %P() <- %P()!\t%03i%P()\t%03i%P()"
+ IL_001d: ldc.i4.4
+ IL_001e: newarr [runtime]System.Object
+ IL_0023: dup
+ IL_0024: ldc.i4.0
+ IL_0025: ldarg.1
+ IL_0026: box [runtime]System.Object
+ IL_002b: stelem [runtime]System.Object
+ IL_0030: dup
+ IL_0031: ldc.i4.1
+ IL_0032: ldarg.2
+ IL_0033: box [runtime]System.Int32
+ IL_0038: stelem [runtime]System.Object
+ IL_003d: dup
+ IL_003e: ldc.i4.2
+ IL_003f: call int32 Issue.'16034'::get_i()
+ IL_0044: box [runtime]System.Int32
+ IL_0049: stelem [runtime]System.Object
+ IL_004e: dup
+ IL_004f: ldc.i4.3
+ IL_0050: call int32 Issue.'16034'/Extensions::get_j()
+ IL_0055: box [runtime]System.Int32
+ IL_005a: stelem [runtime]System.Object
+ IL_005f: ldnull
+ IL_0060: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5>::.ctor(string,
+ object[],
+ class [runtime]System.Type[])
+ IL_0065: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4)
+ IL_006a: pop
+ IL_006b: ret
+ }
+
+ .property int32 j()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 )
+ .set void Issue.'16034'/Extensions::set_j(int32)
+ .get int32 Issue.'16034'/Extensions::get_j()
+ }
+ }
+
+ .method public specialname static int32
+ get_i() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldsfld int32 '.$Issue'.'16034$fsx'::i@1
+ IL_0005: ret
+ }
+
+ .method public specialname static void
+ set_i(int32 'value') cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldarg.0
+ IL_0001: stsfld int32 '.$Issue'.'16034$fsx'::i@1
+ IL_0006: ret
+ }
+
+ .method public specialname static class Issue.'16034'/T
+ get_t() cil managed
+ {
+
+ .maxstack 8
+ IL_0000: ldsfld class Issue.'16034'/T '.$Issue'.'16034$fsx'::t@25
+ IL_0005: ret
+ }
+
+ .property int32 i()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 )
+ .set void Issue.'16034'::set_i(int32)
+ .get int32 Issue.'16034'::get_i()
+ }
+ .property class Issue.'16034'/T t()
+ {
+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 09 00 00 00 00 00 )
+ .get class Issue.'16034'/T Issue.'16034'::get_t()
+ }
+}
+
+.class private abstract auto ansi sealed '.$Issue'.'16034$fsx'
+ extends [runtime]System.Object
+{
+ .field static assembly int32 i@1
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .field static assembly int32 j@13
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .field static assembly initonly class Issue.'16034'/T t@25
+ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 )
+ .field static assembly int32 init@
+ .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
+ {
+
+ .maxstack 5
+ IL_0000: ldc.i4.0
+ IL_0001: stsfld int32 '.$Issue'.'16034$fsx'::i@1
+ IL_0006: ldc.i4.0
+ IL_0007: stsfld int32 '.$Issue'.'16034$fsx'::j@13
+ IL_000c: newobj instance void Issue.'16034'/T::.ctor()
+ IL_0011: stsfld class Issue.'16034'/T '.$Issue'.'16034$fsx'::t@25
+ IL_0016: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_001b: ldstr "ok"
+ IL_0020: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty()
+ IL_0025: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0,
+ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)
+ IL_002a: ldc.i4.1
+ IL_002b: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_0030: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0035: ldstr "ok"
+ IL_003a: ldc.i4.2
+ IL_003b: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_0040: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0045: ldstr "ok"
+ IL_004a: ldc.i4.3
+ IL_004b: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_0050: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0055: ldstr "ok"
+ IL_005a: callvirt instance int32 Issue.'16034'/T::get_indexed1(object)
+ IL_005f: pop
+ IL_0060: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0065: ldstr "ok"
+ IL_006a: callvirt instance int32 Issue.'16034'/T::get_indexed1(object)
+ IL_006f: pop
+ IL_0070: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0075: ldstr "ok"
+ IL_007a: ldc.i4.1
+ IL_007b: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_0080: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0085: ldstr "nok"
+ IL_008a: callvirt instance int32 Issue.'16034'/T::get_indexed1(object)
+ IL_008f: pop
+ IL_0090: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0095: ldstr "ok"
+ IL_009a: callvirt instance int32 Issue.'16034'/T::get_indexed1(object)
+ IL_009f: pop
+ IL_00a0: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_00a5: ldstr "ok"
+ IL_00aa: call int32 Issue.'16034'/Extensions::T.get_indexed1(class Issue.'16034'/T,
+ object)
+ IL_00af: pop
+ IL_00b0: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_00b5: ldstr "nok"
+ IL_00ba: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty()
+ IL_00bf: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0,
+ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)
+ IL_00c4: ldc.i4.1
+ IL_00c5: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_00ca: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_00cf: ldstr "nok"
+ IL_00d4: ldc.i4.2
+ IL_00d5: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_00da: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_00df: ldstr "nok"
+ IL_00e4: ldc.i4.3
+ IL_00e5: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_00ea: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_00ef: ldstr "nok"
+ IL_00f4: callvirt instance int32 Issue.'16034'/T::get_indexed1(object)
+ IL_00f9: pop
+ IL_00fa: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_00ff: ldstr "nok"
+ IL_0104: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::get_Empty()
+ IL_0109: call class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1 class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1::Cons(!0,
+ class [FSharp.Core]Microsoft.FSharp.Collections.FSharpList`1)
+ IL_010e: callvirt instance int32 Issue.'16034'/T::get_indexed1(object)
+ IL_0113: pop
+ IL_0114: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0119: ldstr "nok"
+ IL_011e: callvirt instance int32 Issue.'16034'/T::get_indexed1(object)
+ IL_0123: pop
+ IL_0124: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0129: ldstr "nok_015"
+ IL_012e: ldc.i4.1
+ IL_012f: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_0134: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0139: ldstr "nok_016"
+ IL_013e: ldc.i4.2
+ IL_013f: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_0144: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0149: ldstr "ok_017"
+ IL_014e: ldc.i4.1
+ IL_014f: callvirt instance void Issue.'16034'/T::set_indexed1(object,
+ int32)
+ IL_0154: call class Issue.'16034'/T Issue.'16034'::get_t()
+ IL_0159: ldstr "ok_018"
+ IL_015e: ldc.i4.1
+ IL_015f: call void Issue.'16034'/Extensions::T.set_indexed1(class Issue.'16034'/T,
+ object,
+ int32)
+ IL_0164: ret
+ }
+
+}
+
+
+
+
+
diff --git a/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx.stdout.bsl b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx.stdout.bsl
new file mode 100644
index 00000000000..b0f9ffd34b2
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/TypeChecks/typeextensions/issue.16034/issue.16034.fsx.stdout.bsl
@@ -0,0 +1,19 @@
+T().indexed1 [ok] <- 1 ! 001
+T().indexed1 ok <- 2 ! 002
+T().indexed1 ok <- 3 ! 003
+T().indexed1 ok ! 004
+T().indexed1 ok ! 005
+T().indexed1 ok <- 1 ! 006
+T().indexed1 nok ! 007
+T().indexed1 ok ! 008
+type extensions aa1 ok ! 009 001
+T().indexed1 [nok] <- 1 ! 010
+T().indexed1 nok <- 2 ! 011
+T().indexed1 nok <- 3 ! 012
+T().indexed1 nok ! 013
+T().indexed1 [nok] ! 014
+T().indexed1 nok ! 015
+T().indexed1 nok_015 <- 1 ! 016
+T().indexed1 nok_016 <- 2 ! 017
+T().indexed1 ok_017 <- 1 ! 018
+type extension aa1 ok_018 <- 1! 019 002
diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs
index aabefaf4b35..622b7ee43bd 100644
--- a/tests/FSharp.Test.Utilities/Compiler.fs
+++ b/tests/FSharp.Test.Utilities/Compiler.fs
@@ -206,6 +206,87 @@ module rec Compiler =
| Arm = 5
| Arm64 = 6
+ module NamingConventions =
+ let forActualFSCOutput sourceFilePath = sourceFilePath + ".actual.fsc.stdout.err"
+ let forActualIL sourceFilePath = sourceFilePath + ".actual.il.err"
+ let forBaselineFSCOutput sourceFilePath = sourceFilePath + ".fsc.stdout.bsl"
+
+ let forBaseLineIL sourceFilePath =
+ let ilBslPaths = [|
+ #if DEBUG
+ #if NETCOREAPP
+ yield sourceFilePath + ".il.netcore.debug.bsl"
+ yield sourceFilePath + ".il.netcore.bsl"
+ #else
+ yield sourceFilePath + ".il.net472.debug.bsl"
+ yield sourceFilePath + ".il.net472.bsl"
+ #endif
+ yield sourceFilePath + ".il.debug.bsl"
+ yield sourceFilePath + ".il.bsl"
+ #else
+ #if NETCOREAPP
+ yield sourceFilePath + ".il.netcore.release.bsl"
+ yield sourceFilePath + ".il.netcore.bsl"
+ #else
+ yield sourceFilePath + ".il.net472.release.bsl"
+ yield sourceFilePath + ".il.net472.bsl"
+ #endif
+ yield sourceFilePath + ".il.release.bsl"
+ yield sourceFilePath + ".il.bsl"
+ #endif
+ |]
+
+ let findBaseline =
+ ilBslPaths
+ |> Array.tryPick(fun p -> if File.Exists p then Some p else None)
+ match findBaseline with
+ | Some s -> s
+ | None -> sourceFilePath + ".il.bsl"
+
+ type BaseLineHelper =
+
+
+
+
+ static member readFileOrDefault (path: string) : string option =
+ match FileSystem.FileExistsShim(path) with
+ | true -> Some (File.ReadAllText path)
+ | _ -> None
+
+ static member makeBaseLine(sourceFilePath, ?baselineSuffix) =
+ let baselineSuffix = Option.defaultValue "" baselineSuffix
+ let fsBslFilePath = NamingConventions.forBaselineFSCOutput sourceFilePath
+ let ilBslFilePath = NamingConventions.forBaseLineIL (sourceFilePath + baselineSuffix)
+
+ let fsOutFilePath = normalizePathSeparator <| NamingConventions.forActualFSCOutput sourceFilePath
+ let ilOutFilePath = normalizePathSeparator <| NamingConventions.forActualIL sourceFilePath
+ let fsBslSource = BaseLineHelper.readFileOrDefault fsBslFilePath
+ let ilBslSource = BaseLineHelper.readFileOrDefault ilBslFilePath
+
+ {
+ SourceFilename = Some sourceFilePath
+ FSBaseline = { FilePath = fsOutFilePath; BslSource=fsBslFilePath; Content = fsBslSource }
+ ILBaseline = { FilePath = ilOutFilePath; BslSource=ilBslFilePath ; Content = ilBslSource }
+ }
+ static member makeLegacyBaseLine(sourceFilePath, ?baselineSuffix) =
+ // using change extension is problematic, hence only for legacy baseline
+ let forActualFSCOutput sourceFilePath = Path.ChangeExtension(sourceFilePath, ".err")
+ let forActualIL sourceFilePath = Path.ChangeExtension(sourceFilePath, ".il")
+
+ let baselineSuffix = Option.defaultValue "" baselineSuffix
+ let fsBslFilePath = NamingConventions.forBaselineFSCOutput sourceFilePath
+ let ilBslFilePath = NamingConventions.forBaseLineIL (sourceFilePath + baselineSuffix)
+
+ let fsOutFilePath = normalizePathSeparator <| forActualFSCOutput sourceFilePath
+ let ilOutFilePath = normalizePathSeparator <| forActualIL sourceFilePath
+ let fsBslSource = BaseLineHelper.readFileOrDefault fsBslFilePath
+ let ilBslSource = BaseLineHelper.readFileOrDefault ilBslFilePath
+
+ {
+ SourceFilename = Some sourceFilePath
+ FSBaseline = { FilePath = fsOutFilePath; BslSource=fsBslFilePath; Content = fsBslSource }
+ ILBaseline = { FilePath = ilOutFilePath; BslSource=ilBslFilePath ; Content = ilBslSource }
+ }
let private defaultOptions : string list = []
let normalizePathSeparator (text:string) = text.Replace(@"\", "/")
@@ -353,6 +434,12 @@ module rec Compiler =
let Fsx (source: string) : CompilationUnit =
fsFromString (FsxSourceCode source) |> FS
+ let RealFsxFromPath (path: string) =
+ path
+ |> SourceCodeFileKind.CreateReal
+ |> fsFromString
+ |> FS
+
let FsxFromPath (path: string) : CompilationUnit =
fsFromString (SourceFromPath path) |> FS
@@ -456,7 +543,12 @@ module rec Compiler =
let withDebug (cUnit: CompilationUnit) : CompilationUnit =
withOptionsHelper [ "--debug+" ] "debug+ is only supported on F#" cUnit
-
+ let withBaseLine cUnit =
+ match cUnit with
+ | CompilationUnit.FS fs ->
+ let sourceFileName = fs.Source.GetSourceFileName
+ FS { fs with Baseline = Some(BaseLineHelper.makeBaseLine(sourceFileName)) }
+ | _ -> cUnit
let withNoDebug (cUnit: CompilationUnit) : CompilationUnit =
withOptionsHelper [ "--debug-" ] "debug- is only supported on F#" cUnit
@@ -945,7 +1037,14 @@ module rec Compiler =
match s.OutputPath with
| None -> failwith "Compilation didn't produce any output. Unable to run. (Did you forget to set output type to Exe?)"
| Some p ->
- let (exitCode, output, errors) = CompilerAssert.ExecuteAndReturnResult (p, s.Dependencies, false)
+ let isFsx =
+ match s.Compilation with
+ | FS fs ->
+ match fs.Source with
+ | SourceCodeFileKind.Fsx _ -> true
+ | _ -> false
+ | _ -> false
+ let (exitCode, output, errors) = CompilerAssert.ExecuteAndReturnResult (p, isFsx, s.Dependencies, false)
printfn "---------output-------\n%s\n-------" output
printfn "---------errors-------\n%s\n-------" errors
let executionResult = { s with Output = Some (ExecutionOutput { ExitCode = exitCode; StdOut = output; StdErr = errors }) }
@@ -1076,7 +1175,8 @@ module rec Compiler =
let private createBaselineErrors (baselineFile: BaselineFile) (actualErrors: string) : unit =
- FileSystem.OpenFileForWriteShim(baselineFile.FilePath + ".err").Write(actualErrors)
+ printfn $"creating baseline error file for convenience {baselineFile}"
+ FileSystem.OpenFileForWriteShim(baselineFile.FilePath).Write(actualErrors)
let private verifyFSBaseline (fs) : unit =
match fs.Baseline with
@@ -1086,10 +1186,19 @@ module rec Compiler =
match bsl.FSBaseline.Content with
| Some b -> b.Replace("\r\n","\n")
| None -> String.Empty
-
- let typecheckDiagnostics = fs |> typecheckFSharpSourceAndReturnErrors
-
- let errorsActual = (typecheckDiagnostics |> Array.map (sprintf "%A") |> String.concat "\n").Replace("\r\n","\n")
+ let errorsActual =
+ match fs.Source with
+ | SourceCodeFileKind.Fsx _->
+ let fsxScriptFile = FileInfo fs.Source.GetSourceFileName
+ //let dir = fsxScriptFile.Directory
+ //RunRealScriptWithOptionsAndReturnResult
+ let fsxResult = CompilerAssert.RunRealScriptWithOptionsAndReturnResult [||] fsxScriptFile
+
+ snd fsxResult |> sanitizeFsxOutput
+ | SourceCodeFileKind.Fs _->
+ let typecheckDiagnostics = fs |> typecheckFSharpSourceAndReturnErrors
+ (typecheckDiagnostics |> Array.map (sprintf "%A") |> String.concat "\n").Replace("\r\n","\n")
+ | _ -> failwith $"not supposed to check %A{fs.Source}"
if errorsExpectedBaseLine <> errorsActual then
fs.CreateOutputDirectory()
@@ -1122,29 +1231,31 @@ module rec Compiler =
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
-
- 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
- if snd (Int32.TryParse(Environment.GetEnvironmentVariable("TEST_UPDATE_BSL"))) <> 0 then
- match baseline with
- | Some baseline -> System.IO.File.Copy(baseline.ILBaseline.FilePath, baseline.ILBaseline.BslSource, true)
- | None -> ()
-
- createBaselineErrors bsl.ILBaseline actualIL
- Assert.Fail(errorMsg)
+ match result.OutputPath with
+ | None -> failwith "Operation didn't produce any output!"
+ | Some p ->
+ match baseline with
+ | None -> failwith "Baseline was not provided."
+ | Some bsl ->
+ let expectedIL =
+ match bsl.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
+ if snd (Int32.TryParse(Environment.GetEnvironmentVariable("TEST_UPDATE_BSL"))) <> 0 then
+ match baseline with
+ | Some baseline -> System.IO.File.Copy(baseline.ILBaseline.FilePath, baseline.ILBaseline.FilePath, true)
+ | None -> ()
+
+ createBaselineErrors bsl.ILBaseline actualIL
+ let messagePrefix = $"failed IL base line\nactual file: {baseline.Value.ILBaseline.FilePath}\nexpected file: {baseline.Value.ILBaseline.BslSource}\n"
+ Assert.Fail(messagePrefix + errorMsg)
let verifyILBaseline (cUnit: CompilationUnit) : CompilationUnit =
match cUnit with
@@ -1177,6 +1288,14 @@ module rec Compiler =
let pattern = @"(Microsoft \(R\) (.*) version (.*) F# (.*))"
let result = regexStrip output pattern (RegexOptions.Multiline ||| RegexOptions.ExplicitCapture)
result
+ let sanitizeFsxOutput output =
+ let slndir = (DirectoryInfo __SOURCE_DIRECTORY__).Parent.Parent.FullName
+ let pattern = @"(Microsoft \(R\) (.*) version (.*) F# (.*))"
+ let output = regexStrip output pattern (RegexOptions.Multiline ||| RegexOptions.ExplicitCapture)
+ let pattern = @"\n\nCopyright (c) Microsoft Corporation. All Rights Reserved.\n\n"
+ let output = regexStrip output pattern (RegexOptions.Multiline ||| RegexOptions.ExplicitCapture)
+ output.Replace(slndir, "")
+
let getOutput (cResult: CompilationResult) : string option =
let result =
@@ -1198,10 +1317,25 @@ module rec Compiler =
| Some actual ->
let expected = stripVersion (normalizeNewlines expected)
if expected <> actual then
- failwith $"""Output does not match expected: ------------{Environment.NewLine}{expected}{Environment.NewLine}Actual: ------------{Environment.NewLine}{actual}{Environment.NewLine}"""
+ let errFile =
+ match cResult.Output.Compilation with
+ | FS s -> s.Source.GetSourceFileName + ".stdout.err"
+ | _ -> failwith "not supposed to check output of non F# source"
+ File.WriteAllText(errFile, actual)
+ failwith $"""Output does not match expected, err file generated at {errFile} for your convenience: \n ------------{Environment.NewLine}{expected}{Environment.NewLine}Actual: ------------{Environment.NewLine}{actual}{Environment.NewLine}"""
else
cResult
+ let verifyOutputWithDefaultBaseline (cResult: CompilationResult) =
+ let expected =
+ match cResult.Output.Compilation with
+ | FS s ->
+ s.Source.GetSourceFileName + ".stdout.bsl"
+ |> File.ReadAllText
+ |> normalizeNewlines
+ |> stripVersion
+ | _ -> failwith "not supposed to check output of non F# source"
+ verifyOutput expected cResult
let verifyOutputWithBaseline path =
verifyOutput (File.ReadAllText(path).Replace(@"\r\n", Environment.NewLine))
diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs
index a0eea96e1d4..01d40fe666f 100644
--- a/tests/FSharp.Test.Utilities/CompilerAssert.fs
+++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs
@@ -59,6 +59,13 @@ type SourceCodeFileKind =
| ".fsx" -> Fsx({FileName=path; SourceText=source})
| ".cs" -> Cs({FileName=path; SourceText=source})
| ".fs" | _ -> Fs({FileName=path; SourceText=source})
+ static member CreateReal(path:string) =
+ let source = Some(File.ReadAllText path)
+ match Path.GetExtension(path).ToLowerInvariant() with
+ | ".fsi" -> Fsi({FileName=path; SourceText=source})
+ | ".fsx" -> Fsx({FileName=path; SourceText=source})
+ | ".cs" -> Cs({FileName=path; SourceText=source})
+ | ".fs" | _ -> Fs({FileName=path; SourceText=source})
member this.ChangeExtension =
match this with
@@ -261,18 +268,24 @@ module rec CompilerAssertHelpers =
let checker = FSharpChecker.Create(suggestNamesForErrors=true)
// Unlike C# whose entrypoint is always string[] F# can make an entrypoint with 0 args, or with an array of string[]
- let mkDefaultArgs (entryPoint:MethodInfo) : obj[] = [|
- if entryPoint.GetParameters().Length = 1 then
+ let mkDefaultArgs (entryPoint:MethodBase) : obj[] = [|
+ if not (isNull entryPoint) && entryPoint.GetParameters().Length = 1 then
yield Array.empty
|]
- let executeAssemblyEntryPoint (asm: Assembly) =
- let entryPoint = asm.EntryPoint
+ let executeAssemblyEntryPoint (asm: Assembly) isFsx =
+ let entryPoint : MethodBase = asm.EntryPoint
+ let entryPoint =
+ if isNull entryPoint && isFsx then
+ let moduleInitType = asm.GetTypes() |> Array.last
+ moduleInitType.GetConstructors(BindingFlags.Static ||| BindingFlags.NonPublic).[0] :> MethodBase
+ else
+ entryPoint
let args = mkDefaultArgs entryPoint
captureConsoleOutputs (fun () -> entryPoint.Invoke(Unchecked.defaultof, args) |> ignore)
#if NETCOREAPP
- let executeBuiltApp assembly deps =
+ let executeBuiltApp assembly deps isFsx =
let ctxt = AssemblyLoadContext("ContextName", true)
try
ctxt.add_Resolving(fun ctxt name ->
@@ -281,7 +294,7 @@ module rec CompilerAssertHelpers =
|> Option.map ctxt.LoadFromAssemblyPath
|> Option.defaultValue null)
- ctxt.LoadFromAssemblyPath assembly |> executeAssemblyEntryPoint
+ executeAssemblyEntryPoint (ctxt.LoadFromAssemblyPath assembly) isFsx
finally
ctxt.Unload()
#else
@@ -577,8 +590,8 @@ module rec CompilerAssertHelpers =
succeeded, stdout.ToString(), stderr.ToString(), exn
- let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) : (int * string * string) =
- let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps
+ let executeBuiltAppAndReturnResult (outputFilePath: string) (deps: string list) isFsx : (int * string * string) =
+ let succeeded, stdout, stderr, _ = executeBuiltApp outputFilePath deps isFsx
let exitCode = if succeeded then 0 else -1
exitCode, stdout, stderr
@@ -681,10 +694,10 @@ Updated automatically, please check diffs in your pull request, changes must be
static member CompileRaw(cmpl: Compilation, ?ignoreWarnings) =
returnCompilation cmpl (defaultArg ignoreWarnings false)
- static member ExecuteAndReturnResult (outputFilePath: string, deps: string list, newProcess: bool) =
+ static member ExecuteAndReturnResult (outputFilePath: string, isFsx: bool, deps: string list, newProcess: bool) =
// If we execute in-process (true by default), then the only way of getting STDOUT is to redirect it to SB, and STDERR is from catching an exception.
if not newProcess then
- executeBuiltAppAndReturnResult outputFilePath deps
+ executeBuiltAppAndReturnResult outputFilePath deps isFsx
else
executeBuiltAppNewProcessAndReturnResult outputFilePath
@@ -710,7 +723,7 @@ Updated automatically, please check diffs in your pull request, changes must be
Assert.Fail errors
onOutput output
else
- let _succeeded, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps
+ let _succeeded, _stdout, _stderr, exn = executeBuiltApp outputFilePath deps false
exn |> Option.iter raise)
static member ExecutionHasOutput(cmpl: Compilation, expectedOutput: string) =
@@ -776,6 +789,7 @@ Updated automatically, please check diffs in your pull request, changes must be
let errors =
let parseResults, fileAnswer =
let defaultOptions = defaultProjectOptions TargetFramework.Current
+
checker.ParseAndCheckFileInProject(
name,
0,
@@ -960,6 +974,42 @@ Updated automatically, please check diffs in your pull request, changes must be
errorMessages, outStream.ToString()
+ static member RunRealScriptWithOptionsAndReturnResult options (scriptFile: FileInfo) =
+ //let savedDir = Environment.CurrentDirectory
+ //use _ = { new IDisposable with member x.Dispose() = Environment.CurrentDirectory <- savedDir }
+ //Environment.CurrentDirectory <- scriptFile.Directory.FullName
+
+
+ // Intialize output and input streams
+ use inStream = new StringReader("")
+ use outStream = new StringWriter()
+ use errStream = new StringWriter()
+
+ // Build command line arguments & start FSI session
+ let argv = [| "C:\\fsi.exe" |]
+#if NETCOREAPP
+ let args = Array.append argv [|"--noninteractive"; "--targetprofile:netcore"|]
+#else
+ let args = Array.append argv [|"--noninteractive"; "--targetprofile:mscorlib"|]
+#endif
+ let allArgs = Array.append args options
+
+ let fsiConfig = FsiEvaluationSession.GetDefaultConfiguration()
+ use fsiSession = FsiEvaluationSession.Create(fsiConfig, allArgs, inStream, outStream, errStream, collectible = true)
+ fsiSession.EvalInteraction($"""#cd @"{scriptFile.Directory.FullName}";; """)
+ let ch, errors = fsiSession.EvalScriptNonThrowing scriptFile.FullName
+
+ let errorMessages = ResizeArray()
+ errors
+ |> Seq.iter (fun error -> errorMessages.Add(error.Message))
+
+ match ch with
+ | Choice2Of2 ex -> errorMessages.Add(ex.Message)
+ | _ -> ()
+
+ errorMessages, outStream.ToString()
+
+
static member RunScriptWithOptions options (source: string) (expectedErrorMessages: string list) =
let errorMessages, _ = CompilerAssert.RunScriptWithOptionsAndReturnResult options source
if expectedErrorMessages.Length <> errorMessages.Count then
diff --git a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs
index fbb40b70b17..b01a149d30f 100644
--- a/tests/FSharp.Test.Utilities/DirectoryAttribute.fs
+++ b/tests/FSharp.Test.Utilities/DirectoryAttribute.fs
@@ -26,11 +26,6 @@ type DirectoryAttribute(dir: string) =
let mutable baselineSuffix = ""
let mutable includes = Array.empty
- let readFileOrDefault (path: string) : string option =
- match FileSystem.FileExistsShim(path) with
- | true -> Some (File.ReadAllText path)
- | _ -> None
-
let createCompilationUnit path (filename: string) methodName multipleFiles =
// if there are multiple files being processed, add extra directory for each test to avoid reference file conflicts
let extraDirectory =
@@ -39,58 +34,15 @@ type DirectoryAttribute(dir: string) =
|> normalizeName
else ""
let outputDirectory = outputDirectory methodName extraDirectory
- let outputDirectoryPath =
+ let _outputDirectoryPath =
match outputDirectory with
| Some path -> path.FullName
| None -> failwith "Can't set the output directory"
let sourceFilePath = normalizePathSeparator (path ++ filename)
- let fsBslFilePath = sourceFilePath + ".err.bsl"
- let ilBslFilePath =
- let ilBslPaths = [|
-#if DEBUG
- #if NETCOREAPP
- yield sourceFilePath + baselineSuffix + ".il.netcore.debug.bsl"
- yield sourceFilePath + baselineSuffix + ".il.netcore.bsl"
- #else
- yield sourceFilePath + baselineSuffix + ".il.net472.debug.bsl"
- yield sourceFilePath + baselineSuffix + ".il.net472.bsl"
- #endif
- yield sourceFilePath + baselineSuffix + ".il.debug.bsl"
- yield sourceFilePath + baselineSuffix + ".il.bsl"
-#else
- #if NETCOREAPP
- yield sourceFilePath + baselineSuffix + ".il.netcore.release.bsl"
- yield sourceFilePath + baselineSuffix + ".il.netcore.bsl"
- #else
- yield sourceFilePath + baselineSuffix + ".il.net472.release.bsl"
- yield sourceFilePath + baselineSuffix + ".il.net472.bsl"
- #endif
- yield sourceFilePath + baselineSuffix + ".il.release.bsl"
- yield sourceFilePath + baselineSuffix + ".il.bsl"
-#endif
- |]
-
- let findBaseline =
- ilBslPaths
- |> Array.tryPick(fun p -> if File.Exists(p) then Some p else None)
- match findBaseline with
- | Some s -> s
- | None -> sourceFilePath + baselineSuffix + ".il.bsl"
-
- let fsOutFilePath = normalizePathSeparator (Path.ChangeExtension(outputDirectoryPath ++ filename, ".err"))
- let ilOutFilePath = normalizePathSeparator ( Path.ChangeExtension(outputDirectoryPath ++ filename, ".il"))
- let fsBslSource = readFileOrDefault fsBslFilePath
- let ilBslSource = readFileOrDefault ilBslFilePath
-
+
{ Source = SourceCodeFileKind.Create(sourceFilePath)
AdditionalSources = []
- Baseline =
- Some
- {
- SourceFilename = Some sourceFilePath
- FSBaseline = { FilePath = fsOutFilePath; BslSource=fsBslFilePath; Content = fsBslSource }
- ILBaseline = { FilePath = ilOutFilePath; BslSource=ilBslFilePath ; Content = ilBslSource }
- }
+ Baseline = Some (BaseLineHelper.makeLegacyBaseLine(sourceFilePath, baselineSuffix))
Options = []
OutputType = Library
Name = Some filename