From 41ae26ce8a1d3b6dab791755dcff0344f73b80ad Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Fri, 24 Jan 2020 21:04:16 +0100 Subject: [PATCH 1/4] add a failing test exhibiting issue #8351 --- tests/FSharp.TestHelpers/TestFramework.fs | 12 +++++++++++- .../fsharp/core/members/set-only-property/cs.cs | 7 +++++++ .../fsharp/core/members/set-only-property/fs.fs | 16 ++++++++++++++++ .../fsharp/core/members/set-only-property/vb.vb | 10 ++++++++++ tests/fsharp/tests.fs | 11 ++++++++++- 5 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 tests/fsharp/core/members/set-only-property/cs.cs create mode 100644 tests/fsharp/core/members/set-only-property/fs.fs create mode 100644 tests/fsharp/core/members/set-only-property/vb.vb diff --git a/tests/FSharp.TestHelpers/TestFramework.fs b/tests/FSharp.TestHelpers/TestFramework.fs index 63ab601024b..4392998973e 100644 --- a/tests/FSharp.TestHelpers/TestFramework.fs +++ b/tests/FSharp.TestHelpers/TestFramework.fs @@ -96,6 +96,9 @@ module Commands = let csc exec cscExe flags srcFiles = exec cscExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " ")) + let vbc exec vbcExe flags srcFiles = + exec vbcExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " ")) + let fsi exec fsiExe flags sources = exec fsiExe (sprintf "%s %s" flags (sources |> Seq.ofList |> String.concat " ")) @@ -123,6 +126,8 @@ type TestConfig = { EnvironmentVariables : Map CSC : string csc_flags : string + VBC : string + vbc_flags : string BUILD_CONFIG : string FSC : string fsc_flags : string @@ -183,11 +188,13 @@ let config configurationName envVars = let artifactsBinPath = artifactsPath ++ "bin" let coreClrRuntimePackageVersion = "3.0.0-preview-27318-01" let csc_flags = "/nologo" + let vbc_flags = "/nologo" let fsc_flags = "-r:System.Core.dll --nowarn:20 --define:COMPILED" let fsi_flags = "-r:System.Core.dll --nowarn:20 --define:INTERACTIVE --maxerrors:1 --abortonerror" let Is64BitOperatingSystem = WindowsPlatform.Is64BitOperatingSystem envVars let architectureMoniker = if Is64BitOperatingSystem then "x64" else "x86" let CSC = requireFile (packagesDir ++ "Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "csc.exe") + let VBC = requireFile (packagesDir ++ "Microsoft.Net.Compilers" ++ "2.7.0" ++ "tools" ++ "vbc.exe") let ILDASM = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.ILDAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "ildasm.exe") let ILASM = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.ILAsm") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "ilasm.exe") let coreclrdll = requireFile (packagesDir ++ ("runtime.win-" + architectureMoniker + ".Microsoft.NETCore.Runtime.CoreCLR") ++ coreClrRuntimePackageVersion ++ "runtimes" ++ ("win-" + architectureMoniker) ++ "native" ++ "coreclr.dll") @@ -223,6 +230,7 @@ let config configurationName envVars = ILDASM = ILDASM ILASM = ILASM PEVERIFY = PEVERIFY + VBC = VBC CSC = CSC BUILD_CONFIG = configurationName FSC = FSC @@ -235,7 +243,8 @@ let config configurationName envVars = FSharpCompilerInteractiveSettings = FSharpCompilerInteractiveSettings csc_flags = csc_flags fsc_flags = fsc_flags - fsi_flags = fsi_flags + fsi_flags = fsi_flags + vbc_flags = vbc_flags Directory="" DotNetExe = dotNetExe DefaultPlatform = defaultPlatform } @@ -462,6 +471,7 @@ let fscBothToOut cfg out arg = Printf.ksprintf (Commands.fsc cfg.Directory (exec let fscBothToOutExpectFail cfg out arg = Printf.ksprintf (Commands.fsc cfg.Directory (execBothToOutExpectFail cfg cfg.Directory out) cfg.DotNetExe cfg.FSC) arg let fscAppendErrExpectFail cfg errPath arg = Printf.ksprintf (Commands.fsc cfg.Directory (execAppendErrExpectFail cfg errPath) cfg.DotNetExe cfg.FSC) arg let csc cfg arg = Printf.ksprintf (Commands.csc (exec cfg) cfg.CSC) arg +let vbc cfg arg = Printf.ksprintf (Commands.vbc (exec cfg) cfg.VBC) arg let ildasm cfg arg = Printf.ksprintf (Commands.ildasm (exec cfg) cfg.ILDASM) arg let ilasm cfg arg = Printf.ksprintf (Commands.ilasm (exec cfg) cfg.ILASM) arg let peverify cfg = Commands.peverify (exec cfg) cfg.PEVERIFY "/nologo" diff --git a/tests/fsharp/core/members/set-only-property/cs.cs b/tests/fsharp/core/members/set-only-property/cs.cs new file mode 100644 index 00000000000..5323a3ffb96 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/cs.cs @@ -0,0 +1,7 @@ +namespace csharp +{ + public class Class + { + public int Prop { set; private get; } + } +} \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/fs.fs b/tests/fsharp/core/members/set-only-property/fs.fs new file mode 100644 index 00000000000..c259737a126 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/fs.fs @@ -0,0 +1,16 @@ +type Class () = + let mutable v = 0 + member x.Prop with set(value) = v <- value + +let a = csharp.Class(Prop=1) +let b = basic.BasicClass(Prop=1) +let c = Class(Prop=1) + +type Maker = + static member mkCs () = csharp.Class() + static member mkVb () = basic.BasicClass() + static member mkFs () = Class() + +let aa = Maker.mkCs(Prop=1) +let bb = Maker.mkVb(Prop=1) +let cc = Maker.mkFs(Prop=1) \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/vb.vb b/tests/fsharp/core/members/set-only-property/vb.vb new file mode 100644 index 00000000000..5985cda5a32 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/vb.vb @@ -0,0 +1,10 @@ +namespace basic + public class BasicClass + dim v as integer + public writeonly property Prop as integer + set(value as integer) + v = value + end set + end property + end class +end namespace \ No newline at end of file diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 19e8c725f48..c04f80ac438 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -288,7 +288,7 @@ module CoreTests = testOkFile.CheckExists() end - + [] let span () = @@ -1813,6 +1813,15 @@ module CoreTests = fsc cfg "%s -o:xmlverify.exe -g" cfg.fsc_flags ["xmlverify.fs"] peverifyWithArgs cfg "/nologo" "xmlverify.exe" + + + [] + let ``property setter in method or constructor`` () = + let cfg = testConfig "core/members/set-only-property" + csc cfg @"%s /target:library /out:cs.dll" cfg.csc_flags ["cs.cs"] + vbc cfg @"%s /target:library /out:vb.dll" cfg.vbc_flags ["vb.vb"] + fsc cfg @"%s -r:cs.dll -r:vb.dll -o:fs.exe" cfg.fsc_flags ["fs.fs"] + #endif module VersionTests = From 974df04bc1223b3dd43f81a6b4d39ad8dc6b6545 Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sat, 25 Jan 2020 00:49:57 +0100 Subject: [PATCH 2/4] updating VB and F# code to have private getter as well, VB has same issue as C#. --- tests/fsharp/core/members/set-only-property/fs.fs | 1 + tests/fsharp/core/members/set-only-property/vb.vb | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/fsharp/core/members/set-only-property/fs.fs b/tests/fsharp/core/members/set-only-property/fs.fs index c259737a126..a1ef197b533 100644 --- a/tests/fsharp/core/members/set-only-property/fs.fs +++ b/tests/fsharp/core/members/set-only-property/fs.fs @@ -1,6 +1,7 @@ type Class () = let mutable v = 0 member x.Prop with set(value) = v <- value + and private get () = v let a = csharp.Class(Prop=1) let b = basic.BasicClass(Prop=1) diff --git a/tests/fsharp/core/members/set-only-property/vb.vb b/tests/fsharp/core/members/set-only-property/vb.vb index 5985cda5a32..6cd42330603 100644 --- a/tests/fsharp/core/members/set-only-property/vb.vb +++ b/tests/fsharp/core/members/set-only-property/vb.vb @@ -1,7 +1,10 @@ namespace basic public class BasicClass dim v as integer - public writeonly property Prop as integer + public property Prop as integer + private get + return v + end get set(value as integer) v = value end set From 43158a3b925b5609d2ad6dadd958ef5e45d5522b Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sat, 25 Jan 2020 18:14:52 +0100 Subject: [PATCH 3/4] Furthering the test, all languages exhibit the same issue. Added another property that is expected to fail, exhibiting inconsistencies in how the error is reported depending if the type is defined in F# or not. --- .../core/members/set-only-property/calls.bsl | 20 ++++++++++++++++ .../core/members/set-only-property/calls.fsx | 24 +++++++++++++++++++ .../core/members/set-only-property/cs.cs | 5 ++-- .../core/members/set-only-property/fs.fs | 19 ++++----------- .../core/members/set-only-property/vb.vb | 10 +++++++- tests/fsharp/tests.fs | 5 ++-- 6 files changed, 64 insertions(+), 19 deletions(-) create mode 100644 tests/fsharp/core/members/set-only-property/calls.bsl create mode 100644 tests/fsharp/core/members/set-only-property/calls.fsx diff --git a/tests/fsharp/core/members/set-only-property/calls.bsl b/tests/fsharp/core/members/set-only-property/calls.bsl new file mode 100644 index 00000000000..202d99e89be --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/calls.bsl @@ -0,0 +1,20 @@ + +calls.fsx(9,22,9,27): typecheck error FS0495: The object constructor 'Class' has no argument or settable return property 'Prop1'. The required signature is csharp.Class() : csharp.Class. + +calls.fsx(10,26,10,31): typecheck error FS0495: The object constructor 'BasicClass' has no argument or settable return property 'Prop1'. The required signature is basic.BasicClass() : basic.BasicClass. + +calls.fsx(13,21,13,26): typecheck error FS0495: The member or object constructor 'mkCs' has no argument or settable return property 'Prop1'. The required signature is static member Maker.mkCs : unit -> csharp.Class. + +calls.fsx(14,21,14,26): typecheck error FS0495: The member or object constructor 'mkVb' has no argument or settable return property 'Prop1'. The required signature is static member Maker.mkVb : unit -> basic.BasicClass. + +calls.fsx(18,30,18,31): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(19,34,19,35): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(20,24,20,29): typecheck error FS0495: The object constructor 'Class' has no argument or settable return property 'Prop2'. The required signature is new : unit -> fsharp.Class. + +calls.fsx(22,29,22,30): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(23,29,23,30): typecheck error FS0629: Method 'set_Prop2' is not accessible from this code location + +calls.fsx(24,23,24,28): typecheck error FS0495: The member or object constructor 'mkFs' has no argument or settable return property 'Prop2'. The required signature is static member Maker.mkFs : unit -> fsharp.Class. diff --git a/tests/fsharp/core/members/set-only-property/calls.fsx b/tests/fsharp/core/members/set-only-property/calls.fsx new file mode 100644 index 00000000000..0d811993ee2 --- /dev/null +++ b/tests/fsharp/core/members/set-only-property/calls.fsx @@ -0,0 +1,24 @@ +#r "cs.dll" +#r "vb.dll" +#r "fs.dll" +type Maker = + static member mkCs () = csharp.Class() + static member mkVb () = basic.BasicClass() + static member mkFs () = fsharp.Class() +// so long https://github.com/dotnet/fsharp/issues/8351 isn't fixed, Prop1 setters are failing +let a = csharp.Class(Prop1=1) +let b = basic.BasicClass(Prop1=1) +let c = fsharp.Class(Prop1=1) + +let aa = Maker.mkCs(Prop1=1) +let bb = Maker.mkVb(Prop1=1) +let cc = Maker.mkFs(Prop1=1) + +// those are expected to fail, albeit with inconsistent error messages / marked ranges +let aaa = csharp.Class(Prop2=1) +let bbb = basic.BasicClass(Prop2=1) +let ccc = fsharp.Class(Prop2=1) + +let aaaa = Maker.mkCs(Prop2=1) +let bbbb = Maker.mkVb(Prop2=1) +let cccc = Maker.mkFs(Prop2=1) diff --git a/tests/fsharp/core/members/set-only-property/cs.cs b/tests/fsharp/core/members/set-only-property/cs.cs index 5323a3ffb96..18818edcf45 100644 --- a/tests/fsharp/core/members/set-only-property/cs.cs +++ b/tests/fsharp/core/members/set-only-property/cs.cs @@ -2,6 +2,7 @@ namespace csharp { public class Class { - public int Prop { set; private get; } - } + public int Prop1 { set; private get; } + public int Prop2 { private set; get; } + } } \ No newline at end of file diff --git a/tests/fsharp/core/members/set-only-property/fs.fs b/tests/fsharp/core/members/set-only-property/fs.fs index a1ef197b533..9b05bc67e70 100644 --- a/tests/fsharp/core/members/set-only-property/fs.fs +++ b/tests/fsharp/core/members/set-only-property/fs.fs @@ -1,17 +1,8 @@ +namespace fsharp type Class () = let mutable v = 0 - member x.Prop with set(value) = v <- value - and private get () = v + member x.Prop1 with set(value) = v <- value + and private get () = v -let a = csharp.Class(Prop=1) -let b = basic.BasicClass(Prop=1) -let c = Class(Prop=1) - -type Maker = - static member mkCs () = csharp.Class() - static member mkVb () = basic.BasicClass() - static member mkFs () = Class() - -let aa = Maker.mkCs(Prop=1) -let bb = Maker.mkVb(Prop=1) -let cc = Maker.mkFs(Prop=1) \ No newline at end of file + member x.Prop2 with private set(value) = v <- value + and public get () = v diff --git a/tests/fsharp/core/members/set-only-property/vb.vb b/tests/fsharp/core/members/set-only-property/vb.vb index 6cd42330603..c6a4865c012 100644 --- a/tests/fsharp/core/members/set-only-property/vb.vb +++ b/tests/fsharp/core/members/set-only-property/vb.vb @@ -1,7 +1,7 @@ namespace basic public class BasicClass dim v as integer - public property Prop as integer + public property Prop1 as integer private get return v end get @@ -9,5 +9,13 @@ namespace basic v = value end set end property + public property Prop2 as integer + get + return v + end get + private set(value as integer) + v = value + end set + end property end class end namespace \ No newline at end of file diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index c04f80ac438..0d05effa61c 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -288,7 +288,7 @@ module CoreTests = testOkFile.CheckExists() end - + [] let span () = @@ -1820,7 +1820,8 @@ module CoreTests = let cfg = testConfig "core/members/set-only-property" csc cfg @"%s /target:library /out:cs.dll" cfg.csc_flags ["cs.cs"] vbc cfg @"%s /target:library /out:vb.dll" cfg.vbc_flags ["vb.vb"] - fsc cfg @"%s -r:cs.dll -r:vb.dll -o:fs.exe" cfg.fsc_flags ["fs.fs"] + fsc cfg @"%s /target:library /out:fs.dll" cfg.fsc_flags ["fs.fs"] + singleNegTest cfg "calls" #endif From 1d2cfc33133afd6d43aac2905ba270b365bb1506 Mon Sep 17 00:00:00 2001 From: Gauthier Segay Date: Sat, 25 Jan 2020 18:20:24 +0100 Subject: [PATCH 4/4] F# setter on Prop1 works, despite the getter is internal --- tests/fsharp/core/members/set-only-property/calls.fsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fsharp/core/members/set-only-property/calls.fsx b/tests/fsharp/core/members/set-only-property/calls.fsx index 0d811993ee2..ddd6b365cb3 100644 --- a/tests/fsharp/core/members/set-only-property/calls.fsx +++ b/tests/fsharp/core/members/set-only-property/calls.fsx @@ -8,11 +8,11 @@ type Maker = // so long https://github.com/dotnet/fsharp/issues/8351 isn't fixed, Prop1 setters are failing let a = csharp.Class(Prop1=1) let b = basic.BasicClass(Prop1=1) -let c = fsharp.Class(Prop1=1) +let c = fsharp.Class(Prop1=1) // this one works, inconsistent but correct. let aa = Maker.mkCs(Prop1=1) let bb = Maker.mkVb(Prop1=1) -let cc = Maker.mkFs(Prop1=1) +let cc = Maker.mkFs(Prop1=1) // this one works, inconsistent but correct. // those are expected to fail, albeit with inconsistent error messages / marked ranges let aaa = csharp.Class(Prop2=1)