@@ -3,7 +3,8 @@
3module Reporting.Error.Syntax
3module Reporting.Error.Syntax
4 ( Error(..)
4 ( Error(..)
5 , ParseError(..)
5 , ParseError(..)
6− , Problem(..), Theory(..), Context(..)
6+ , Problem(..), Theory(..)
7+ , ContextStack, Context(..)
7 , BadOp(..), Next(..), NextDecl(..)
8 , BadOp(..), Next(..), NextDecl(..)
@@ -14,7 +15,7 @@ import qualified Data.Text as Text
14import Data.Text (Text)
15import Data.Text (Text)
16import qualified Reporting.Render.Type as RenderType
17import qualified Reporting.Render.Type as RenderType
17−import qualified Reporting.Region as Region
18+import qualified Reporting.Region as R
18import qualified Reporting.Report as Report
19import qualified Reporting.Report as Report
19import qualified Reporting.Helpers as Help
20import qualified Reporting.Helpers as Help
20import Reporting.Helpers ((<>), dullyellow, hsep, i2t, reflowParagraph, text)
21import Reporting.Helpers ((<>), dullyellow, hsep, i2t, reflowParagraph, text)
@@ -25,7 +26,7 @@ import Reporting.Helpers ((<>), dullyellow, hsep, i2t, reflowParagraph, text)
28− = Parse Problem
29+ = Parse (Maybe R.Region) Problem
29 | BadFunctionName Int
30 | BadFunctionName Int
30 | BadPattern Text
31 | BadPattern Text
@@ -42,7 +43,7 @@ data Error
42 | TypeWithoutDefinition Text
43 | TypeWithoutDefinition Text
44 | DuplicateArgument Text Text
45 | DuplicateArgument Text Text
45− | DuplicateFieldName Region.Region Text
46+ | DuplicateFieldName R.Region Text
46 | DuplicateValueDeclaration Text
47 | DuplicateValueDeclaration Text
47 | DuplicateTypeDeclaration Text
48 | DuplicateTypeDeclaration Text
48 | DuplicateDefinition Text
49 | DuplicateDefinition Text
@@ -74,17 +75,17 @@ data Problem
74 | BadNumberHex
75 | BadNumberHex
75 | BadNumberZero
76 | BadNumberZero
76 | BadShader Text
77 | BadShader Text
77− | BadOp BadOp [Context]
78+ | BadOp BadOp ContextStack
78− | Theories [Context] [Theory]
79+ | Theories ContextStack [Theory]
81data BadOp = HasType | Equals | Arrow | Pipe | Dot
82data BadOp = HasType | Equals | Arrow | Pipe | Dot
84data Theory
85data Theory
86− | Keyword Text
86+ = Keyword Text
87 | Symbol Text
87 | Symbol Text
@@ -96,7 +97,8 @@ data Theory
100 | AfterOpExpr Text
102 | AfterOpExpr Text
101 | ElseBranch
103 | ElseBranch
@@ -111,6 +113,9 @@ data NextDecl = ModuleDecl | DocCommentDecl | ImportDecl | OtherDecl
111 deriving (Eq, Ord)
113 deriving (Eq, Ord)
116+type ContextStack = [(Context, R.Position)]
114data Context
119data Context
116 | ExprLet
121 | ExprLet
@@ -132,7 +137,6 @@ data Context
132 ----------------
137 ----------------
136 | TypeUnion
140 | TypeUnion
137 | TypeAlias
141 | TypeAlias
@@ -147,8 +151,8 @@ data Context
147toReport :: RenderType.Localizer -> Error -> Report.Report
151toReport :: RenderType.Localizer -> Error -> Report.Report
148toReport _localizer err =
152toReport _localizer err =
149 case err of
153 case err of
150− Parse problem ->
154+ Parse subRegion problem ->
151− problemToReport problem
155+ problemToReport subRegion problem
153 BadFunctionName arity ->
157 BadFunctionName arity ->
154 Report.report
158 Report.report
@@ -398,13 +402,14 @@ unboundTypeVars declKind typeName givenVars unboundVars =
398-- PARSE ERROR TO REPORT
402-- PARSE ERROR TO REPORT
401−parseReport :: Text -> Help.Doc -> Report.Report
405+makeParseReport :: Maybe R.Region -> Text -> Help.Doc -> Report.Report
402−parseReport pre post =
406+makeParseReport subRegion pre post =
403− Report.report "PARSE ERROR" Nothing pre post
407+ Report.report "PARSE ERROR" subRegion pre post
406−problemToReport :: Problem -> Report.Report
410+problemToReport :: Maybe R.Region -> Problem -> Report.Report
407−problemToReport problem =
411+problemToReport subRegion problem =
412+ let parseReport = makeParseReport subRegion in
408 case problem of
413 case problem of
410 parseReport
415 parseReport
@@ -529,20 +534,20 @@ problemToReport problem =
529 "I ran into a problem while parsing this GLSL block."
534 "I ran into a problem while parsing this GLSL block."
530 (reflowParagraph msg)
535 (reflowParagraph msg)
532− BadOp op context ->
537+ BadOp op stack ->
533 case op of
538 case op of
534 HasType ->
539 HasType ->
535− badOp context "the \"has type\" operator" "(:)"
540+ badOp subRegion stack "the \"has type\" operator" "(:)"
536 "type annotations and record types"
541 "type annotations and record types"
537 "Maybe you want :: instead? Or maybe your indentation is a bit off?"
542 "Maybe you want :: instead? Or maybe your indentation is a bit off?"
539 Equals ->
544 Equals ->
540− badOp context "an equals sign" "(=)"
545+ badOp subRegion stack "an equals sign" "(=)"
541 "definitions"
546 "definitions"
542 "Maybe you want == instead? Or maybe your indentation is a bit off?"
547 "Maybe you want == instead? Or maybe your indentation is a bit off?"
545− if isCaseRelated context then
550+ if isCaseRelated stack then
546 parseReport
551 parseReport
547 "I ran into a stray arrow (->) while parsing this `case` expression."
552 "I ran into a stray arrow (->) while parsing this `case` expression."
548 ( reflowParagraph $
553 ( reflowParagraph $
@@ -552,12 +557,12 @@ problemToReport problem =
555− badOp context "an arrow" "(->)"
560+ badOp subRegion stack "an arrow" "(->)"
556 "cases expressions and anonymous functions"
561 "cases expressions and anonymous functions"
557 "Maybe you want > or >= instead?"
562 "Maybe you want > or >= instead?"
560− badOp context "a vertical bar" "(|)"
565+ badOp subRegion stack "a vertical bar" "(|)"
561 "type declarations"
566 "type declarations"
562 "Maybe you want || instead?"
567 "Maybe you want || instead?"
@@ -570,11 +575,11 @@ problemToReport problem =
570 \ there is some extra whitespace?"
575 \ there is some extra whitespace?"
573− Theories context allTheories ->
578+ Theories stack allTheories ->
575 starter =
580 starter =
576− "I got confused while trying to parse "
581+ "Something went wrong while parsing "
577− <> contextToText "your code" "" context
582+ <> contextToText "your code" "" stack
580 parseReport starter $
585 parseReport starter $
@@ -592,14 +597,14 @@ problemToReport problem =
592 [theory] ->
597 [theory] ->
593 reflowParagraph $
598 reflowParagraph $
594 "I was expecting to see "
599 "I was expecting to see "
595− <> addPeriod (theoryToText context theory)
600+ <> addPeriod (theoryToText stack theory)
597 theories ->
602 theories ->
598 Help.vcat $
603 Help.vcat $
599 [ text "I was expecting:"
604 [ text "I was expecting:"
600 , text ""
605 , text ""
602− ++ map (bullet . theoryToText context) theories
607+ ++ map (bullet . theoryToText stack) theories
605bullet :: Text -> Help.Doc
610bullet :: Text -> Help.Doc
@@ -615,24 +620,24 @@ addPeriod msg =
615 msg <> "."
620 msg <> "."
618−badOp :: [Context] -> Text -> Text -> Text -> Text -> Report.Report
623+badOp :: Maybe R.Region -> ContextStack -> Text -> Text -> Text -> Text -> Report.Report
619−badOp context opName op setting hint =
624+badOp subRegion stack opName op setting hint =
620− parseReport ("I was not expecting " <> opName <> " here.") $
625+ makeParseReport subRegion ("I was not expecting " <> opName <> " here.") $
621 Help.stack
626 Help.stack
622 [ reflowParagraph $
627 [ reflowParagraph $
623 "A " <> op <> " should only appear in " <> setting
628 "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 <> "."
625 , reflowParagraph hint
630 , reflowParagraph hint
629−contextToText :: Text -> Text -> [Context] -> Text
634+contextToText :: Text -> Text -> ContextStack -> Text
630−contextToText defaultText prefixText contextStack =
635+contextToText defaultText prefixText stack =
631− case contextStack of
636+ case stack of
633 defaultText
638 defaultText
635− context : rest ->
640+ (context, _) : rest ->
636 let anchor = getAnchor rest in
641 let anchor = getAnchor rest in
637 prefixText <>
642 prefixText <>
638 case context of
643 case context of
@@ -641,7 +646,7 @@ contextToText defaultText prefixText contextStack =
641 ExprFunc -> "an anonymous function" <> anchor
646 ExprFunc -> "an anonymous function" <> anchor
642 ExprCase -> "a `case`" <> anchor
647 ExprCase -> "a `case`" <> anchor
643 ExprList -> "a list" <> anchor
648 ExprList -> "a list" <> anchor
644− ExprTuple -> "a expression (in parentheses)" <> anchor
649+ ExprTuple -> "an expression (in parentheses)" <> anchor
645 ExprRecord -> "a record" <> anchor
650 ExprRecord -> "a record" <> anchor
646 Definition name -> name <> "'s definition"
651 Definition name -> name <> "'s definition"
647 Annotation name -> name <> "'s type annotation"
652 Annotation name -> name <> "'s type annotation"
@@ -652,31 +657,41 @@ contextToText defaultText prefixText contextStack =
652 PatternRecord -> "a record pattern" <> anchor
657 PatternRecord -> "a record pattern" <> anchor
653 Module -> "a module declaration"
658 Module -> "a module declaration"
654 Import -> "an import"
659 Import -> "an import"
655− DocComment -> "a documentation comment"
656 TypeUnion -> "a union type"
660 TypeUnion -> "a union type"
657 TypeAlias -> "a type alias"
661 TypeAlias -> "a type alias"
658 Infix -> "an infix declaration"
662 Infix -> "an infix declaration"
659 Port -> "a port declaration"
663 Port -> "a port declaration"
662−getAnchor :: [Context] -> Text
666+getAnchor :: ContextStack -> Text
663−getAnchor context =
667+getAnchor stack =
664− case context of
668+ case stack of
672+ (context, _) : rest ->
666− Definition name : _ -> " in " <> name <> "'s definition"
675+ " in " <> name <> "'s definition"
667− Annotation name : _ -> " in " <> name <> "'s type annotation"
678+ " in " <> name <> "'s type annotation"
668− _ : rest -> getAnchor rest
681+ getAnchor rest
684+isCaseRelated :: ContextStack -> Bool
685+isCaseRelated stack =
671−isCaseRelated :: [Context] -> Bool
690+ (context, _) : rest ->
672−isCaseRelated context =
675− ExprCase : _ -> True
676− _ : rest -> isCaseRelated rest
691+ context == ExprCase || isCaseRelated rest
679−theoryToText :: [Context] -> Theory -> Text
694+theoryToText :: ContextStack -> Theory -> Text
680theoryToText context theory =
695theoryToText context theory =
681 case theory of
696 case theory of
682 Keyword keyword ->
697 Keyword keyword ->
@@ -699,6 +714,7 @@ theoryToText context theory =
699 "]" -> "a right square bracket, to end a list"
714 "]" -> "a right square bracket, to end a list"
700 "{" -> "a left curly brace, for starting records"
715 "{" -> "a left curly brace, for starting records"
701 "}" -> "a right curly brace, to end a record"
716 "}" -> "a right curly brace, to end a record"
717+ "{-|" -> "a doc comment, like {-| example -}"
702 _ -> "the (" <> symbol <> ") symbol"
718 _ -> "the (" <> symbol <> ") symbol"
704 LowVar ->
720 LowVar ->
@@ -722,13 +738,14 @@ theoryToText context theory =
722 FreshLine nextDecl ->
738 FreshLine nextDecl ->
723 "a fresh line (without any leading spaces) for " <>
739 "a fresh line (without any leading spaces) for " <>
724 case nextDecl of
740 case nextDecl of
725− ModuleDecl -> "an `import`"
741+ ModuleDecl -> "something like `module Main exposing (..)`"
726− DocCommentDecl -> "an `import`"
742+ DocCommentDecl -> "something like `import Html exposing (text)`"
727 ImportDecl -> "an `import` or a declarations"
743 ImportDecl -> "an `import` or a declarations"
728− OtherDecl -> "a top-level declaration"
744+ OtherDecl -> "a top-level declaration, like `view model = div [] [...]`"
730 Expecting next ->
746 Expecting next ->
731 case next of
747 case next of
748+ Decl -> "a declaration, like `x = 5` or `type alias Model = { ... }`"
732 Expr -> "an expression, like x or 42"
749 Expr -> "an expression, like x or 42"
733 AfterOpExpr op -> "an expression after that (" <> op <> ") operator, like x or 42"
750 AfterOpExpr op -> "an expression after that (" <> op <> ") operator, like x or 42"
734 ElseBranch -> "an `else` branch. An `if` must handle both possibilities."
751 ElseBranch -> "an `else` branch. An `if` must handle both possibilities."
@@ -739,14 +756,14 @@ theoryToText context theory =
739 Exposing -> "something like `exposing (..)`"
756 Exposing -> "something like `exposing (..)`"
742−equalsTheory :: [Context] -> Text
759+equalsTheory :: ContextStack -> Text
743−equalsTheory context =
760+equalsTheory stack =
744− case context of
761+ case stack of
746 "an equals sign (=)"
763 "an equals sign (=)"
748− first : rest ->
765+ (context, _) : rest ->
749− case first of
766+ case context of
750 ExprRecord -> "an equals sign (=) followed by an expression"
767 ExprRecord -> "an equals sign (=) followed by an expression"
751 Definition name -> "an equals sign (=) followed by " <> name <> "'s definition"
768 Definition name -> "an equals sign (=) followed by " <> name <> "'s definition"
752 TypeUnion -> "an equals sign (=) followed by the first union type constructor"
769 TypeUnion -> "an equals sign (=) followed by the first union type constructor"
@@ -754,28 +771,28 @@ equalsTheory context =
754 _ -> equalsTheory rest
771 _ -> equalsTheory rest
757−barTheory :: [Context] -> Text
774+barTheory :: ContextStack -> Text
758−barTheory context =
775+barTheory stack =
759− case context of
776+ case stack of
761 "a vertical bar (|)"
778 "a vertical bar (|)"
763− first : rest ->
780+ (context, _) : rest ->
764− case first of
781+ case context of
765 ExprRecord -> "a vertical bar (|) followed by the record fields you want to update"
782 ExprRecord -> "a vertical bar (|) followed by the record fields you want to update"
766 TypeRecord -> "a vertical bar (|) followed by some record field types"
783 TypeRecord -> "a vertical bar (|) followed by some record field types"
767 TypeUnion -> "a vertical bar (|) followed by more union type constructors"
784 TypeUnion -> "a vertical bar (|) followed by more union type constructors"
768 _ -> barTheory rest
785 _ -> barTheory rest
771−badSpace :: [Context] -> Text
788+badSpace :: ContextStack -> Text
772−badSpace context =
789+badSpace stack =
773− case context of
790+ case stack of
775 "more indentation? I was not done with that last thing yet."
792 "more indentation? I was not done with that last thing yet."
777− first : rest ->
794+ (context, _) : rest ->
778− case first of
795+ case context of
779 ExprIf -> "the end of that `if`" <> badSpaceEnd
796 ExprIf -> "the end of that `if`" <> badSpaceEnd
780 ExprLet -> "the end of that `let`" <> badSpaceEnd
797 ExprLet -> "the end of that `let`" <> badSpaceEnd
781 ExprFunc -> badSpace rest
798 ExprFunc -> badSpace rest
@@ -792,7 +809,6 @@ badSpace context =
792 PatternRecord -> "the end of that record" <> badSpaceEnd
809 PatternRecord -> "the end of that record" <> badSpaceEnd
793 Module -> "something like `module Main exposing (..)`"
810 Module -> "something like `module Main exposing (..)`"
794 Import -> "something like `import Html exposing (..)`"
811 Import -> "something like `import Html exposing (..)`"
795− DocComment -> badSpace rest
796 TypeUnion -> "more of that union type" <> badSpaceEnd
812 TypeUnion -> "more of that union type" <> badSpaceEnd
797 TypeAlias -> "more of that type alias" <> badSpaceEnd
813 TypeAlias -> "more of that type alias" <> badSpaceEnd
798 Infix -> "more of that infix declaration" <> badSpaceEnd
814 Infix -> "more of that infix declaration" <> badSpaceEnd