Skip to content

Make parser more strict on invalid input #44

Description

@ninioArtillero

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions