@@ -3,9 +3,13 @@
3module Reporting.Error.Syntax
3module Reporting.Error.Syntax
4 ( Error(..)
4 ( Error(..)
7− , Infix(..)
8+ , DeclType(..)
8 , CustomType(..)
10 , CustomType(..)
10 , Expr(..)
14 , Expr(..)
11 , Record(..)
15 , Record(..)
@@ -65,33 +69,89 @@ data Error
68−-- DECLARATIONS
72+-- MODULE
71−data Decl
75+data Module
72 = Module Row Col
76 = Module Row Col
77+ | ModuleSpace Space Row Col
73 | Import Row Col
78 | Import Row Col
74− | Annotation Name.Name Type Row Col
79+ | Infix Row Col
75− | Definition Name.Name Def Row Col
80+ | Declarations Decl Row Col
76− | TypeAlias Name.Name Row Col
81+
77− | CustomType Name.Name CustomType Row Col
82+
78− | Port Name.Name Row Col
83+
79− | Infix Infix Row Col
84+-- DECLARATIONS
81− | EndlessDocComment Row Col
86+
82 | DeclSpace Space Row Col
89 | DeclSpace Space Row Col
83− | DeclDeadend Row Col
90+ --
92+ | DeclType DeclType Row Col
93+ | DeclDef Name.Name DeclDef Row Col
97+ = DeclDefSpace Space Row Col
98+ | DeclDefEquals Row Col
99+ | DeclDefType Type Row Col
100+ | DeclDefAlignment Row Col
101+ | DeclDefArg Pattern Row Col
102+ | DeclDefBody Expr Row Col
103+ | DeclDefNameRepeat Name.Name Row Col
104+ | DeclDefNameMatch Name.Name Name.Name Row Col
105+ | DeclDefIndentType Row Col
106+ | DeclDefIndentEquals Row Col
107+ | DeclDefIndentBody Row Col
111+ = PortSpace Space Row Col
114+ | PortType Type Row Col
115+ | PortIndentName Row Col
116+ | PortIndentColon Row Col
117+ | PortIndentType Row Col
87− = Precedence Row Col
121+-- TYPE DECLARATIONS
88− | Associativity Row Col
122+
125+ = DT_Space Space Row Col
127+ | DT_Alias TypeAlias Row Col
128+ | DT_Union CustomType Row Col
130+ | DT_IndentName Row Col
134+ = AliasSpace Space Row Col
136+ | AliasEquals Row Col
137+ | AliasBody Type Row Col
139+ | AliasIndentEquals Row Col
140+ | AliasIndentBody Row Col
91data CustomType
143data CustomType
93− | CT_Space Space Row Col
144+ = CT_Space Space Row Col
148+ | CT_Variant Row Col
94− | CT_Type Type Row Col
149+ | CT_VariantArg Type Row Col
151+ | CT_IndentEquals Row Col
152+ | CT_IndentBar Row Col
153+ | CT_IndentAfterBar Row Col
154+ | CT_IndentAfterEquals Row Col
@@ -397,3 +457,1056 @@ data Operator
397toReport :: Code.Source -> Error -> Report.Report
457toReport :: Code.Source -> Error -> Report.Report
398toReport source err =
458toReport source err =
399 error "TODO" source err
459 error "TODO" source err
462+ CommentOnNothing region ->
463+ Report.Report "STRAY COMMENT" region [] $
464+ Report.toCodeSnippet source region Nothing
466+ "This documentation comment is not followed by anything."
469+ "All documentation comments need to be right above the declaration they\
470+ \ describe. Maybe some code got deleted or commented out by accident? Or\
471+ \ maybe this comment is here by accident?"
474+ UnexpectedPort region ->
475+ Report.Report "UNEXPECTED PORTS" region [] $
476+ Report.toCodeSnippet source region Nothing
479+ "You are declaring ports in a normal module."
483+ ["Switch","this","to","say",D.green "port module","instead,"
484+ ,"marking","that","this","module","contains","port","declarations."
487+ "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
489+ "to learn the syntax and how to use it effectively."
494+ Report.Report "NO PORTS" region [] $
495+ Report.toCodeSnippet source region Nothing
498+ "This module does not declare any ports, but it says it will:"
501+ ["Switch","this","to",D.green "module"
502+ ,"and","you","should","be","all","set!"
506+ ParseError row col context expectation ->
508+ pos = A.Position row col
509+ region = A.Region pos pos
513+ error "TODO no parse error yet"
516+ error "TODO no parse error yet"
521+ Report.Report "NO TABS" region [] $
522+ Report.toCodeSnippet source region Nothing
525+ "I ran into a tab, but tabs are not allowed in Elm files."
528+ "Replace the tab with spaces."
532+ Report.Report "EXPECTING DOC COMMENT" region [] $
533+ Report.toCodeSnippet source region Nothing
536+ "I was expecting a doc comment here:"
539+ "Check out" "TODO" "for examples of doc comments."
542+ MultiCommentEnd startRow startCol ->
546+ (A.Position startRow startCol)
547+ (A.Position startRow (startCol + 3))
549+ Report.Report "ENDLESS COMMENT" startRegion [] $
550+ Report.toCodeSnippet source startRegion Nothing
553+ "I cannot find the end of this multi-line comment:"
556+ [ D.reflow "Add a -} somewhere after this to end the comment."
558+ "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
559+ \ that happens to contain another comment. Like parentheses and curly braces,\
560+ \ the start and end markers must always be balanced. Maybe that is the problem?"
567+ Report.Report "EXPECTING NUMBER" region [] $
568+ Report.toCodeSnippet source region Nothing
571+ "I was expecting to see a number here:"
575+ "I recognize numbers in the following formats:"
576+ , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
578+ "So is there a way to write it like one of those?"
583+ Report.Report "WEIRD NUMBER" region [] $
584+ Report.toCodeSnippet source region Nothing
587+ "I thought I was reading a number, but I ran into some weird stuff here:"
591+ "I recognize numbers in the following formats:"
592+ , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
594+ "So is there a way to write it like one of those?"
599+ Report.Report "WEIRD NUMBER" region [] $
600+ Report.toCodeSnippet source region Nothing
603+ "Numbers cannot end with a dot like this:"
606+ ["Switching","to",D.green (D.fromChars (show int))
607+ ,"or",D.green (D.fromChars (show int ++ ".0"))
608+ ,"will","work","though!"
613+ Report.Report "WEIRD HEXIDECIMAL" region [] $
614+ Report.toCodeSnippet source region Nothing
617+ "I thought I was reading a hexidecimal number until I got here:"
621+ "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
622+ \ only recognize things like this:"
623+ , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
627+ Number_NoLeadingZero ->
628+ Report.Report "LEADING ZEROS" region [] $
629+ Report.toCodeSnippet source region Nothing
632+ "I do not accept numbers with leading zeros:"
636+ "Just delete the leading zeros and it should work!"
638+ "Some languages let you to specify octal numbers by adding a leading zero.\
639+ \ So in C, writing 0111 is the same as writing 73. Some people are used to\
640+ \ that, but others probably want it to equal 111. Either path is going to\
641+ \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
647+ Report.Report "EXPECTING PRECEDENCE" region [] $
648+ Report.toCodeSnippet source region Nothing
651+ "I was expecting the precedence here:"
654+ "I need a single digit between 0 and 9 inclusive."
660+ Report.Report "EXPECTING A CHARACTER" region [] $
661+ Report.toCodeSnippet source region Nothing
664+ "I was expecting a character here:"
668+ "Characters start and end with single quotes, like this:"
669+ , D.indent 4 $ D.vcat $
677+ "That last style lets you encode characters by their unicode\
678+ \ code point, so 'a' is equivalent to '\\u{0061}', 'ø' is\
679+ \ equivalent to '\\u{00F8}', and so on for all code points."
684+ Report.Report "MISSING SINGLE QUOTE" region [] $
685+ Report.toCodeSnippet source region Nothing
688+ "I thought I was parsing a character, but I got to the end of\
689+ \ the line without seeing the closing single quote:"
693+ "Characters start and end with single quotes, like this:"
694+ , D.indent 4 $ D.vcat $
702+ "That last style lets you encode characters by their unicode\
703+ \ code point, so 'a' is equivalent to '\\u{0061}', 'ø' is\
704+ \ equivalent to '\\u{00F8}', and so on for all code points."
708+ CharNotString startRow startCol ->
711+ A.Region (A.Position startRow startCol) pos
713+ Report.Report "NEEDS DOUBLE QUOTES" stringRegion [] $
714+ Report.toCodeSnippet source stringRegion Nothing
716+ "The following string uses single quotes:"
719+ [ "Please switch to double quotes instead:"
721+ D.dullyellow "'this'" <> " => " <> D.green "\"this\""
723+ "Elm uses double quotes for strings like \"hello\", whereas it uses single\
724+ \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
725+ \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
726+ \ individual characters."
731+ Report.Report "EXPECTING A STRING" region [] $
732+ Report.toCodeSnippet source region Nothing
735+ "I was expecting a string here:"
742+ ,"with","double","quotes."
747+ Report.Report "ENDLESS STRING" region [] $
748+ Report.toCodeSnippet source region Nothing
751+ "I got to the end of the line without seeing the closing double quote:"
755+ ["Strings","look","like",D.green "\"this\"","with","double"
756+ ,"quotes","on","each","end.","Is","the","closing","double"
757+ ,"quote","missing","in","your","code?"
759+ , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
763+ StringEnd_Multi startRow startCol ->
767+ (A.Position startRow startCol)
768+ (A.Position startRow (startCol + 3))
770+ Report.Report "ENDLESS STRING" startRegion [] $
771+ Report.toCodeSnippet source startRegion Nothing
774+ "I cannot find the end of this multi-line string:"
777+ [ D.reflow "Add a \"\"\" somewhere after this to end the string."
778+ , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
782+ EscapeUnknown startCol endCol ->
785+ A.Region (A.Position row startCol) (A.Position row endCol)
787+ Report.Report "UNKNOWN ESCAPE" escapeRegion [] $
788+ Report.toCodeSnippet source escapeRegion Nothing
791+ "Backslashes always start escaped characters, but I do not recognize this one:"
795+ "Valid escape characters include:"
796+ , D.indent 4 $ D.vcat $
806+ "The last one lets encode ANY character by its Unicode code\
807+ \ point, so use that for anything outside the ordinary six."
811+ BadUnicodeFormat startCol endCol ->
814+ A.Region (A.Position row startCol) (A.Position row endCol)
816+ Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
817+ Report.toCodeSnippet source escapeRegion Nothing
820+ "I ran into an invalid Unicode escape:"
824+ "Here are some examples of valid Unicode escapes:"
825+ , D.green $ D.indent 4 $ D.vcat $
832+ "Notice that the code point is always surrounded by curly\
833+ \ braces. They are required!"
837+ BadUnicodeCode startCol endCol ->
840+ A.Region (A.Position row startCol) (A.Position row endCol)
842+ Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
843+ Report.toCodeSnippet source escapeRegion Nothing
846+ "This is not a valid code point:"
849+ "The valid code points are between 0 and 10FFFF inclusive."
852+ BadUnicodeLength startCol endCol numDigits badCode ->
855+ A.Region (A.Position row startCol) (A.Position row endCol)
857+ Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
858+ Report.toCodeSnippet source escapeRegion Nothing $
859+ if numDigits < 4 then
862+ "Every code point needs at least four digits:"
865+ goodCode = replicate (4 - numDigits) '0' ++ showHex badCode ""
866+ escape = "\\u{" <> D.fromChars goodCode <> "}"
868+ D.fillSep ["Try",D.green escape,"instead?"]
874+ "This code point has too many digits:"
877+ ["Valid","code","points","are","between"
878+ ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
879+ ,"so","try","trimming","any","leading","zeros","until"
880+ ,"you","have","between","four","and","six","digits."
887+ Report.Report "EXPECTING A SHADER" region [] $
888+ Report.toCodeSnippet source region Nothing $
891+ "I was expecting a GLSL shader block here:"
894+ "These blocks start with [glsl| and end with |] and should be\
895+ \ filled with GLSL code."
898+ ShaderEnd startCol endCol ->
901+ A.Region (A.Position row startCol) (A.Position row endCol)
903+ Report.Report "ENDLESS SHADER" shaderRegion [] $
904+ Report.toCodeSnippet source shaderRegion Nothing
906+ D.reflow "I cannot find the end of this shader:"
908+ D.reflow "Add a |] somewhere after this to end the shader."
911+ ShaderProblem problem ->
912+ Report.Report "SHADER PROBLEM" region [] $
913+ Report.toCodeSnippet source region Nothing
916+ "I ran into a problem while parsing this GLSL block."
922+ Report.Report "EXPECTING AN OPERATOR" region [] $
923+ Report.toCodeSnippet source region Nothing
926+ "I was expecting an operator here:"
929+ [ D.reflow "Some of the most common operators are:"
930+ , D.indent 4 $ D.vcat ["+","-","*","&&","||"]
931+ , D.reflow "Something like that!"
935+ ReservedOperator op ->
936+ error "TODO ReservedOperator" op
939+ Report.Report "EXPECTING A WILDCARD" region [] $
940+ Report.toCodeSnippet source region Nothing
943+ "I was expecting a _ here:"
946+ "An underscore indicates that “I do not care about this value” and is\
947+ \ called a wildcard pattern because it will match with any type of values."
950+ WildcardNotVar startCol endCol ->
953+ A.Region (A.Position row startCol) (A.Position row endCol)
955+ Report.Report "INVALID PATTERN" badRegion [] $
956+ Report.toCodeSnippet source badRegion Nothing
959+ "I was expecting to see an underscore without any additional characters:"
962+ "There are two options. Either (1) remove the extra characters and ignore the\
963+ \ value or (2) remove the starting underscore to give the value a normal name."
969+ error "TODO" context
977+ Report.Report "INVALID PATTERN" region [] $
978+ Report.toCodeSnippet source region Nothing
981+ "I cannot pattern match with floating point numbers:"
984+ "Equality on floats can be unreliable, so you usually want to check that they\
985+ \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
989+ Report.Report "EXPECTING A FIELD NAME" region [] $
990+ Report.toCodeSnippet source region Nothing
993+ "I was expecting a field name here:"
996+ ["A","name","like",D.dullyellow "id" <> ",",D.dullyellow "status" <> ","
997+ ,"or","whatever","field","you","want","to","access."
1001+ -- Parse.Expression
1003+ MatchingName name ->
1004+ Report.Report "EXPECTING A DEFINITION" region [] $
1005+ Report.toCodeSnippet source region Nothing
1008+ "I just saw the type annotation for `" ++ Name.toChars name
1009+ ++ "` so I was expecting to see its definition here:"
1012+ "Type annotations always appear directly above the relevant\
1013+ \ definition, without anything else (even doc comments) in between."
1019+ Report.Report "EXPECTING END OF FILE" region [] $
1020+ Report.toCodeSnippet source region Nothing
1023+ "I was not expecting to see anything more here:"
1026+ "I think I have read all the declarations in the file and that there is nothing\
1027+ \ left to see, so whatever I am running into is confusing me a lot!"
1033+ TypeWithBadDefinition region annName defName ->
1034+ Report.Report "ANNOTATION MISMATCH" region [] $
1035+ Report.toCodeSnippet source region Nothing
1038+ "I see a `" <> Name.toChars annName
1039+ <> "` annotation, but it is followed by a `"
1040+ <> Name.toChars defName <> "` definition."
1043+ ["The","annotation","and","definition","names","must","match!"
1044+ ,"Is","there","a","typo","between"
1045+ , D.dullyellow (D.fromName annName)
1047+ , D.dullyellow (D.fromName defName) <> "?"
1052+-- PARSE ERROR TO DOCS
1055+problemToDocs :: Problem -> (D.Doc, D.Doc)
1056+problemToDocs problem =
1060+ "I ran into a tab, but tabs are not allowed in Elm files."
1062+ "Replace the tab with spaces."
1065+ EndOfFile_Comment ->
1067+ "I got to the end of the file while parsing a multi-line comment."
1070+ "Multi-line comments look like {- comment -}, and it looks like\
1071+ \ you are missing the closing marker."
1074+ "Nested multi-line comments like {- this {- and this -} -} are allowed.\
1075+ \ The opening and closing markers must be balanced though, just\
1076+ \ like parentheses in normal code. Maybe that is the problem?"
1080+ EndOfFile_String ->
1082+ "I got to the end of the file while parsing a string."
1084+ "Strings look like \"this\" with double quotes on each end.\
1085+ \ Is the closing double quote missing in your code?"
1088+ EndOfFile_MultiString ->
1090+ "I got to the end of the file while parsing a multi-line string."
1092+ "Multi-line strings look like \"\"\"this\"\"\" with three double quotes\
1093+ \ on each end. Is the closing triple quote missing in your code?"
1098+ "I got to the end of the file while parsing a character."
1100+ "Characters look like 'c' with single quotes on each end.\
1101+ \ Is the closing single quote missing in your code?"
1106+ "This string is missing the closing quote."
1109+ "Elm strings like \"this\" cannot contain newlines."
1112+ "For strings that CAN contain newlines, say \"\"\"this\"\"\" for Elm’s\
1113+ \ multi-line string syntax. It allows unescaped newlines and double quotes."
1119+ "This character is missing the closing quote."
1121+ "Elm characters must start and end with a single quote. Valid examples\n\
1122+ \ include 'a', 'b', '\n', 'ø', and '\\u{00F8}' for unicode code points."
1125+ BadNumberDot numberBeforeDot ->
1127+ "Numbers cannot end with a decimal points."
1131+ D.fromString (show numberBeforeDot)
1133+ "Saying " <> D.green number <> " or " <> D.green (number <> ".0") <> " will work though!"
1138+ "Numbers cannot have letters or underscores in them."
1140+ "Maybe a space is missing between a number and a variable?"
1145+ "If you put the letter E in a number, it should followed by more digits."
1147+ "If you want to say 1000, you can also say 1e3.\
1148+ \ You cannot just end it with an E though!"
1153+ "I see the start of a hex number, but not the end."
1155+ "A hex number looks like 0x123ABC, where the 0x is followed by hexidecimal\
1156+ \ digits. Valid hexidecimal digits include: 0123456789abcdefABCDEF"
1161+ "Normal numbers cannot start with zeros. Take the zeros off the front."
1163+ "Only numbers like 0x0040 or 0.25 can start with a zero."
1168+ "Variable names cannot start with an underscore like this:"
1170+ "Delete the underscore and it shoulld be fine!"
1176+ badOp stack "A" "\"has type\" operator"
1177+ "type annotations and record types"
1178+ "Maybe you want :: instead? Or maybe something is indented too much?"
1182+ "I was not expecting this equals sign"
1183+ <> contextToString " here" " while parsing " stack <> "."
1185+ toBadEqualsHint stack
1189+ if isCaseRelated stack then
1191+ "I ran into a stray arrow while parsing this `case` expression."
1194+ "All branches in a `case` must be indented the exact\
1195+ \ same amount, so the patterns are vertically\
1196+ \ aligned. Maybe this branch is indented too much?"
1200+ badOp stack "An" "arrow"
1201+ "cases expressions and anonymous functions"
1202+ "Maybe you want > or >= instead?"
1205+ badOp stack "A" "vertical bar"
1206+ "type declarations"
1207+ "Maybe you want || instead?"
1211+ "I was not expecting this dot."
1214+ "Dots are for record access and decimal points, so\
1215+ \ they cannot float around on their own. Maybe\
1216+ \ there is some extra whitespace?"
1219+ Theories stack allTheories ->
1222+ "Something went wrong while parsing " <> contextToString "your code" "" stack <> "."
1224+ case Set.toList (Set.fromList allTheories) of
1228+ "I do not have any suggestions though!"
1230+ "Can you get it down to a <http://sscce.org> and share it at\
1231+ \ <https://github.com/elm/error-message-catalog/issues>?\
1232+ \ That way we can figure out how to give better advice!"
1237+ "I was expecting to see "
1238+ <> addPeriod (theoryToString stack theory)
1242+ [ "I was expecting:"
1245+ ++ map (bullet . theoryToString stack) theories
1253+badOp :: ContextStack -> String -> String -> String -> String -> ( D.Doc, D.Doc )
1254+badOp stack article opName setting hint =
1257+ "I was not expecting this " <> opName
1258+ <> contextToString " here" " while parsing " stack <> "."
1261+ article <> " " <> opName <> " should only appear in "
1262+ <> setting <> ". " <> hint
1266+toBadEqualsHint :: ContextStack -> D.Doc
1267+toBadEqualsHint stack =
1271+ "Maybe you want == instead? Or maybe something is indented too much?"
1273+ (ExprRecord, _) : _ ->
1275+ "Records look like { x = 3, y = 4 } with the equals sign right\
1276+ \ after the field name. Maybe you forgot a comma?"
1278+ (Definition _, _) : rest ->
1280+ "Maybe this is supposed to be a separate definition? If so, it\
1281+ \ is indented too far. "
1283+ if any ((==) ExprLet . fst) rest then
1284+ "All definitions in a `let` expression must be vertically aligned."
1286+ "Spaces are not allowed before top-level definitions."
1289+ toBadEqualsHint rest
1293+isCaseRelated :: ContextStack -> Bool
1294+isCaseRelated stack =
1299+ (context, _) : rest ->
1300+ context == ExprCase || isCaseRelated rest
1307+contextToString :: String -> String -> ContextStack -> String
1308+contextToString defaultString prefixString stack =
1313+ (context, _) : rest ->
1314+ let anchor = getAnchor rest in
1317+ ExprIf -> "an `if` expression" <> anchor
1318+ ExprLet -> "a `let` expression" <> anchor
1319+ ExprFunc -> "an anonymous function" <> anchor
1320+ ExprCase -> "a `case` expression" <> anchor
1321+ ExprList -> "a list" <> anchor
1322+ ExprTuple -> "an expression (in parentheses)" <> anchor
1323+ ExprRecord -> "a record" <> anchor
1324+ Definition name -> Name.toChars name <> "'s definition"
1325+ Annotation name -> Name.toChars name <> "'s type annotation"
1326+ TypeTuple -> "a type (in parentheses)" <> anchor
1327+ TypeRecord -> "a record type" <> anchor
1328+ PatternList -> "a list pattern" <> anchor
1329+ PatternTuple -> "a pattern (in parentheses)" <> anchor
1330+ PatternRecord -> "a record pattern" <> anchor
1331+ Module -> "a module declaration"
1332+ Import -> "an import"
1333+ TypeUnion -> "a union type"
1334+ TypeAlias -> "a type alias"
1335+ Infix -> "an infix declaration"
1336+ Port -> "a port declaration"
1339+getAnchor :: ContextStack -> String
1345+ (context, _) : rest ->
1348+ " in " <> Name.toChars name <> "'s definition"
1351+ " in " <> Name.toChars name <> "'s type annotation"
1361+bullet :: String -> D.Doc
1363+ D.hang 4 (" - " <> D.fillSep (map D.fromString (words point)))
1366+addPeriod :: String -> String
1368+ if last msg `elem` ['`', ')', '.', '!', '?'] then
1374+theoryToString :: ContextStack -> Theory -> String
1375+theoryToString context theory =
1378+ "the `" <> keyword <> "` keyword"
1382+ "=" -> equalsTheory context
1383+ "->" -> "an arrow (->) followed by an expression"
1384+ ":" -> "the \"has type\" symbol (:) followed by a type"
1386+ "|" -> barTheory context
1387+ "::" -> "the cons operator (::) followed by more list elements"
1389+ "-" -> "a minus sign (-)"
1390+ "_" -> "an underscore"
1391+ "(" -> "a left paren, for grouping or starting tuples"
1392+ ")" -> "a closing paren"
1393+ "[" -> "a left square bracket, for starting lists"
1394+ "]" -> "a right square bracket, to end a list"
1395+ "{" -> "a left curly brace, for starting records"
1396+ "}" -> "a right curly brace, to end a record"
1397+ "{-|" -> "a doc comment, like {-| this -}" --}
1398+ _ -> "the (" <> symbol <> ") symbol"
1401+ "a lower-case variable, like `x` or `user`"
1404+ "an upper-case variable, like `Maybe` or `Just`"
1407+ "an infix operator, like (+) or (==)"
1410+ "a digit from 0 to 9"
1417+ Decl -> "a declaration, like `x = 5` or `type alias Model = { ... }`"
1418+ Expr -> "an expression, like x or 42"
1419+ AfterOpExpr op -> "an expression after that (" <> Name.toChars op <> ") operator, like x or 42"
1420+ ElseBranch -> "an `else` branch. An `if` must handle both possibilities."
1421+ Arg -> "an argument, like `name` or `total`"
1422+ Pattern -> "a pattern, like `name` or (Just x)"
1423+ Type -> "a type, like Int or (List String)"
1424+ Listing -> "a list of exposed values and types, like (..) or (x,y,z)"
1425+ Exposing -> "something like `exposing (..)`"
1428+equalsTheory :: ContextStack -> String
1429+equalsTheory stack =
1432+ "an equals sign (=)"
1434+ (context, _) : rest ->
1436+ ExprRecord -> "an equals sign (=) followed by an expression"
1437+ Definition name -> "an equals sign (=) followed by " <> Name.toChars name <> "'s definition"
1438+ TypeUnion -> "an equals sign (=) followed by the first union type constructor"
1439+ TypeAlias -> "an equals sign (=) followed by the aliased type"
1440+ _ -> equalsTheory rest
1443+barTheory :: ContextStack -> String
1447+ "a vertical bar (|)"
1449+ (context, _) : rest ->
1451+ ExprRecord -> "a vertical bar (|) followed by the record fields you want to update"
1452+ TypeRecord -> "a vertical bar (|) followed by some record field types"
1453+ TypeUnion -> "a vertical bar (|) followed by more union type constructors"
1454+ _ -> barTheory rest
1457+badSpace :: ContextStack -> String
1461+ "more indentation? I was not done with that last thing yet."
1463+ (context, _) : rest ->
1465+ ExprIf -> "the end of that `if`" <> badSpaceExprEnd rest
1466+ ExprLet -> "the end of that `let`" <> badSpaceExprEnd rest
1467+ ExprFunc -> badSpace rest
1468+ ExprCase -> "more of that `case`" <> badSpaceExprEnd rest
1469+ ExprList -> "the end of that list" <> badSpaceExprEnd rest
1470+ ExprTuple -> "a closing paren" <> badSpaceExprEnd rest
1471+ ExprRecord -> "the end of that record" <> badSpaceExprEnd rest
1472+ Definition name -> "the rest of " <> Name.toChars name <> "'s definition" <> badSpaceExprEnd stack
1473+ Annotation name -> "the rest of " <> Name.toChars name <> "'s type annotation" <> badSpaceEnd
1474+ TypeTuple -> "a closing paren" <> badSpaceEnd
1475+ TypeRecord -> "the end of that record" <> badSpaceEnd
1476+ PatternList -> "the end of that list" <> badSpaceEnd
1477+ PatternTuple -> "a closing paren" <> badSpaceEnd
1478+ PatternRecord -> "the end of that record" <> badSpaceEnd
1479+ Module -> "something like `module Main exposing (..)`"
1480+ Import -> "something like `import Html exposing (..)`"
1481+ TypeUnion -> "more of that union type" <> badSpaceEnd
1482+ TypeAlias -> "more of that type alias" <> badSpaceEnd
1483+ Infix -> "more of that infix declaration" <> badSpaceEnd
1484+ Port -> "more of that port declaration" <> badSpaceEnd
1487+badSpaceEnd :: String
1489+ ". Maybe you forgot some code? Or you need more indentation?"
1492+badSpaceExprEnd :: ContextStack -> String
1493+badSpaceExprEnd stack =
1498+ (Definition name, A.Position _ column) : _ ->
1501+ if column <= 1 then
1504+ "more indentation? (Try " <> show (column + 1) <> "+ spaces.)"
1506+ ". Maybe you forgot some code? Or maybe the body of `"
1507+ <> Name.toChars name
1508+ <> "` needs " <> ending
1511+ badSpaceExprEnd rest