dhall-haskell icon indicating copy to clipboard operation
dhall-haskell copied to clipboard

line overrun in error reporting

Open jsoref opened this issue 3 years ago • 3 comments

Steps

% echo 'λ(a : Type) → ' > q.dhall;
% wc -l q.dhall;
       1 q.dhall
% echo ./q.dhall | dhall-to-json


↳ ./q.dhall

Error: Invalid input

/Users/jsoref/code/validators/dhall-validator-action/q.dhall:2:1:
  |
2 | <empty line>
  | ^
unexpected end of input
expecting expression or whitespace


1│ ./q.dhall

(input):1:1

Expected results

% echo 'λ(a : Type) → ' > q.dhall;
% wc -l q.dhall;
       1 q.dhall
% echo ./q.dhall | dhall-to-json


↳ ./q.dhall

Error: Invalid input

/Users/jsoref/code/validators/dhall-validator-action/q.dhall:1:18:
  |
1 | <end of file>
  | ^
unexpected end of input
expecting expression or whitespace


1│ ./q.dhall

(input):1:1

(n.b. #2210 should adjust the last line of this output... )

jsoref avatar Jun 07 '21 04:06 jsoref

This will be pretty difficult to fix since that logic for computing the line number comes from the upstream megaparsec package that we use for parsing. What's happening here is that it treats newlines as being the first character of the next line instead of the last character of the previous line for error reporting purpose

Gabriella439 avatar Jun 08 '21 05:06 Gabriella439

Might I suggest starting with opening an issue in that repository?

It'd mean I could at least track it.

For reference, I've written code to undo it: https://github.com/dhall-validator/action/blob/91532576ccd33a3729f61d2bc4b58fac0c113528/dhall-checker#L19-L31

That's more than a quarter of the entire code...

jsoref avatar Jun 08 '21 13:06 jsoref

@jsoref: I'm a bit reluctant to open an upstream report because I'm not entirely sure that I prefer the alternative behavior (adding a special case to megaparsec for when the file ends with \n<EOF>), because I generally don't like adding special case logic if possible.

However, if you're still interested in proposing such an upstream change I created a small file that can be used as a minimal reproducing test case for this purpose:

{-# LANGUAGE OverloadedStrings #-}

module Main where

import Data.Text (Text)
import Data.Void (Void)
import Text.Megaparsec (Parsec)

import qualified Text.Megaparsec as Megaparsec

parser :: Parsec Void Text Text
parser = "A\n" *> "B"

main :: IO ()
main = Megaparsec.parseTest parser "A\n"

Gabriella439 avatar Jun 11 '21 01:06 Gabriella439