Skip to content

Commit c17ed2e

Browse files
authored
fix: drop allowAccessToPrivateRepresentation arg from reflection calls (#4689)
1 parent a4c7548 commit c17ed2e

4 files changed

Lines changed: 61 additions & 2 deletions

File tree

src/Fable.Transforms/Python/Replacements.fs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3967,7 +3967,8 @@ let fsharpType com methName (r: SourceLocation option) t (i: CallInfo) (args: Ex
39673967
|> Some
39683968
// Prevent name clash with FSharpValue.GetRecordFields
39693969
| "GetRecordFields" ->
3970-
Helper.LibCall(com, "Reflection", "get_record_elements", t, args, i.SignatureArgTypes, ?loc = r)
3970+
// Drop the trailing `allowAccessToPrivateRepresentation` flag (no meaning in Python)
3971+
Helper.LibCall(com, "Reflection", "get_record_elements", t, List.truncate 1 args, i.SignatureArgTypes, ?loc = r)
39713972
|> Some
39723973
| "GetUnionCases"
39733974
| "GetTupleElements"
@@ -3992,6 +3993,16 @@ let fsharpValue com methName (r: SourceLocation option) t (i: CallInfo) (args: E
39923993
| "MakeUnion"
39933994
| "MakeRecord"
39943995
| "MakeTuple" ->
3996+
// Drop the trailing `allowAccessToPrivateRepresentation` flag, a .NET-only
3997+
// concept the runtime helpers don't accept.
3998+
let args =
3999+
match methName with
4000+
| "GetRecordFields" -> List.truncate 1 args
4001+
| "GetUnionFields"
4002+
| "MakeUnion"
4003+
| "MakeRecord" -> List.truncate 2 args
4004+
| _ -> args
4005+
39954006
Helper.LibCall(com, "Reflection", Naming.lowerFirst methName, t, args, i.SignatureArgTypes, ?loc = r)
39964007
|> Some
39974008
| "GetExceptionFields" -> None // TODO!!!

src/Fable.Transforms/Replacements.fs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4154,7 +4154,8 @@ let fsharpType com (ctx: Context) methName (r: SourceLocation option) t (i: Call
41544154
|> Some
41554155
// Prevent name clash with FSharpValue.GetRecordFields
41564156
| "GetRecordFields" ->
4157-
Helper.LibCall(com, "Reflection", "getRecordElements", t, args, i.SignatureArgTypes, ?loc = r)
4157+
// Drop the trailing `allowAccessToPrivateRepresentation` flag (no meaning in JS/TS)
4158+
Helper.LibCall(com, "Reflection", "getRecordElements", t, List.truncate 1 args, i.SignatureArgTypes, ?loc = r)
41584159
|> Some
41594160
| "GetUnionCases"
41604161
| "GetTupleElements"
@@ -4185,6 +4186,16 @@ let fsharpValue com methName (r: SourceLocation option) t (i: CallInfo) (args: E
41854186
| "MakeUnion"
41864187
| "MakeRecord"
41874188
| "MakeTuple" ->
4189+
// Drop the trailing `allowAccessToPrivateRepresentation` flag, a .NET-only
4190+
// concept the runtime helpers don't accept.
4191+
let args =
4192+
match methName with
4193+
| "GetRecordFields" -> List.truncate 1 args
4194+
| "GetUnionFields"
4195+
| "MakeUnion"
4196+
| "MakeRecord" -> List.truncate 2 args
4197+
| _ -> args
4198+
41884199
Helper.LibCall(com, "Reflection", Naming.lowerFirst methName, t, args, i.SignatureArgTypes, ?loc = r)
41894200
|> Some
41904201
| "GetExceptionFields" -> None // TODO!!!

tests/Js/Main/ReflectionTests.fs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,24 @@ let reflectionTests = [
381381
let all = isRecord && matchRecordFields && matchIndividualRecordFields && canMakeSameRecord
382382
all |> equal true
383383

384+
testCase "Reflection functions accept allowAccessToPrivateRepresentation" <| fun () ->
385+
let recordType = typeof<TestRecord>
386+
let record = { String = "a"; Int = 1 }
387+
388+
FSharpType.GetRecordFields(recordType, allowAccessToPrivateRepresentation = true).Length |> equal 2
389+
390+
let values = FSharpValue.GetRecordFields(record, allowAccessToPrivateRepresentation = true)
391+
let rebuilt =
392+
FSharpValue.MakeRecord(recordType, values, allowAccessToPrivateRepresentation = true) :?> TestRecord
393+
rebuilt |> equal record
394+
395+
let unionType = typeof<TestUnion>
396+
let intCase = FSharpType.GetUnionCases(unionType).[1]
397+
let u = FSharpValue.MakeUnion(intCase, [| box 5 |], allowAccessToPrivateRepresentation = true) :?> TestUnion
398+
let info, fields = FSharpValue.GetUnionFields(u, unionType, allowAccessToPrivateRepresentation = true)
399+
info.Name |> equal "IntCase"
400+
fields.[0] |> equal (box 5)
401+
384402
testCase "PropertyInfo.GetValue works" <| fun () ->
385403
let value: obj = { Firstname = "Maxime"; Age = 12 } :> obj
386404

tests/Python/TestReflection.fs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,25 @@ let ``test Reflection Array`` () =
218218
typeof<bool> = elType |> equal false
219219
liType.GetElementType() |> equal null
220220

221+
[<Fact>]
222+
let ``test reflection functions accept allowAccessToPrivateRepresentation`` () =
223+
let recordType = typeof<MyRecord>
224+
let record = { String = "a"; Int = 1 }
225+
226+
FSharpType.GetRecordFields(recordType, allowAccessToPrivateRepresentation = true).Length |> equal 2
227+
228+
let values = FSharpValue.GetRecordFields(record, allowAccessToPrivateRepresentation = true)
229+
let rebuilt =
230+
FSharpValue.MakeRecord(recordType, values, allowAccessToPrivateRepresentation = true) :?> MyRecord
231+
rebuilt |> equal record
232+
233+
let unionType = typeof<MyUnion>
234+
let intCase = FSharpType.GetUnionCases(unionType).[1]
235+
let u = FSharpValue.MakeUnion(intCase, [| box 5 |], allowAccessToPrivateRepresentation = true) :?> MyUnion
236+
let info, fields = FSharpValue.GetUnionFields(u, unionType, allowAccessToPrivateRepresentation = true)
237+
info.Name |> equal "IntCase"
238+
fields.[0] |> equal (box 5)
239+
221240
#if FABLE_COMPILER
222241
[<Fact>]
223242
let ``test FSharp.Reflection Record`` () =

0 commit comments

Comments
 (0)