@@ -3,7 +3,8 @@
33module Reporting.Error.Syntax
44 ( Error(..)
55 , ParseError(..)
6− , Problem(..), Theory(..), Context(..)
6+ , Problem(..), Theory(..)
7+ , ContextStack, Context(..)
78 , BadOp(..), Next(..), NextDecl(..)
89 , toReport
910 )
@@ -14,7 +15,7 @@ import qualified Data.Text as Text
1415import Data.Text (Text)
1516
1617import qualified Reporting.Render.Type as RenderType
17−import qualified Reporting.Region as Region
18+import qualified Reporting.Region as R
1819import qualified Reporting.Report as Report
1920import qualified Reporting.Helpers as Help
2021import Reporting.Helpers ((<>), dullyellow, hsep, i2t, reflowParagraph, text)
@@ -25,7 +26,7 @@ import Reporting.Helpers ((<>), dullyellow, hsep, i2t, reflowParagraph, text)
2526
2627
2728data Error
28− = Parse Problem
29+ = Parse (Maybe R.Region) Problem
2930 | BadFunctionName Int
3031 | BadPattern Text
3132
@@ -42,7 +43,7 @@ data Error
4243 | TypeWithoutDefinition Text
4344
4445 | DuplicateArgument Text Text
45− | DuplicateFieldName Region.Region Text
46+ | DuplicateFieldName R.Region Text
4647 | DuplicateValueDeclaration Text
4748 | DuplicateTypeDeclaration Text
4849 | DuplicateDefinition Text
@@ -74,17 +75,17 @@ data Problem
7475 | BadNumberHex
7576 | BadNumberZero
7677 | BadShader Text
77− | BadOp BadOp [Context]
78− | Theories [Context] [Theory]
78+ | BadOp BadOp ContextStack
79+ | Theories ContextStack [Theory]
7980
8081
8182data BadOp = HasType | Equals | Arrow | Pipe | Dot
8283
8384
8485data Theory
85− = Expecting Next
86− | Keyword Text
86+ = Keyword Text
8787 | Symbol Text
88+ | Expecting Next
8889 | LowVar
8990 | CapVar
9091 | InfixOp
@@ -96,7 +97,8 @@ data Theory
9697
9798
9899data Next
99− = Expr
100+ = Decl
101+ | Expr
100102 | AfterOpExpr Text
101103 | ElseBranch
102104 | Arg
@@ -111,6 +113,9 @@ data NextDecl = ModuleDecl | DocCommentDecl | ImportDecl | OtherDecl
111113 deriving (Eq, Ord)
112114
113115
116+type ContextStack = [(Context, R.Position)]
117+
118+
114119data Context
115120 = ExprIf
116121 | ExprLet
@@ -132,7 +137,6 @@ data Context
132137 ----------------
133138 | Module
134139 | Import
135− | DocComment
136140 | TypeUnion
137141 | TypeAlias
138142 | Infix
@@ -147,8 +151,8 @@ data Context
147151toReport :: RenderType.Localizer -> Error -> Report.Report
148152toReport _localizer err =
149153 case err of
150− Parse problem ->
151− problemToReport problem
154+ Parse subRegion problem ->
155+ problemToReport subRegion problem
152156
153157 BadFunctionName arity ->
154158 Report.report
@@ -398,13 +402,14 @@ unboundTypeVars declKind typeName givenVars unboundVars =
398402-- PARSE ERROR TO REPORT
399403
400404
401−parseReport :: Text -> Help.Doc -> Report.Report
402−parseReport pre post =
403− Report.report "PARSE ERROR" Nothing pre post
405+makeParseReport :: Maybe R.Region -> Text -> Help.Doc -> Report.Report
406+makeParseReport subRegion pre post =
407+ Report.report "PARSE ERROR" subRegion pre post
404408
405409
406−problemToReport :: Problem -> Report.Report
407−problemToReport problem =
410+problemToReport :: Maybe R.Region -> Problem -> Report.Report
411+problemToReport subRegion problem =
412+ let parseReport = makeParseReport subRegion in
408413 case problem of
409414 Tab ->
410415 parseReport
@@ -529,20 +534,20 @@ problemToReport problem =
529534 "I ran into a problem while parsing this GLSL block."
530535 (reflowParagraph msg)
531536
532− BadOp op context ->
537+ BadOp op stack ->
533538 case op of
534539 HasType ->
535− badOp context "the \"has type\" operator" "(:)"
540+ badOp subRegion stack "the \"has type\" operator" "(:)"
536541 "type annotations and record types"
537542 "Maybe you want :: instead? Or maybe your indentation is a bit off?"
538543
539544 Equals ->
540− badOp context "an equals sign" "(=)"
545+ badOp subRegion stack "an equals sign" "(=)"
541546 "definitions"
542547 "Maybe you want == instead? Or maybe your indentation is a bit off?"
543548
544549 Arrow ->
545− if isCaseRelated context then
550+ if isCaseRelated stack then
546551 parseReport
547552 "I ran into a stray arrow (->) while parsing this `case` expression."
548553 ( reflowParagraph $
@@ -552,12 +557,12 @@ problemToReport problem =
552557 )
553558
554559 else
555− badOp context "an arrow" "(->)"
560+ badOp subRegion stack "an arrow" "(->)"
556561 "cases expressions and anonymous functions"
557562 "Maybe you want > or >= instead?"
558563
559564 Pipe ->
560− badOp context "a vertical bar" "(|)"
565+ badOp subRegion stack "a vertical bar" "(|)"
561566 "type declarations"
562567 "Maybe you want || instead?"
563568
@@ -570,11 +575,11 @@ problemToReport problem =
570575 \ there is some extra whitespace?"
571576 )
572577
573− Theories context allTheories ->
578+ Theories stack allTheories ->
574579 let
575580 starter =
576− "I got confused while trying to parse "
577− <> contextToText "your code" "" context
581+ "Something went wrong while parsing "
582+ <> contextToText "your code" "" stack
578583 <> "."
579584 in
580585 parseReport starter $
@@ -592,14 +597,14 @@ problemToReport problem =
592597 [theory] ->
593598 reflowParagraph $
594599 "I was expecting to see "
595− <> addPeriod (theoryToText context theory)
600+ <> addPeriod (theoryToText stack theory)
596601
597602 theories ->
598603 Help.vcat $
599604 [ text "I was expecting:"
600605 , text ""
601606 ]
602− ++ map (bullet . theoryToText context) theories
607+ ++ map (bullet . theoryToText stack) theories
603608
604609
605610bullet :: Text -> Help.Doc
@@ -615,24 +620,24 @@ addPeriod msg =
615620 msg <> "."
616621
617622
618−badOp :: [Context] -> Text -> Text -> Text -> Text -> Report.Report
619−badOp context opName op setting hint =
620− parseReport ("I was not expecting " <> opName <> " here.") $
623+badOp :: Maybe R.Region -> ContextStack -> Text -> Text -> Text -> Text -> Report.Report
624+badOp subRegion stack opName op setting hint =
625+ makeParseReport subRegion ("I was not expecting " <> opName <> " here.") $
621626 Help.stack
622627 [ reflowParagraph $
623628 "A " <> op <> " should only appear in " <> setting
624− <> contextToText "" ", but I think I am parsing " context <> "."
629+ <> contextToText "" ", but I think I am parsing " stack <> "."
625630 , reflowParagraph hint
626631 ]
627632
628633
629−contextToText :: Text -> Text -> [Context] -> Text
630−contextToText defaultText prefixText contextStack =
631− case contextStack of
634+contextToText :: Text -> Text -> ContextStack -> Text
635+contextToText defaultText prefixText stack =
636+ case stack of
632637 [] ->
633638 defaultText
634639
635− context : rest ->
640+ (context, _) : rest ->
636641 let anchor = getAnchor rest in
637642 prefixText <>
638643 case context of
@@ -641,7 +646,7 @@ contextToText defaultText prefixText contextStack =
641646 ExprFunc -> "an anonymous function" <> anchor
642647 ExprCase -> "a `case`" <> anchor
643648 ExprList -> "a list" <> anchor
644− ExprTuple -> "a expression (in parentheses)" <> anchor
649+ ExprTuple -> "an expression (in parentheses)" <> anchor
645650 ExprRecord -> "a record" <> anchor
646651 Definition name -> name <> "'s definition"
647652 Annotation name -> name <> "'s type annotation"
@@ -652,31 +657,41 @@ contextToText defaultText prefixText contextStack =
652657 PatternRecord -> "a record pattern" <> anchor
653658 Module -> "a module declaration"
654659 Import -> "an import"
655− DocComment -> "a documentation comment"
656660 TypeUnion -> "a union type"
657661 TypeAlias -> "a type alias"
658662 Infix -> "an infix declaration"
659663 Port -> "a port declaration"
660664
661665
662−getAnchor :: [Context] -> Text
663−getAnchor context =
664− case context of
665− [] -> ""
666− Definition name : _ -> " in " <> name <> "'s definition"
667− Annotation name : _ -> " in " <> name <> "'s type annotation"
668− _ : rest -> getAnchor rest
666+getAnchor :: ContextStack -> Text
667+getAnchor stack =
668+ case stack of
669+ [] ->
670+ ""
671+
672+ (context, _) : rest ->
673+ case context of
674+ Definition name ->
675+ " in " <> name <> "'s definition"
676+
677+ Annotation name ->
678+ " in " <> name <> "'s type annotation"
679+
680+ _ ->
681+ getAnchor rest
682+
669683
684+isCaseRelated :: ContextStack -> Bool
685+isCaseRelated stack =
686+ case stack of
687+ [] ->
688+ False
670689
671−isCaseRelated :: [Context] -> Bool
672−isCaseRelated context =
673− case context of
674− [] -> False
675− ExprCase : _ -> True
676− _ : rest -> isCaseRelated rest
690+ (context, _) : rest ->
691+ context == ExprCase || isCaseRelated rest
677692
678693
679−theoryToText :: [Context] -> Theory -> Text
694+theoryToText :: ContextStack -> Theory -> Text
680695theoryToText context theory =
681696 case theory of
682697 Keyword keyword ->
@@ -699,6 +714,7 @@ theoryToText context theory =
699714 "]" -> "a right square bracket, to end a list"
700715 "{" -> "a left curly brace, for starting records"
701716 "}" -> "a right curly brace, to end a record"
717+ "{-|" -> "a doc comment, like {-| example -}"
702718 _ -> "the (" <> symbol <> ") symbol"
703719
704720 LowVar ->
@@ -722,13 +738,14 @@ theoryToText context theory =
722738 FreshLine nextDecl ->
723739 "a fresh line (without any leading spaces) for " <>
724740 case nextDecl of
725− ModuleDecl -> "an `import`"
726− DocCommentDecl -> "an `import`"
741+ ModuleDecl -> "something like `module Main exposing (..)`"
742+ DocCommentDecl -> "something like `import Html exposing (text)`"
727743 ImportDecl -> "an `import` or a declarations"
728− OtherDecl -> "a top-level declaration"
744+ OtherDecl -> "a top-level declaration, like `view model = div [] [...]`"
729745
730746 Expecting next ->
731747 case next of
748+ Decl -> "a declaration, like `x = 5` or `type alias Model = { ... }`"
732749 Expr -> "an expression, like x or 42"
733750 AfterOpExpr op -> "an expression after that (" <> op <> ") operator, like x or 42"
734751 ElseBranch -> "an `else` branch. An `if` must handle both possibilities."
@@ -739,14 +756,14 @@ theoryToText context theory =
739756 Exposing -> "something like `exposing (..)`"
740757
741758
742−equalsTheory :: [Context] -> Text
743−equalsTheory context =
744− case context of
759+equalsTheory :: ContextStack -> Text
760+equalsTheory stack =
761+ case stack of
745762 [] ->
746763 "an equals sign (=)"
747764
748− first : rest ->
749− case first of
765+ (context, _) : rest ->
766+ case context of
750767 ExprRecord -> "an equals sign (=) followed by an expression"
751768 Definition name -> "an equals sign (=) followed by " <> name <> "'s definition"
752769 TypeUnion -> "an equals sign (=) followed by the first union type constructor"
@@ -754,28 +771,28 @@ equalsTheory context =
754771 _ -> equalsTheory rest
755772
756773
757−barTheory :: [Context] -> Text
758−barTheory context =
759− case context of
774+barTheory :: ContextStack -> Text
775+barTheory stack =
776+ case stack of
760777 [] ->
761778 "a vertical bar (|)"
762779
763− first : rest ->
764− case first of
780+ (context, _) : rest ->
781+ case context of
765782 ExprRecord -> "a vertical bar (|) followed by the record fields you want to update"
766783 TypeRecord -> "a vertical bar (|) followed by some record field types"
767784 TypeUnion -> "a vertical bar (|) followed by more union type constructors"
768785 _ -> barTheory rest
769786
770787
771−badSpace :: [Context] -> Text
772−badSpace context =
773− case context of
788+badSpace :: ContextStack -> Text
789+badSpace stack =
790+ case stack of
774791 [] ->
775792 "more indentation? I was not done with that last thing yet."
776793
777− first : rest ->
778− case first of
794+ (context, _) : rest ->
795+ case context of
779796 ExprIf -> "the end of that `if`" <> badSpaceEnd
780797 ExprLet -> "the end of that `let`" <> badSpaceEnd
781798 ExprFunc -> badSpace rest
@@ -792,7 +809,6 @@ badSpace context =
792809 PatternRecord -> "the end of that record" <> badSpaceEnd
793810 Module -> "something like `module Main exposing (..)`"
794811 Import -> "something like `import Html exposing (..)`"
795− DocComment -> badSpace rest
796812 TypeUnion -> "more of that union type" <> badSpaceEnd
797813 TypeAlias -> "more of that type alias" <> badSpaceEnd
798814 Infix -> "more of that infix declaration" <> badSpaceEnd