This ticket is about making parsePrettyDiffs :: String -> [DiffOperation LineRange] more strict in how invalid input is handled such that it can be specified to
{-@ parsePrettyDiffs :: String -> [DiffOperation ValidLineRange] @-}
Where ValidLineRange is the alias used to specify {-@ diffToLineRanges :: [LineDiff] -> [DiffOperation ValidLineRange] @-} (introduced in #34).
Indeed, parsePrettyDiffs can be found to require this postcondition from it being a left inverse to prettyDiff, in the sense of one of our test properties:
-- Data.Algorithm.DiffOutput
prettyDiffs :: [DiffOperation LineRange] -> Doc
parsePrettyDiffs :: String -> [DiffOperation LineRange]
-- test/Test.hs
-- | Check pretty printed DiffOperations can be parsed again
prop_parse :: DiffInput -> Bool
prop_parse (DiffInput le ri) =
let difflrs = diffToLineRanges $ getGroupedDiff le ri
output = render (prettyDiffs difflrs) ++ "\n"
parsed = parsePrettyDiffs output
in difflrs == parsed
As diffToLineRanges produces ValidLineRange, so must parsePrettyDiffs.
The required annotations for the current implementation can be seen in 4ccb48a. In 7908122 this spec is forced to pass by adding extraneous source checks. As it turns out the ValidLineRange is not an implicit invariant of this parser, essentially because it is too permissive/optimistic about its input. An alternative approach explored in ec75c3f manages to remove the additional checks by allowing a ValidLineRange to have empty contents. However, the result does not relate coherently with the intended semantics (e.g. the end of a range is allowed to be before its start).
These specification difficulties prompt for an improvement of this parser. Also, uses of this functions in hackage need to be investigated in order to anticipate/avoid breaking downstream code.
This ticket is about making
parsePrettyDiffs :: String -> [DiffOperation LineRange]more strict in how invalid input is handled such that it can be specified to{-@ parsePrettyDiffs :: String -> [DiffOperation ValidLineRange] @-}Where
ValidLineRangeis the alias used to specify{-@ diffToLineRanges :: [LineDiff] -> [DiffOperation ValidLineRange] @-}(introduced in #34).Indeed,
parsePrettyDiffscan be found to require this postcondition from it being a left inverse toprettyDiff, in the sense of one of our test properties:As
diffToLineRangesproducesValidLineRange, so mustparsePrettyDiffs.The required annotations for the current implementation can be seen in 4ccb48a. In 7908122 this spec is forced to pass by adding extraneous source checks. As it turns out the
ValidLineRangeis not an implicit invariant of this parser, essentially because it is too permissive/optimistic about its input. An alternative approach explored in ec75c3f manages to remove the additional checks by allowing aValidLineRangeto have empty contents. However, the result does not relate coherently with the intended semantics (e.g. theendof a range is allowed to be before itsstart).These specification difficulties prompt for an improvement of this parser. Also, uses of this functions in hackage need to be investigated in order to anticipate/avoid breaking downstream code.