@@ -501,6 +501,115 @@ extends [runtime]System.Object
501501
502502 }""" ]
503503
504+ [<Test>]
505+ let ``Properties are emitted for CliMutable records`` () =
506+ FSharp """
507+ namespace ReferenceAssembly
508+ type [<CLIMutable;NoComparison;NoEquality>] MyRecord = { MyId: int }"""
509+ |> withOptions [ " --refonly" ]
510+ |> compile
511+ |> shouldSucceed
512+ |> verifyIL [
513+ referenceAssemblyAttributeExpectedIL
514+ " .property instance int32 MyId()" ]
515+
516+ [<Test>]
517+ let ``Properties are emitted even for CliMutable records which are not last in a file`` () =
518+ FSharp """
519+ namespace ReferenceAssembly
520+ type [<CLIMutable;NoComparison;NoEquality>] MyRecord = { MyId: int }
521+ type [<CLIMutable;NoComparison;NoEquality>] MySecondRecord = { MySecondId: string }
522+ """
523+ |> withOptions [ " --refonly" ]
524+ |> compile
525+ |> shouldSucceed
526+ |> verifyIL [
527+ referenceAssemblyAttributeExpectedIL
528+ " .property instance int32 MyId()"
529+ " .property instance string MySecondId()" ]
530+
531+ [<Test>] // Regression https://github.com/dotnet/fsharp/issues/14088 .
532+ // Generated IL was assigning properties to the last record in file instead of where they are supposed to be
533+ let ``Properties are emitted for equal records in the same file`` () =
534+ FSharp """
535+ namespace Net7FSharpSnafu.Library
536+
537+ open System
538+
539+ type [<CLIMutable;NoComparison;NoEquality>] MyRecord =
540+ { Name: string }
541+
542+ type [<CLIMutable;NoComparison;NoEquality>] MySecondRecord = { Name: string }
543+ """
544+ |> withOptions [ " --refonly" ]
545+ |> compile
546+ |> shouldSucceed
547+ |> verifyIL [ """ .class public auto ansi serializable sealed Net7FSharpSnafu.Library.MyRecord
548+ extends [runtime]System.Object
549+ {
550+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CLIMutableAttribute::.ctor() = ( 01 00 00 00 )
551+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoComparisonAttribute::.ctor() = ( 01 00 00 00 )
552+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.NoEqualityAttribute::.ctor() = ( 01 00 00 00 )
553+ .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 )
554+ .method public hidebysig specialname instance string
555+ get_Name() cil managed
556+ {
557+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
558+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
559+
560+ .maxstack 8
561+ IL_0000: ldnull
562+ IL_0001: throw
563+ }
564+
565+ .method public hidebysig specialname instance void
566+ set_Name(string 'value') cil managed
567+ {
568+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
569+ .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 )
570+
571+ .maxstack 8
572+ IL_0000: ldnull
573+ IL_0001: throw
574+ }
575+
576+ .method public specialname rtspecialname
577+ instance void .ctor(string name) cil managed
578+ {
579+
580+ .maxstack 8
581+ IL_0000: ldnull
582+ IL_0001: throw
583+ }
584+
585+ .method public specialname rtspecialname
586+ instance void .ctor() cil managed
587+ {
588+
589+ .maxstack 8
590+ IL_0000: ldnull
591+ IL_0001: throw
592+ }
593+
594+ .method public strict virtual instance string
595+ ToString() cil managed
596+ {
597+ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
598+
599+ .maxstack 8
600+ IL_0000: ldnull
601+ IL_0001: throw
602+ }
603+
604+ .property instance string Name()
605+ {
606+ .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags,
607+ int32) = ( 01 00 04 00 00 00 00 00 00 00 00 00 )
608+ .set instance void Net7FSharpSnafu.Library.MyRecord::set_Name(string)
609+ .get instance string Net7FSharpSnafu.Library.MyRecord::get_Name()
610+ }
611+ } """ ]
612+
504613 [<Test>]
505614 let ``Properties , getters , setters are emitted for internal properties`` () =
506615 FSharp """
@@ -558,6 +667,11 @@ type MySecondaryAttribute() =
558667 IL_0001: throw
559668 }
560669
670+ .property instance int32 Prop1()
671+ {
672+ .set instance void ReferenceAssembly/MyAttribute::set_Prop1(int32)
673+ .get instance int32 ReferenceAssembly/MyAttribute::get_Prop1()
674+ }
561675 }
562676
563677 .class auto ansi serializable nested public MySecondaryAttribute
@@ -597,11 +711,6 @@ type MySecondaryAttribute() =
597711 IL_0001: throw
598712 }
599713
600- .property instance int32 Prop1()
601- {
602- .set instance void ReferenceAssembly/MyAttribute::set_Prop1(int32)
603- .get instance int32 ReferenceAssembly/MyAttribute::get_Prop1()
604- }
605714 .property instance int32 Prop1()
606715 {
607716 .set instance void ReferenceAssembly/MySecondaryAttribute::set_Prop1(int32)
@@ -805,6 +914,10 @@ type Person(name : string, age : int) =
805914 IL_0001: throw
806915 }
807916
917+ .property instance bool Something()
918+ {
919+ .get instance bool ReferenceAssembly/CustomAttribute::get_Something()
920+ }
808921 }
809922
810923 .class auto ansi serializable nested public Person
@@ -865,10 +978,6 @@ type Person(name : string, age : int) =
865978 IL_0001: throw
866979 }
867980
868- .property instance bool Something()
869- {
870- .get instance bool ReferenceAssembly/CustomAttribute::get_Something()
871- }
872981 .property instance string Name()
873982 {
874983 .custom instance void ReferenceAssembly/CustomAttribute::.ctor(bool) = ( 01 00 01 00 00 )
0 commit comments