Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 10 additions & 27 deletions src/utils/sformat.fs
Original file line number Diff line number Diff line change
Expand Up @@ -394,19 +394,13 @@ module ReflectUtils =
| TupleValue of TupleType * (obj * Type)[]
| FunctionClosureValue of Type
| RecordValue of (string * obj * Type)[]
| UnionCaseValue of declaringType: Type option * string * (string * (obj * Type))[]
| UnionCaseValue of string * (string * (obj * Type))[]
| ExceptionValue of Type * (string * (obj * Type))[]
| NullValue
| UnitValue
| ObjectValue of obj

module Value =

// Returns true if a given type has the RequireQualifiedAccess attribute
let private requiresQualifiedAccess (declaringType: Type) =
let rqaAttr = declaringType.GetCustomAttribute(typeof<RequireQualifiedAccessAttribute>, false)
isNull rqaAttr |> not

// Analyze an object to see if it the representation
// of an F# value.
let GetValueInfoOfObject (bindingFlags: BindingFlags) (obj: obj) =
Expand Down Expand Up @@ -440,10 +434,7 @@ module ReflectUtils =
let tag, vals = FSharpValue.GetUnionFields (obj, reprty, bindingFlags)
let props = tag.GetFields()
let pvals = (props, vals) ||> Array.map2 (fun prop v -> prop.Name, (v, prop.PropertyType))
let declaringType =
if requiresQualifiedAccess tag.DeclaringType then Some tag.DeclaringType
else None
UnionCaseValue(declaringType, tag.Name, pvals)
UnionCaseValue(tag.Name, pvals)

elif FSharpType.IsExceptionRepresentation(reprty, bindingFlags) then
let props = FSharpType.GetExceptionFields(reprty, bindingFlags)
Expand Down Expand Up @@ -472,10 +463,7 @@ module ReflectUtils =
| _ -> false
if isNullaryUnion then
let nullaryCase = FSharpType.GetUnionCases ty |> Array.filter (fun uc -> uc.GetFields().Length = 0) |> Array.item 0
let declaringType =
if requiresQualifiedAccess ty then Some ty
else None
UnionCaseValue(declaringType, nullaryCase.Name, [| |])
UnionCaseValue(nullaryCase.Name, [| |])
elif isUnitType ty then UnitValue
else NullValue
| _ ->
Expand Down Expand Up @@ -725,8 +713,8 @@ module Display =
| null -> None
| _ ->
match Value.GetValueInfo bindingFlags (x, ty) with
| UnionCaseValue (_, "Cons", recd) -> Some (unpackCons recd)
| UnionCaseValue (_, "Empty", [| |]) -> None
| UnionCaseValue ("Cons", recd) -> Some (unpackCons recd)
| UnionCaseValue ("Empty", [| |]) -> None
| _ -> failwith "List value had unexpected ValueInfo"

let structL = wordL (tagKeyword "struct")
Expand Down Expand Up @@ -1018,14 +1006,9 @@ module Display =
countNodes 1
wordL (tagPunctuation "[]")

and unionCaseValueL depthLim prec (declaringType: Type option) unionCaseName recd =
and unionCaseValueL depthLim prec unionCaseName recd =
countNodes 1
let caseName =
match declaringType with
| None ->
wordL (tagMethod unionCaseName)
| Some declaringType ->
wordL (tagClass declaringType.Name) ^^ sepL (tagPunctuation ".") ^^ wordL (tagMethod unionCaseName)
let caseName = wordL (tagMethod unionCaseName)
match recd with
| [] -> caseName
| recd -> (caseName --- recdAtomicTupleL depthLim recd) |> bracketIfL (prec <= Precedence.BracketIfTupleOrNotAtomic)
Expand Down Expand Up @@ -1178,12 +1161,12 @@ module Display =
| RecordValue items ->
recordValueL depthLim (Array.toList items)

| UnionCaseValue (_,constr,recd) when // x is List<T>. Note: "null" is never a valid list value.
| UnionCaseValue (constr,recd) when // x is List<T>. Note: "null" is never a valid list value.
x<>null && isListType (x.GetType()) ->
listValueL depthLim constr recd

| UnionCaseValue(declaringType, unionCaseName, recd) ->
unionCaseValueL depthLim prec declaringType unionCaseName (Array.toList recd)
| UnionCaseValue(unionCaseName, recd) ->
unionCaseValueL depthLim prec unionCaseName (Array.toList recd)

| ExceptionValue(exceptionType, recd) ->
fsharpExceptionL depthLim prec exceptionType (Array.toList recd)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

namespace FSharp.Core.UnitTests

open System
open FSharp.Core.UnitTests.LibraryTestFx
open Xunit

type MyUnionType =
Expand Down Expand Up @@ -57,16 +55,16 @@ type PrintfTests() =

[<Fact>]
member __.``union case formatting with RequireQualifiedAccess`` () =
Assert.AreEqual("SecondUnionType.Case1", sprintf "%A" SecondUnionType.Case1)
Assert.AreEqual("SecondUnionType.Case2 \"hello\"", sprintf "%A" (SecondUnionType.Case2 "hello"))
Assert.AreEqual("SecondUnionType.Case2Opt None", sprintf "%A" (SecondUnionType.Case2Opt None))
Assert.AreEqual("SecondUnionType.Case2Opt (Some \"hi\")", sprintf "%A" (SecondUnionType.Case2Opt (Some "hi")))
Assert.AreEqual("SecondUnionType.Case3 (5, \"hello\")", sprintf "%A" (SecondUnionType.Case3 (5, "hello")))
Assert.AreEqual("Case1", sprintf "%A" SecondUnionType.Case1)
Assert.AreEqual("Case2 \"hello\"", sprintf "%A" (SecondUnionType.Case2 "hello"))
Assert.AreEqual("Case2Opt None", sprintf "%A" (SecondUnionType.Case2Opt None))
Assert.AreEqual("Case2Opt (Some \"hi\")", sprintf "%A" (SecondUnionType.Case2Opt (Some "hi")))
Assert.AreEqual("Case3 (5, \"hello\")", sprintf "%A" (SecondUnionType.Case3 (5, "hello")))

[<Fact>]
member __.``union case formatting with UseNullAsTrueValue`` () =
Assert.AreEqual("NullCase", sprintf "%A" NullCase)
Assert.AreEqual("RQANullAsTrueUnionType.NullCase", sprintf "%A" RQANullAsTrueUnionType.NullCase)
Assert.AreEqual("NullCase", sprintf "%A" RQANullAsTrueUnionType.NullCase)

[<Fact>]
member __.``F# option formatting`` () =
Expand Down