1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Syntax
48import Prelude hiding (Char, String)
49import qualified Data.Char as Char
50import qualified Data.Name as Name
51import Data.Word (Word16)
52--import Numeric (showHex)
54import qualified Elm.ModuleName as ModuleName
55import Parse.Primitives (Row, Col)
56--import qualified Parse.Primitives as P
57import qualified Reporting.Annotation as A
58--import qualified Reporting.Doc as D
59import qualified Reporting.Report as Report
60import qualified Reporting.Render.Code as Code
68 = ModuleNameUnspecified ModuleName.Raw
69 | ModuleNameMismatch ModuleName.Raw (A.Located ModuleName.Raw)
70 | UnexpectedPort A.Region
80 = ModuleSpace Space Row Col
81 | ModuleEndOfFile Row Col
84 | ModuleExposing Row Col
85 | ModuleExposingList Exposing Row Col
87 | ModulePortModule Row Col
88 | ModuleEffect Row Col
90 | ModuleIndentStart Row Col
91 | ModuleIndentName Row Col
92 | ModuleIndentExposing Row Col
93 | ModuleIndentExposingList Row Col
94 | ModuleIndentPortModule Row Col
96 | FreshLineModuleStart Row Col
97 | FreshLineAfterModuleLine Row Col
98 | FreshLineAfterDocComment Row Col
100 | ImportStart Row Col
103 | ImportAlias Row Col
104 | ImportExposing Row Col
105 | ImportExposingList Exposing Row Col
106 | ImportEnd Row Col -- different based on col=1 or if greater
108 | ImportIndentName Row Col
109 | ImportIndentAs Row Col
110 | ImportIndentAlias Row Col
111 | ImportIndentExposing Row Col
112 | ImportIndentExposingList Row Col
116 | Declarations Decl Row Col
120 = ExposingSpace Space Row Col
121 | ExposingStart Row Col
122 | ExposingValue Row Col
123 | ExposingOperator Row Col
124 | ExposingOperatorReserved Operator Row Col
125 | ExposingOperatorRightParen Row Col
126 | ExposingEnd Row Col
128 | ExposingTypePrivacy Row Col
129 | ExposingTypePrivacyDots Row Col
130 | ExposingTypePrivacyEnd Row Col
132 | ExposingIndentEnd Row Col
133 | ExposingIndentValue Row Col
134 | ExposingIndentValueEnd Row Col
135 | ExposingIndentTypePrivacy Row Col
136 | ExposingIndentTypePrivacyDots Row Col
137 | ExposingIndentTypePrivacyEnd Row Col
146 | DeclSpace Space Row Col
149 | DeclType DeclType Row Col
150 | DeclDef Name.Name DeclDef Row Col
152 | DeclFreshLineStart Row Col
153 | DeclFreshLineAfterDocComment Row Col
157 = DeclDefSpace Space Row Col
158 | DeclDefEquals Row Col
159 | DeclDefType Type Row Col
160 | DeclDefArg Pattern Row Col
161 | DeclDefBody Expr Row Col
162 | DeclDefNameRepeat Name.Name Row Col
163 | DeclDefNameMatch Name.Name Name.Name Row Col
165 | DeclDefIndentType Row Col
166 | DeclDefIndentEquals Row Col
167 | DeclDefIndentBody Row Col
169 | DeclDefFreshLineAfterType Row Col
173 = PortSpace Space Row Col
176 | PortType Type Row Col
177 | PortIndentName Row Col
178 | PortIndentColon Row Col
179 | PortIndentType Row Col
187 = DT_Space Space Row Col
189 | DT_Alias TypeAlias Row Col
190 | DT_Union CustomType Row Col
192 | DT_IndentName Row Col
196 = AliasSpace Space Row Col
198 | AliasEquals Row Col
199 | AliasBody Type Row Col
201 | AliasIndentEquals Row Col
202 | AliasIndentBody Row Col
206 = CT_Space Space Row Col
211 | CT_VariantArg Type Row Col
213 | CT_IndentEquals Row Col
214 | CT_IndentBar Row Col
215 | CT_IndentAfterBar Row Col
216 | CT_IndentAfterEquals Row Col
228 | Record Record Row Col
229 | Update Expr Row Col
230 | Tuple Tuple Row Col
235 | OperatorRHS Row Col
236 | OperatorRight Row Col
237 | OperatorReserved Operator Row Col
241 | String String Row Col
242 | Number Number Row Col
243 | Space Space Row Col
244 | EndlessShader Row Col
245 | ShaderProblem [Char.Char] Row Col
246 | IndentOperatorRight Row Col
247 | IndentMoreExpr Row Col
253 | RecordField Row Col
254 | RecordEquals Row Col
255 | RecordExpr Expr Row Col
256 | RecordSpace Space Row Col
258 | RecordIndentOpen Row Col
259 | RecordIndentEnd Row Col
260 | RecordIndentField Row Col
261 | RecordIndentEquals Row Col
262 | RecordIndentExpr Row Col
267 | TupleExpr Expr Row Col
268 | TupleSpace Space Row Col
270 | TupleOperatorClose Row Col
271 | TupleOperatorReserved Operator Row Col
273 | TupleIndentExpr Row Col
274 | TupleIndentEnd Row Col
278 = ListSpace Space Row Col
280 | ListExpr Expr Row Col
283 | ListIndentOpen Row Col
284 | ListIndentEnd Row Col
285 | ListIndentExpr Row Col
289 = FuncSpace Space Row Col
290 | FuncArg Pattern Row Col
291 | FuncBody Expr Row Col
294 | FuncIndentArg Row Col
295 | FuncIndentArrow Row Col
296 | FuncIndentBody Row Col
300 = CaseSpace Space Row Col
302 | CasePattern Pattern Row Col
304 | CaseExpr Expr Row Col
305 | CaseBranch Expr Row Col
307 | CaseIndentOf Row Col
308 | CaseIndentExpr Row Col
309 | CaseIndentPattern Row Col
310 | CaseIndentArrow Row Col
311 | CaseIndentBranch Row Col
312 | CasePatternAlignment Word16 Row Col
316 = IfSpace Space Row Col
319 | IfElseBranchStart Row Col
321 | IfCondition Expr Row Col
322 | IfThenBranch Expr Row Col
323 | IfElseBranch Expr Row Col
325 | IfIndentCondition Row Col
326 | IfIndentThen Row Col
327 | IfIndentThenBranch Row Col
328 | IfIndentElseBranch Row Col
329 | IfIndentElse Row Col
333 = LetSpace Space Row Col
335 | LetDefAlignment Word16 Row Col
337 | LetDef Name.Name Def Row Col
338 | LetDestruct Destruct Row Col
339 | LetBody Expr Row Col
340 | LetIndentDef Row Col
341 | LetIndentIn Row Col
342 | LetIndentBody Row Col
346 = DefSpace Space Row Col
347 | DefType Type Row Col
348 | DefNameRepeat Name.Name Row Col
349 | DefNameMatch Name.Name Name.Name Row Col
350 | DefArg Pattern Row Col
352 | DefBody Expr Row Col
353 | DefIndentEquals Row Col
354 | DefIndentType Row Col
355 | DefIndentBody Row Col
356 | DefAlignment Word16 Row Col
360 = DestructSpace Space Row Col
361 | DestructPattern Pattern Row Col
362 | DestructEquals Row Col
363 | DestructBody Expr Row Col
364 | DestructIndentEquals Row Col
365 | DestructIndentBody Row Col
373 = PRecord PRecord Row Col
374 | PTuple PTuple Row Col
375 | PList PList Row Col
379 | PString String Row Col
380 | PNumber Number Row Col
383 | PWildcardNotVar Int Row Col
384 | PSpace Space Row Col
386 | PIndentStart Row Col
387 | PIndentAlias Row Col
391 = PRecordOpen Row Col
393 | PRecordField Row Col
394 | PRecordSpace Space Row Col
396 | PRecordIndentOpen Row Col
397 | PRecordIndentEnd Row Col
398 | PRecordIndentField Row Col
404 | PTupleExpr Pattern Row Col
405 | PTupleSpace Space Row Col
407 | PTupleIndentOpen Row Col
408 | PTupleIndentEnd Row Col
409 | PTupleIndentExpr Row Col
415 | PListExpr Pattern Row Col
416 | PListSpace Space Row Col
418 | PListIndentOpen Row Col
419 | PListIndentEnd Row Col
420 | PListIndentExpr Row Col
428 = TRecord TRecord Row Col
429 | TTuple TTuple Row Col
434 | TSpace Space Row Col
436 | TIndentStart Row Col
440 = TRecordOpen Row Col
443 | TRecordField Row Col
444 | TRecordColon Row Col
445 | TRecordType Type Row Col
447 | TRecordSpace Space Row Col
449 | TRecordIndentOpen Row Col
450 | TRecordIndentField Row Col
451 | TRecordIndentColon Row Col
452 | TRecordIndentType Row Col
453 | TRecordIndentEnd Row Col
459 | TTupleType Type Row Col
460 | TTupleSpace Space Row Col
462 | TTupleIndentOpen Row Col
463 | TTupleIndentType Row Col
464 | TTupleIndentEnd Row Col
478 = StringEndless_Single
479 | StringEndless_Multi
480 | StringEscape Escape
484 = EscapeUnknown Word16 Word16
485 | BadUnicodeFormat Word16 Word16
486 | BadUnicodeCode Word16 Word16
487 | BadUnicodeLength Word16 Word16 Int Int
494 | NumberNoLeadingZero
503 | EndlessMultiComment
504 | UnexpectedDocComment
519toReport :: Code.Source -> Error -> Report.Report
521 error "TODO" source err
524 CommentOnNothing region ->
525 Report.Report "STRAY COMMENT" region [] $
526 Report.toCodeSnippet source region Nothing
528 "This documentation comment is not followed by anything."
531 "All documentation comments need to be right above the declaration they\
532 \ describe. Maybe some code got deleted or commented out by accident? Or\
533 \ maybe this comment is here by accident?"
536 UnexpectedPort region ->
537 Report.Report "UNEXPECTED PORTS" region [] $
538 Report.toCodeSnippet source region Nothing
541 "You are declaring ports in a normal module."
545 ["Switch","this","to","say",D.green "port module","instead,"
546 ,"marking","that","this","module","contains","port","declarations."
549 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
551 "to learn the syntax and how to use it effectively."
556 Report.Report "NO PORTS" region [] $
557 Report.toCodeSnippet source region Nothing
560 "This module does not declare any ports, but it says it will:"
563 ["Switch","this","to",D.green "module"
564 ,"and","you","should","be","all","set!"
568 ParseError row col context expectation ->
570 pos = A.Position row col
571 region = A.Region pos pos
575 error "TODO no parse error yet"
578 error "TODO no parse error yet"
583 Report.Report "NO TABS" region [] $
584 Report.toCodeSnippet source region Nothing
587 "I ran into a tab, but tabs are not allowed in Elm files."
590 "Replace the tab with spaces."
594 Report.Report "EXPECTING DOC COMMENT" region [] $
595 Report.toCodeSnippet source region Nothing
598 "I was expecting a doc comment here:"
601 "Check out" "TODO" "for examples of doc comments."
604 MultiCommentEnd startRow startCol ->
608 (A.Position startRow startCol)
609 (A.Position startRow (startCol + 3))
611 Report.Report "ENDLESS COMMENT" startRegion [] $
612 Report.toCodeSnippet source startRegion Nothing
615 "I cannot find the end of this multi-line comment:"
618 [ D.reflow "Add a -} somewhere after this to end the comment."
620 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
621 \ that happens to contain another comment. Like parentheses and curly braces,\
622 \ the start and end markers must always be balanced. Maybe that is the problem?"
629 Report.Report "EXPECTING NUMBER" region [] $
630 Report.toCodeSnippet source region Nothing
633 "I was expecting to see a number here:"
637 "I recognize numbers in the following formats:"
638 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
640 "So is there a way to write it like one of those?"
645 Report.Report "WEIRD NUMBER" region [] $
646 Report.toCodeSnippet source region Nothing
649 "I thought I was reading a number, but I ran into some weird stuff here:"
653 "I recognize numbers in the following formats:"
654 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
656 "So is there a way to write it like one of those?"
661 Report.Report "WEIRD NUMBER" region [] $
662 Report.toCodeSnippet source region Nothing
665 "Numbers cannot end with a dot like this:"
668 ["Switching","to",D.green (D.fromChars (show int))
669 ,"or",D.green (D.fromChars (show int ++ ".0"))
670 ,"will","work","though!"
675 Report.Report "WEIRD HEXIDECIMAL" region [] $
676 Report.toCodeSnippet source region Nothing
679 "I thought I was reading a hexidecimal number until I got here:"
683 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
684 \ only recognize things like this:"
685 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
689 Number_NoLeadingZero ->
690 Report.Report "LEADING ZEROS" region [] $
691 Report.toCodeSnippet source region Nothing
694 "I do not accept numbers with leading zeros:"
698 "Just delete the leading zeros and it should work!"
700 "Some languages let you to specify octal numbers by adding a leading zero.\
701 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
702 \ that, but others probably want it to equal 111. Either path is going to\
703 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
709 Report.Report "EXPECTING PRECEDENCE" region [] $
710 Report.toCodeSnippet source region Nothing
713 "I was expecting the precedence here:"
716 "I need a single digit between 0 and 9 inclusive."
722 Report.Report "EXPECTING A CHARACTER" region [] $
723 Report.toCodeSnippet source region Nothing
726 "I was expecting a character here:"
730 "Characters start and end with single quotes, like this:"
731 , D.indent 4 $ D.vcat $
739 "That last style lets you encode characters by their unicode\
740 \ code point, so 'a' is equivalent to '\\u{0061}', 'ø' is\
741 \ equivalent to '\\u{00F8}', and so on for all code points."
746 Report.Report "MISSING SINGLE QUOTE" region [] $
747 Report.toCodeSnippet source region Nothing
750 "I thought I was parsing a character, but I got to the end of\
751 \ the line without seeing the closing single quote:"
755 "Characters start and end with single quotes, like this:"
756 , D.indent 4 $ D.vcat $
764 "That last style lets you encode characters by their unicode\
765 \ code point, so 'a' is equivalent to '\\u{0061}', 'ø' is\
766 \ equivalent to '\\u{00F8}', and so on for all code points."
770 CharNotString startRow startCol ->
773 A.Region (A.Position startRow startCol) pos
775 Report.Report "NEEDS DOUBLE QUOTES" stringRegion [] $
776 Report.toCodeSnippet source stringRegion Nothing
778 "The following string uses single quotes:"
781 [ "Please switch to double quotes instead:"
783 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
785 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
786 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
787 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
788 \ individual characters."
793 Report.Report "EXPECTING A STRING" region [] $
794 Report.toCodeSnippet source region Nothing
797 "I was expecting a string here:"
804 ,"with","double","quotes."
809 Report.Report "ENDLESS STRING" region [] $
810 Report.toCodeSnippet source region Nothing
813 "I got to the end of the line without seeing the closing double quote:"
817 ["Strings","look","like",D.green "\"this\"","with","double"
818 ,"quotes","on","each","end.","Is","the","closing","double"
819 ,"quote","missing","in","your","code?"
821 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
825 StringEnd_Multi startRow startCol ->
829 (A.Position startRow startCol)
830 (A.Position startRow (startCol + 3))
832 Report.Report "ENDLESS STRING" startRegion [] $
833 Report.toCodeSnippet source startRegion Nothing
836 "I cannot find the end of this multi-line string:"
839 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
840 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
844 EscapeUnknown startCol endCol ->
847 A.Region (A.Position row startCol) (A.Position row endCol)
849 Report.Report "UNKNOWN ESCAPE" escapeRegion [] $
850 Report.toCodeSnippet source escapeRegion Nothing
853 "Backslashes always start escaped characters, but I do not recognize this one:"
857 "Valid escape characters include:"
858 , D.indent 4 $ D.vcat $
868 "The last one lets encode ANY character by its Unicode code\
869 \ point, so use that for anything outside the ordinary six."
873 BadUnicodeFormat startCol endCol ->
876 A.Region (A.Position row startCol) (A.Position row endCol)
878 Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
879 Report.toCodeSnippet source escapeRegion Nothing
882 "I ran into an invalid Unicode escape:"
886 "Here are some examples of valid Unicode escapes:"
887 , D.green $ D.indent 4 $ D.vcat $
894 "Notice that the code point is always surrounded by curly\
895 \ braces. They are required!"
899 BadUnicodeCode startCol endCol ->
902 A.Region (A.Position row startCol) (A.Position row endCol)
904 Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
905 Report.toCodeSnippet source escapeRegion Nothing
908 "This is not a valid code point:"
911 "The valid code points are between 0 and 10FFFF inclusive."
914 BadUnicodeLength startCol endCol numDigits badCode ->
917 A.Region (A.Position row startCol) (A.Position row endCol)
919 Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
920 Report.toCodeSnippet source escapeRegion Nothing $
921 if numDigits < 4 then
924 "Every code point needs at least four digits:"
927 goodCode = replicate (4 - numDigits) '0' ++ showHex badCode ""
928 escape = "\\u{" <> D.fromChars goodCode <> "}"
930 D.fillSep ["Try",D.green escape,"instead?"]
936 "This code point has too many digits:"
939 ["Valid","code","points","are","between"
940 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
941 ,"so","try","trimming","any","leading","zeros","until"
942 ,"you","have","between","four","and","six","digits."
949 Report.Report "EXPECTING A SHADER" region [] $
950 Report.toCodeSnippet source region Nothing $
953 "I was expecting a GLSL shader block here:"
956 "These blocks start with [glsl| and end with |] and should be\
957 \ filled with GLSL code."
960 ShaderEnd startCol endCol ->
963 A.Region (A.Position row startCol) (A.Position row endCol)
965 Report.Report "ENDLESS SHADER" shaderRegion [] $
966 Report.toCodeSnippet source shaderRegion Nothing
968 D.reflow "I cannot find the end of this shader:"
970 D.reflow "Add a |] somewhere after this to end the shader."
973 ShaderProblem problem ->
974 Report.Report "SHADER PROBLEM" region [] $
975 Report.toCodeSnippet source region Nothing
978 "I ran into a problem while parsing this GLSL block."
984 Report.Report "EXPECTING AN OPERATOR" region [] $
985 Report.toCodeSnippet source region Nothing
988 "I was expecting an operator here:"
991 [ D.reflow "Some of the most common operators are:"
992 , D.indent 4 $ D.vcat ["+","-","*","&&","||"]
993 , D.reflow "Something like that!"
997 ReservedOperator op ->
998 error "TODO ReservedOperator" op
1001 Report.Report "EXPECTING A WILDCARD" region [] $
1002 Report.toCodeSnippet source region Nothing
1005 "I was expecting a _ here:"
1008 "An underscore indicates that “I do not care about this value” and is\
1009 \ called a wildcard pattern because it will match with any type of values."
1012 WildcardNotVar startCol endCol ->
1015 A.Region (A.Position row startCol) (A.Position row endCol)
1017 Report.Report "INVALID PATTERN" badRegion [] $
1018 Report.toCodeSnippet source badRegion Nothing
1021 "I was expecting to see an underscore without any additional characters:"
1024 "There are two options. Either (1) remove the extra characters and ignore the\
1025 \ value or (2) remove the starting underscore to give the value a normal name."
1031 error "TODO" context
1039 Report.Report "INVALID PATTERN" region [] $
1040 Report.toCodeSnippet source region Nothing
1043 "I cannot pattern match with floating point numbers:"
1046 "Equality on floats can be unreliable, so you usually want to check that they\
1047 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
1051 Report.Report "EXPECTING A FIELD NAME" region [] $
1052 Report.toCodeSnippet source region Nothing
1055 "I was expecting a field name here:"
1058 ["A","name","like",D.dullyellow "id" <> ",",D.dullyellow "status" <> ","
1059 ,"or","whatever","field","you","want","to","access."
1065 MatchingName name ->
1066 Report.Report "EXPECTING A DEFINITION" region [] $
1067 Report.toCodeSnippet source region Nothing
1070 "I just saw the type annotation for `" ++ Name.toChars name
1071 ++ "` so I was expecting to see its definition here:"
1074 "Type annotations always appear directly above the relevant\
1075 \ definition, without anything else (even doc comments) in between."
1081 Report.Report "EXPECTING END OF FILE" region [] $
1082 Report.toCodeSnippet source region Nothing
1085 "I was not expecting to see anything more here:"
1088 "I think I have read all the declarations in the file and that there is nothing\
1089 \ left to see, so whatever I am running into is confusing me a lot!"
1095 TypeWithBadDefinition region annName defName ->
1096 Report.Report "ANNOTATION MISMATCH" region [] $
1097 Report.toCodeSnippet source region Nothing
1100 "I see a `" <> Name.toChars annName
1101 <> "` annotation, but it is followed by a `"
1102 <> Name.toChars defName <> "` definition."
1105 ["The","annotation","and","definition","names","must","match!"
1106 ,"Is","there","a","typo","between"
1107 , D.dullyellow (D.fromName annName)
1109 , D.dullyellow (D.fromName defName) <> "?"
1114-- PARSE ERROR TO DOCS
1117problemToDocs :: Problem -> (D.Doc, D.Doc)
1118problemToDocs problem =
1122 "I ran into a tab, but tabs are not allowed in Elm files."
1124 "Replace the tab with spaces."
1127 EndOfFile_Comment ->
1129 "I got to the end of the file while parsing a multi-line comment."
1132 "Multi-line comments look like {- comment -}, and it looks like\
1133 \ you are missing the closing marker."
1136 "Nested multi-line comments like {- this {- and this -} -} are allowed.\
1137 \ The opening and closing markers must be balanced though, just\
1138 \ like parentheses in normal code. Maybe that is the problem?"
1144 "I got to the end of the file while parsing a string."
1146 "Strings look like \"this\" with double quotes on each end.\
1147 \ Is the closing double quote missing in your code?"
1150 EndOfFile_MultiString ->
1152 "I got to the end of the file while parsing a multi-line string."
1154 "Multi-line strings look like \"\"\"this\"\"\" with three double quotes\
1155 \ on each end. Is the closing triple quote missing in your code?"
1160 "I got to the end of the file while parsing a character."
1162 "Characters look like 'c' with single quotes on each end.\
1163 \ Is the closing single quote missing in your code?"
1168 "This string is missing the closing quote."
1171 "Elm strings like \"this\" cannot contain newlines."
1174 "For strings that CAN contain newlines, say \"\"\"this\"\"\" for Elm’s\
1175 \ multi-line string syntax. It allows unescaped newlines and double quotes."
1181 "This character is missing the closing quote."
1183 "Elm characters must start and end with a single quote. Valid examples\n\
1184 \ include 'a', 'b', '\n', 'ø', and '\\u{00F8}' for unicode code points."
1187 BadNumberDot numberBeforeDot ->
1189 "Numbers cannot end with a decimal points."
1193 D.fromString (show numberBeforeDot)
1195 "Saying " <> D.green number <> " or " <> D.green (number <> ".0") <> " will work though!"
1200 "Numbers cannot have letters or underscores in them."
1202 "Maybe a space is missing between a number and a variable?"
1207 "If you put the letter E in a number, it should followed by more digits."
1209 "If you want to say 1000, you can also say 1e3.\
1210 \ You cannot just end it with an E though!"
1215 "I see the start of a hex number, but not the end."
1217 "A hex number looks like 0x123ABC, where the 0x is followed by hexidecimal\
1218 \ digits. Valid hexidecimal digits include: 0123456789abcdefABCDEF"
1223 "Normal numbers cannot start with zeros. Take the zeros off the front."
1225 "Only numbers like 0x0040 or 0.25 can start with a zero."
1230 "Variable names cannot start with an underscore like this:"
1232 "Delete the underscore and it shoulld be fine!"
1238 badOp stack "A" "\"has type\" operator"
1239 "type annotations and record types"
1240 "Maybe you want :: instead? Or maybe something is indented too much?"
1244 "I was not expecting this equals sign"
1245 <> contextToString " here" " while parsing " stack <> "."
1247 toBadEqualsHint stack
1251 if isCaseRelated stack then
1253 "I ran into a stray arrow while parsing this `case` expression."
1256 "All branches in a `case` must be indented the exact\
1257 \ same amount, so the patterns are vertically\
1258 \ aligned. Maybe this branch is indented too much?"
1262 badOp stack "An" "arrow"
1263 "cases expressions and anonymous functions"
1264 "Maybe you want > or >= instead?"
1267 badOp stack "A" "vertical bar"
1269 "Maybe you want || instead?"
1273 "I was not expecting this dot."
1276 "Dots are for record access and decimal points, so\
1277 \ they cannot float around on their own. Maybe\
1278 \ there is some extra whitespace?"
1281 Theories stack allTheories ->
1284 "Something went wrong while parsing " <> contextToString "your code" "" stack <> "."
1286 case Set.toList (Set.fromList allTheories) of
1290 "I do not have any suggestions though!"
1292 "Can you get it down to a <http://sscce.org> and share it at\
1293 \ <https://github.com/elm/error-message-catalog/issues>?\
1294 \ That way we can figure out how to give better advice!"
1299 "I was expecting to see "
1300 <> addPeriod (theoryToString stack theory)
1304 [ "I was expecting:"
1307 ++ map (bullet . theoryToString stack) theories
1315badOp :: ContextStack -> String -> String -> String -> String -> ( D.Doc, D.Doc )
1316badOp stack article opName setting hint =
1319 "I was not expecting this " <> opName
1320 <> contextToString " here" " while parsing " stack <> "."
1323 article <> " " <> opName <> " should only appear in "
1324 <> setting <> ". " <> hint
1328toBadEqualsHint :: ContextStack -> D.Doc
1329toBadEqualsHint stack =
1333 "Maybe you want == instead? Or maybe something is indented too much?"
1335 (ExprRecord, _) : _ ->
1337 "Records look like { x = 3, y = 4 } with the equals sign right\
1338 \ after the field name. Maybe you forgot a comma?"
1340 (Definition _, _) : rest ->
1342 "Maybe this is supposed to be a separate definition? If so, it\
1343 \ is indented too far. "
1345 if any ((==) ExprLet . fst) rest then
1346 "All definitions in a `let` expression must be vertically aligned."
1348 "Spaces are not allowed before top-level definitions."
1351 toBadEqualsHint rest
1355isCaseRelated :: ContextStack -> Bool
1356isCaseRelated stack =
1361 (context, _) : rest ->
1362 context == ExprCase || isCaseRelated rest
1369contextToString :: String -> String -> ContextStack -> String
1370contextToString defaultString prefixString stack =
1375 (context, _) : rest ->
1376 let anchor = getAnchor rest in
1379 ExprIf -> "an `if` expression" <> anchor
1380 ExprLet -> "a `let` expression" <> anchor
1381 ExprFunc -> "an anonymous function" <> anchor
1382 ExprCase -> "a `case` expression" <> anchor
1383 ExprList -> "a list" <> anchor
1384 ExprTuple -> "an expression (in parentheses)" <> anchor
1385 ExprRecord -> "a record" <> anchor
1386 Definition name -> Name.toChars name <> "'s definition"
1387 Annotation name -> Name.toChars name <> "'s type annotation"
1388 TypeTuple -> "a type (in parentheses)" <> anchor
1389 TypeRecord -> "a record type" <> anchor
1390 PatternList -> "a list pattern" <> anchor
1391 PatternTuple -> "a pattern (in parentheses)" <> anchor
1392 PatternRecord -> "a record pattern" <> anchor
1393 Module -> "a module declaration"
1394 Import -> "an import"
1395 TypeUnion -> "a union type"
1396 TypeAlias -> "a type alias"
1397 Infix -> "an infix declaration"
1398 Port -> "a port declaration"
1401getAnchor :: ContextStack -> String
1407 (context, _) : rest ->
1410 " in " <> Name.toChars name <> "'s definition"
1413 " in " <> Name.toChars name <> "'s type annotation"
1423bullet :: String -> D.Doc
1425 D.hang 4 (" - " <> D.fillSep (map D.fromString (words point)))
1428addPeriod :: String -> String
1430 if last msg `elem` ['`', ')', '.', '!', '?'] then
1436theoryToString :: ContextStack -> Theory -> String
1437theoryToString context theory =
1440 "the `" <> keyword <> "` keyword"
1444 "=" -> equalsTheory context
1445 "->" -> "an arrow (->) followed by an expression"
1446 ":" -> "the \"has type\" symbol (:) followed by a type"
1448 "|" -> barTheory context
1449 "::" -> "the cons operator (::) followed by more list elements"
1451 "-" -> "a minus sign (-)"
1452 "_" -> "an underscore"
1453 "(" -> "a left paren, for grouping or starting tuples"
1454 ")" -> "a closing paren"
1455 "[" -> "a left square bracket, for starting lists"
1456 "]" -> "a right square bracket, to end a list"
1457 "{" -> "a left curly brace, for starting records"
1458 "}" -> "a right curly brace, to end a record"
1459 "{-|" -> "a doc comment, like {-| this -}" --}
1460 _ -> "the (" <> symbol <> ") symbol"
1463 "a lower-case variable, like `x` or `user`"
1466 "an upper-case variable, like `Maybe` or `Just`"
1469 "an infix operator, like (+) or (==)"
1472 "a digit from 0 to 9"
1479 Decl -> "a declaration, like `x = 5` or `type alias Model = { ... }`"
1480 Expr -> "an expression, like x or 42"
1481 AfterOpExpr op -> "an expression after that (" <> Name.toChars op <> ") operator, like x or 42"
1482 ElseBranch -> "an `else` branch. An `if` must handle both possibilities."
1483 Arg -> "an argument, like `name` or `total`"
1484 Pattern -> "a pattern, like `name` or (Just x)"
1485 Type -> "a type, like Int or (List String)"
1486 Listing -> "a list of exposed values and types, like (..) or (x,y,z)"
1487 Exposing -> "something like `exposing (..)`"
1490equalsTheory :: ContextStack -> String
1494 "an equals sign (=)"
1496 (context, _) : rest ->
1498 ExprRecord -> "an equals sign (=) followed by an expression"
1499 Definition name -> "an equals sign (=) followed by " <> Name.toChars name <> "'s definition"
1500 TypeUnion -> "an equals sign (=) followed by the first union type constructor"
1501 TypeAlias -> "an equals sign (=) followed by the aliased type"
1502 _ -> equalsTheory rest
1505barTheory :: ContextStack -> String
1509 "a vertical bar (|)"
1511 (context, _) : rest ->
1513 ExprRecord -> "a vertical bar (|) followed by the record fields you want to update"
1514 TypeRecord -> "a vertical bar (|) followed by some record field types"
1515 TypeUnion -> "a vertical bar (|) followed by more union type constructors"
1519badSpace :: ContextStack -> String
1523 "more indentation? I was not done with that last thing yet."
1525 (context, _) : rest ->
1527 ExprIf -> "the end of that `if`" <> badSpaceExprEnd rest
1528 ExprLet -> "the end of that `let`" <> badSpaceExprEnd rest
1529 ExprFunc -> badSpace rest
1530 ExprCase -> "more of that `case`" <> badSpaceExprEnd rest
1531 ExprList -> "the end of that list" <> badSpaceExprEnd rest
1532 ExprTuple -> "a closing paren" <> badSpaceExprEnd rest
1533 ExprRecord -> "the end of that record" <> badSpaceExprEnd rest
1534 Definition name -> "the rest of " <> Name.toChars name <> "'s definition" <> badSpaceExprEnd stack
1535 Annotation name -> "the rest of " <> Name.toChars name <> "'s type annotation" <> badSpaceEnd
1536 TypeTuple -> "a closing paren" <> badSpaceEnd
1537 TypeRecord -> "the end of that record" <> badSpaceEnd
1538 PatternList -> "the end of that list" <> badSpaceEnd
1539 PatternTuple -> "a closing paren" <> badSpaceEnd
1540 PatternRecord -> "the end of that record" <> badSpaceEnd
1541 Module -> "something like `module Main exposing (..)`"
1542 Import -> "something like `import Html exposing (..)`"
1543 TypeUnion -> "more of that union type" <> badSpaceEnd
1544 TypeAlias -> "more of that type alias" <> badSpaceEnd
1545 Infix -> "more of that infix declaration" <> badSpaceEnd
1546 Port -> "more of that port declaration" <> badSpaceEnd
1549badSpaceEnd :: String
1551 ". Maybe you forgot some code? Or you need more indentation?"
1554badSpaceExprEnd :: ContextStack -> String
1555badSpaceExprEnd stack =
1560 (Definition name, A.Position _ column) : _ ->
1566 "more indentation? (Try " <> show (column + 1) <> "+ spaces.)"
1568 ". Maybe you forgot some code? Or maybe the body of `"
1569 <> Name.toChars name
1570 <> "` needs " <> ending
1573 badSpaceExprEnd rest
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list