SwensenSoftware / unquote

Write F# unit test assertions as quoted expressions, get step-by-step failure messages for free
http://www.swensensoftware.com/unquote
Apache License 2.0
287 stars 25 forks source link

Decompiler Feature Request: support UnionCaseTest expressions #3

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
For example,

source <@ let [a;b] = [1;2] in a,b @>

produces

let patternInput = [1; 2] in if UnionCaseTest (patternInput, FSharpList`1.Cons) 
then (if UnionCaseTest (PropertyGet (Some (patternInput),
                            Microsoft.FSharp.Collections.FSharpList`1[System.Int32] Tail,
                            []), FSharpList`1.Cons) then (if UnionCaseTest (PropertyGet (Some (PropertyGet (Some (patternInput),
                                               Microsoft.FSharp.Collections.FSharpList`1[System.Int32] Tail,
                                               [])),
                            Microsoft.FSharp.Collections.FSharpList`1[System.Int32] Tail,
                            []), FSharpList`1.Empty) then (let a = patternInput.Head in let b = patternInput.Tail.Head in (a, b)) else raise (MatchFailureException("stdin", 18, 14))) else raise (MatchFailureException("stdin", 18, 14))) else raise (MatchFailureException("stdin", 18, 14))

Original issue reported on code.google.com by stephen....@gmail.com on 15 Feb 2011 at 1:29

GoogleCodeExporter commented 9 years ago
note: the winning approach to decompiling UnionCaseTests is not clear and 
results of the decompilation would be almost unusable for human reading (deeply 
nested boolean expressions).

Original comment by stephen....@gmail.com on 16 Feb 2011 at 4:16

GoogleCodeExporter commented 9 years ago
in progress: it's going to be hard to read by nature, but will work.  going to 
make use of dynamic operator in sprinting for better readability

Original comment by stephen....@gmail.com on 20 Feb 2011 at 7:28

GoogleCodeExporter commented 9 years ago
Fixed, but pretty much unusable for Unquote's purposes: output is correct but 
too crazy to be human readable (and not sure much can do to get around it).  
For example,

> source <@ let [a;b] = [1;2] in a,b @>;;
val it : string =
  "let patternInput = [1; 2] in if (match patternInput with | _::_ -> true | _ -> false) then (if (match patternInput.Tail with | _::_ -> true | _ -> false) then (if (match patternInput.Tail.Tail with | [] -> true | _ -> false) then (let a = patternInput.Head in let b = patternInput.Tail.Head in (a, b)) else raise (MatchFailureException("stdin", 8, 14))) else raise (MatchFailureException("stdin", 8, 14))) else raise (MatchFailureException("stdin", 8, 14))"

Original comment by stephen....@gmail.com on 21 Feb 2011 at 3:05

GoogleCodeExporter commented 9 years ago
Also note that in certain cases op_Dynamic property get lookup implementation 
assumed to make output a bit easier (I would say clearer, but the madness can't 
be overtaken -- however, I am thinking of implementing this approach to make 
tuple decomposition a bit clearer). For example,

> type genericDu<'a> =
    | Hello of 'a
    | World of genericDu<'a>
    | Hello2 of 'a * bool;;
> let h = World (Hello2(Hello 3, true));;
> source <@ match h with | World (Hello2(Hello 3, true)) -> true | _ -> false 
@>;;
val it : string =
  "(match h with | World(_) -> true | _ -> false) && ((match (h?Item : genericDu<genericDu<int>>) with | Hello2(_,_) -> true | _ -> false) && ((match ((h?Item : genericDu<genericDu<int>>)?Item1 : genericDu<int>) with | Hello(_) -> true | _ -> false) && ((((h?Item : genericDu<genericDu<int>>)?Item1 : genericDu<int>)?Item : int) = 3 && (((h?Item : genericDu<genericDu<int>>)?Item2 : bool) && true))))"

Original comment by stephen....@gmail.com on 21 Feb 2011 at 3:10

GoogleCodeExporter commented 9 years ago

Original comment by stephen....@gmail.com on 17 Mar 2011 at 4:12