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 Parse.Primitives (Row, Col)
55--import qualified Parse.Primitives as P
56import qualified Reporting.Annotation as A
57--import qualified Reporting.Doc as D
58import qualified Reporting.Report as Report
59import qualified Reporting.Render.Code as Code
67 = CommentOnNothing A.Region
68 | UnexpectedPort A.Region
78 = ModuleSpace Space Row Col
79 | ModuleEndOfFile Row Col
82 | ModuleExposing Row Col
83 | ModuleExposingList Exposing Row Col
85 | ModulePortModule Row Col
86 | ModuleEffect Row Col
88 | ModuleIndentStart Row Col
89 | ModuleIndentName Row Col
90 | ModuleIndentExposing Row Col
91 | ModuleIndentExposingList Row Col
92 | ModuleIndentPortModule Row Col
94 | FreshLineModuleStart Row Col
95 | FreshLineAfterModuleLine Row Col
96 | FreshLineAfterDocComment Row Col
101 | ImportAlias Row Col
102 | ImportExposing Row Col
103 | ImportExposingList Exposing Row Col
104 | ImportEnd Row Col -- different based on col=1 or if greater
106 | ImportIndentName Row Col
107 | ImportIndentAs Row Col
108 | ImportIndentAlias Row Col
109 | ImportIndentExposing Row Col
110 | ImportIndentExposingList Row Col
114 | Declarations Decl Row Col
118 = ExposingSpace Space Row Col
119 | ExposingStart Row Col
120 | ExposingValue Row Col
121 | ExposingOperator Row Col
122 | ExposingOperatorReserved Operator Row Col
123 | ExposingOperatorRightParen Row Col
124 | ExposingEnd Row Col
126 | ExposingTypePrivacy Row Col
127 | ExposingTypePrivacyDots Row Col
128 | ExposingTypePrivacyEnd Row Col
130 | ExposingIndentEnd Row Col
131 | ExposingIndentValue Row Col
132 | ExposingIndentValueEnd Row Col
133 | ExposingIndentTypePrivacy Row Col
134 | ExposingIndentTypePrivacyDots Row Col
135 | ExposingIndentTypePrivacyEnd Row Col
144 | DeclSpace Space Row Col
147 | DeclType DeclType Row Col
148 | DeclDef Name.Name DeclDef Row Col
150 | DeclFreshLineStart Row Col
151 | DeclFreshLineAfterDocComment Row Col
155 = DeclDefSpace Space Row Col
156 | DeclDefEquals Row Col
157 | DeclDefType Type Row Col
158 | DeclDefArg Pattern Row Col
159 | DeclDefBody Expr Row Col
160 | DeclDefNameRepeat Name.Name Row Col
161 | DeclDefNameMatch Name.Name Name.Name Row Col
163 | DeclDefIndentType Row Col
164 | DeclDefIndentEquals Row Col
165 | DeclDefIndentBody Row Col
167 | DeclDefFreshLineAfterType Row Col
171 = PortSpace Space Row Col
174 | PortType Type Row Col
175 | PortIndentName Row Col
176 | PortIndentColon Row Col
177 | PortIndentType Row Col
185 = DT_Space Space Row Col
187 | DT_Alias TypeAlias Row Col
188 | DT_Union CustomType Row Col
190 | DT_IndentName Row Col
194 = AliasSpace Space Row Col
196 | AliasEquals Row Col
197 | AliasBody Type Row Col
199 | AliasIndentEquals Row Col
200 | AliasIndentBody Row Col
204 = CT_Space Space Row Col
209 | CT_VariantArg Type Row Col
211 | CT_IndentEquals Row Col
212 | CT_IndentBar Row Col
213 | CT_IndentAfterBar Row Col
214 | CT_IndentAfterEquals Row Col
226 | Record Record Row Col
227 | Update Expr Row Col
228 | Tuple Tuple Row Col
233 | OperatorRHS Row Col
234 | OperatorRight Row Col
235 | OperatorReserved Operator Row Col
239 | String String Row Col
240 | Number Number Row Col
241 | Space Space Row Col
242 | EndlessShader Row Col
243 | ShaderProblem [Char.Char] Row Col
244 | IndentOperatorRight Row Col
245 | IndentMoreExpr Row Col
251 | RecordField Row Col
252 | RecordEquals Row Col
253 | RecordExpr Expr Row Col
254 | RecordSpace Space Row Col
256 | RecordIndentOpen Row Col
257 | RecordIndentEnd Row Col
258 | RecordIndentField Row Col
259 | RecordIndentEquals Row Col
260 | RecordIndentExpr Row Col
265 | TupleExpr Expr Row Col
266 | TupleSpace Space Row Col
268 | TupleOperatorClose Row Col
269 | TupleOperatorReserved Operator Row Col
271 | TupleIndentExpr Row Col
272 | TupleIndentEnd Row Col
276 = ListSpace Space Row Col
278 | ListExpr Expr Row Col
281 | ListIndentOpen Row Col
282 | ListIndentEnd Row Col
283 | ListIndentExpr Row Col
287 = FuncSpace Space Row Col
288 | FuncArg Pattern Row Col
289 | FuncBody Expr Row Col
292 | FuncIndentArg Row Col
293 | FuncIndentArrow Row Col
294 | FuncIndentBody Row Col
298 = CaseSpace Space Row Col
300 | CasePattern Pattern Row Col
302 | CaseExpr Expr Row Col
303 | CaseBranch Expr Row Col
305 | CaseIndentOf Row Col
306 | CaseIndentExpr Row Col
307 | CaseIndentPattern Row Col
308 | CaseIndentArrow Row Col
309 | CaseIndentBranch Row Col
310 | CasePatternAlignment Word16 Row Col
314 = IfSpace Space Row Col
317 | IfElseBranchStart Row Col
319 | IfCondition Expr Row Col
320 | IfThenBranch Expr Row Col
321 | IfElseBranch Expr Row Col
323 | IfIndentCondition Row Col
324 | IfIndentThen Row Col
325 | IfIndentThenBranch Row Col
326 | IfIndentElseBranch Row Col
327 | IfIndentElse Row Col
331 = LetSpace Space Row Col
333 | LetDefAlignment Word16 Row Col
335 | LetDef Name.Name Def Row Col
336 | LetDestruct Destruct Row Col
337 | LetBody Expr Row Col
338 | LetIndentDef Row Col
339 | LetIndentIn Row Col
340 | LetIndentBody Row Col
344 = DefSpace Space Row Col
345 | DefType Type Row Col
346 | DefNameRepeat Name.Name Row Col
347 | DefNameMatch Name.Name Name.Name Row Col
348 | DefArg Pattern Row Col
350 | DefBody Expr Row Col
351 | DefIndentEquals Row Col
352 | DefIndentType Row Col
353 | DefIndentBody Row Col
354 | DefAlignment Word16 Row Col
358 = DestructSpace Space Row Col
359 | DestructPattern Pattern Row Col
360 | DestructEquals Row Col
361 | DestructBody Expr Row Col
362 | DestructIndentEquals Row Col
363 | DestructIndentBody Row Col
371 = PRecord PRecord Row Col
372 | PTuple PTuple Row Col
373 | PList PList Row Col
377 | PString String Row Col
378 | PNumber Number Row Col
381 | PWildcardNotVar Int Row Col
382 | PSpace Space Row Col
384 | PIndentStart Row Col
385 | PIndentAlias Row Col
389 = PRecordOpen Row Col
391 | PRecordField Row Col
392 | PRecordSpace Space Row Col
394 | PRecordIndentOpen Row Col
395 | PRecordIndentEnd Row Col
396 | PRecordIndentField Row Col
402 | PTupleExpr Pattern Row Col
403 | PTupleSpace Space Row Col
405 | PTupleIndentOpen Row Col
406 | PTupleIndentEnd Row Col
407 | PTupleIndentExpr Row Col
413 | PListExpr Pattern Row Col
414 | PListSpace Space Row Col
416 | PListIndentOpen Row Col
417 | PListIndentEnd Row Col
418 | PListIndentExpr Row Col
426 = TRecord TRecord Row Col
427 | TTuple TTuple Row Col
432 | TSpace Space Row Col
434 | TIndentStart Row Col
438 = TRecordOpen Row Col
441 | TRecordField Row Col
442 | TRecordColon Row Col
443 | TRecordType Type Row Col
445 | TRecordSpace Space Row Col
447 | TRecordIndentOpen Row Col
448 | TRecordIndentField Row Col
449 | TRecordIndentColon Row Col
450 | TRecordIndentType Row Col
451 | TRecordIndentEnd Row Col
457 | TTupleType Type Row Col
458 | TTupleSpace Space Row Col
460 | TTupleIndentOpen Row Col
461 | TTupleIndentType Row Col
462 | TTupleIndentEnd Row Col
476 = StringEndless_Single
477 | StringEndless_Multi
478 | StringEscape Escape
482 = EscapeUnknown Word16 Word16
483 | BadUnicodeFormat Word16 Word16
484 | BadUnicodeCode Word16 Word16
485 | BadUnicodeLength Word16 Word16 Int Int
492 | NumberNoLeadingZero
501 | EndlessMultiComment
502 | UnexpectedDocComment
517toReport :: Code.Source -> Error -> Report.Report
519 error "TODO" source err
522 CommentOnNothing region ->
523 Report.Report "STRAY COMMENT" region [] $
524 Report.toCodeSnippet source region Nothing
526 "This documentation comment is not followed by anything."
529 "All documentation comments need to be right above the declaration they\
530 \ describe. Maybe some code got deleted or commented out by accident? Or\
531 \ maybe this comment is here by accident?"
534 UnexpectedPort region ->
535 Report.Report "UNEXPECTED PORTS" region [] $
536 Report.toCodeSnippet source region Nothing
539 "You are declaring ports in a normal module."
543 ["Switch","this","to","say",D.green "port module","instead,"
544 ,"marking","that","this","module","contains","port","declarations."
547 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
549 "to learn the syntax and how to use it effectively."
554 Report.Report "NO PORTS" region [] $
555 Report.toCodeSnippet source region Nothing
558 "This module does not declare any ports, but it says it will:"
561 ["Switch","this","to",D.green "module"
562 ,"and","you","should","be","all","set!"
566 ParseError row col context expectation ->
568 pos = A.Position row col
569 region = A.Region pos pos
573 error "TODO no parse error yet"
576 error "TODO no parse error yet"
581 Report.Report "NO TABS" region [] $
582 Report.toCodeSnippet source region Nothing
585 "I ran into a tab, but tabs are not allowed in Elm files."
588 "Replace the tab with spaces."
592 Report.Report "EXPECTING DOC COMMENT" region [] $
593 Report.toCodeSnippet source region Nothing
596 "I was expecting a doc comment here:"
599 "Check out" "TODO" "for examples of doc comments."
602 MultiCommentEnd startRow startCol ->
606 (A.Position startRow startCol)
607 (A.Position startRow (startCol + 3))
609 Report.Report "ENDLESS COMMENT" startRegion [] $
610 Report.toCodeSnippet source startRegion Nothing
613 "I cannot find the end of this multi-line comment:"
616 [ D.reflow "Add a -} somewhere after this to end the comment."
618 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
619 \ that happens to contain another comment. Like parentheses and curly braces,\
620 \ the start and end markers must always be balanced. Maybe that is the problem?"
627 Report.Report "EXPECTING NUMBER" region [] $
628 Report.toCodeSnippet source region Nothing
631 "I was expecting to see a number here:"
635 "I recognize numbers in the following formats:"
636 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
638 "So is there a way to write it like one of those?"
643 Report.Report "WEIRD NUMBER" region [] $
644 Report.toCodeSnippet source region Nothing
647 "I thought I was reading a number, but I ran into some weird stuff here:"
651 "I recognize numbers in the following formats:"
652 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
654 "So is there a way to write it like one of those?"
659 Report.Report "WEIRD NUMBER" region [] $
660 Report.toCodeSnippet source region Nothing
663 "Numbers cannot end with a dot like this:"
666 ["Switching","to",D.green (D.fromChars (show int))
667 ,"or",D.green (D.fromChars (show int ++ ".0"))
668 ,"will","work","though!"
673 Report.Report "WEIRD HEXIDECIMAL" region [] $
674 Report.toCodeSnippet source region Nothing
677 "I thought I was reading a hexidecimal number until I got here:"
681 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
682 \ only recognize things like this:"
683 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
687 Number_NoLeadingZero ->
688 Report.Report "LEADING ZEROS" region [] $
689 Report.toCodeSnippet source region Nothing
692 "I do not accept numbers with leading zeros:"
696 "Just delete the leading zeros and it should work!"
698 "Some languages let you to specify octal numbers by adding a leading zero.\
699 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
700 \ that, but others probably want it to equal 111. Either path is going to\
701 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
707 Report.Report "EXPECTING PRECEDENCE" region [] $
708 Report.toCodeSnippet source region Nothing
711 "I was expecting the precedence here:"
714 "I need a single digit between 0 and 9 inclusive."
720 Report.Report "EXPECTING A CHARACTER" region [] $
721 Report.toCodeSnippet source region Nothing
724 "I was expecting a character here:"
728 "Characters start and end with single quotes, like this:"
729 , D.indent 4 $ D.vcat $
737 "That last style lets you encode characters by their unicode\
738 \ code point, so 'a' is equivalent to '\\u{0061}', 'ø' is\
739 \ equivalent to '\\u{00F8}', and so on for all code points."
744 Report.Report "MISSING SINGLE QUOTE" region [] $
745 Report.toCodeSnippet source region Nothing
748 "I thought I was parsing a character, but I got to the end of\
749 \ the line without seeing the closing single quote:"
753 "Characters start and end with single quotes, like this:"
754 , D.indent 4 $ D.vcat $
762 "That last style lets you encode characters by their unicode\
763 \ code point, so 'a' is equivalent to '\\u{0061}', 'ø' is\
764 \ equivalent to '\\u{00F8}', and so on for all code points."
768 CharNotString startRow startCol ->
771 A.Region (A.Position startRow startCol) pos
773 Report.Report "NEEDS DOUBLE QUOTES" stringRegion [] $
774 Report.toCodeSnippet source stringRegion Nothing
776 "The following string uses single quotes:"
779 [ "Please switch to double quotes instead:"
781 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
783 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
784 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
785 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
786 \ individual characters."
791 Report.Report "EXPECTING A STRING" region [] $
792 Report.toCodeSnippet source region Nothing
795 "I was expecting a string here:"
802 ,"with","double","quotes."
807 Report.Report "ENDLESS STRING" region [] $
808 Report.toCodeSnippet source region Nothing
811 "I got to the end of the line without seeing the closing double quote:"
815 ["Strings","look","like",D.green "\"this\"","with","double"
816 ,"quotes","on","each","end.","Is","the","closing","double"
817 ,"quote","missing","in","your","code?"
819 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
823 StringEnd_Multi startRow startCol ->
827 (A.Position startRow startCol)
828 (A.Position startRow (startCol + 3))
830 Report.Report "ENDLESS STRING" startRegion [] $
831 Report.toCodeSnippet source startRegion Nothing
834 "I cannot find the end of this multi-line string:"
837 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
838 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
842 EscapeUnknown startCol endCol ->
845 A.Region (A.Position row startCol) (A.Position row endCol)
847 Report.Report "UNKNOWN ESCAPE" escapeRegion [] $
848 Report.toCodeSnippet source escapeRegion Nothing
851 "Backslashes always start escaped characters, but I do not recognize this one:"
855 "Valid escape characters include:"
856 , D.indent 4 $ D.vcat $
866 "The last one lets encode ANY character by its Unicode code\
867 \ point, so use that for anything outside the ordinary six."
871 BadUnicodeFormat startCol endCol ->
874 A.Region (A.Position row startCol) (A.Position row endCol)
876 Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
877 Report.toCodeSnippet source escapeRegion Nothing
880 "I ran into an invalid Unicode escape:"
884 "Here are some examples of valid Unicode escapes:"
885 , D.green $ D.indent 4 $ D.vcat $
892 "Notice that the code point is always surrounded by curly\
893 \ braces. They are required!"
897 BadUnicodeCode startCol endCol ->
900 A.Region (A.Position row startCol) (A.Position row endCol)
902 Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
903 Report.toCodeSnippet source escapeRegion Nothing
906 "This is not a valid code point:"
909 "The valid code points are between 0 and 10FFFF inclusive."
912 BadUnicodeLength startCol endCol numDigits badCode ->
915 A.Region (A.Position row startCol) (A.Position row endCol)
917 Report.Report "BAD UNICODE ESCAPE" escapeRegion [] $
918 Report.toCodeSnippet source escapeRegion Nothing $
919 if numDigits < 4 then
922 "Every code point needs at least four digits:"
925 goodCode = replicate (4 - numDigits) '0' ++ showHex badCode ""
926 escape = "\\u{" <> D.fromChars goodCode <> "}"
928 D.fillSep ["Try",D.green escape,"instead?"]
934 "This code point has too many digits:"
937 ["Valid","code","points","are","between"
938 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
939 ,"so","try","trimming","any","leading","zeros","until"
940 ,"you","have","between","four","and","six","digits."
947 Report.Report "EXPECTING A SHADER" region [] $
948 Report.toCodeSnippet source region Nothing $
951 "I was expecting a GLSL shader block here:"
954 "These blocks start with [glsl| and end with |] and should be\
955 \ filled with GLSL code."
958 ShaderEnd startCol endCol ->
961 A.Region (A.Position row startCol) (A.Position row endCol)
963 Report.Report "ENDLESS SHADER" shaderRegion [] $
964 Report.toCodeSnippet source shaderRegion Nothing
966 D.reflow "I cannot find the end of this shader:"
968 D.reflow "Add a |] somewhere after this to end the shader."
971 ShaderProblem problem ->
972 Report.Report "SHADER PROBLEM" region [] $
973 Report.toCodeSnippet source region Nothing
976 "I ran into a problem while parsing this GLSL block."
982 Report.Report "EXPECTING AN OPERATOR" region [] $
983 Report.toCodeSnippet source region Nothing
986 "I was expecting an operator here:"
989 [ D.reflow "Some of the most common operators are:"
990 , D.indent 4 $ D.vcat ["+","-","*","&&","||"]
991 , D.reflow "Something like that!"
995 ReservedOperator op ->
996 error "TODO ReservedOperator" op
999 Report.Report "EXPECTING A WILDCARD" region [] $
1000 Report.toCodeSnippet source region Nothing
1003 "I was expecting a _ here:"
1006 "An underscore indicates that “I do not care about this value” and is\
1007 \ called a wildcard pattern because it will match with any type of values."
1010 WildcardNotVar startCol endCol ->
1013 A.Region (A.Position row startCol) (A.Position row endCol)
1015 Report.Report "INVALID PATTERN" badRegion [] $
1016 Report.toCodeSnippet source badRegion Nothing
1019 "I was expecting to see an underscore without any additional characters:"
1022 "There are two options. Either (1) remove the extra characters and ignore the\
1023 \ value or (2) remove the starting underscore to give the value a normal name."
1029 error "TODO" context
1037 Report.Report "INVALID PATTERN" region [] $
1038 Report.toCodeSnippet source region Nothing
1041 "I cannot pattern match with floating point numbers:"
1044 "Equality on floats can be unreliable, so you usually want to check that they\
1045 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
1049 Report.Report "EXPECTING A FIELD NAME" region [] $
1050 Report.toCodeSnippet source region Nothing
1053 "I was expecting a field name here:"
1056 ["A","name","like",D.dullyellow "id" <> ",",D.dullyellow "status" <> ","
1057 ,"or","whatever","field","you","want","to","access."
1063 MatchingName name ->
1064 Report.Report "EXPECTING A DEFINITION" region [] $
1065 Report.toCodeSnippet source region Nothing
1068 "I just saw the type annotation for `" ++ Name.toChars name
1069 ++ "` so I was expecting to see its definition here:"
1072 "Type annotations always appear directly above the relevant\
1073 \ definition, without anything else (even doc comments) in between."
1079 Report.Report "EXPECTING END OF FILE" region [] $
1080 Report.toCodeSnippet source region Nothing
1083 "I was not expecting to see anything more here:"
1086 "I think I have read all the declarations in the file and that there is nothing\
1087 \ left to see, so whatever I am running into is confusing me a lot!"
1093 TypeWithBadDefinition region annName defName ->
1094 Report.Report "ANNOTATION MISMATCH" region [] $
1095 Report.toCodeSnippet source region Nothing
1098 "I see a `" <> Name.toChars annName
1099 <> "` annotation, but it is followed by a `"
1100 <> Name.toChars defName <> "` definition."
1103 ["The","annotation","and","definition","names","must","match!"
1104 ,"Is","there","a","typo","between"
1105 , D.dullyellow (D.fromName annName)
1107 , D.dullyellow (D.fromName defName) <> "?"
1112-- PARSE ERROR TO DOCS
1115problemToDocs :: Problem -> (D.Doc, D.Doc)
1116problemToDocs problem =
1120 "I ran into a tab, but tabs are not allowed in Elm files."
1122 "Replace the tab with spaces."
1125 EndOfFile_Comment ->
1127 "I got to the end of the file while parsing a multi-line comment."
1130 "Multi-line comments look like {- comment -}, and it looks like\
1131 \ you are missing the closing marker."
1134 "Nested multi-line comments like {- this {- and this -} -} are allowed.\
1135 \ The opening and closing markers must be balanced though, just\
1136 \ like parentheses in normal code. Maybe that is the problem?"
1142 "I got to the end of the file while parsing a string."
1144 "Strings look like \"this\" with double quotes on each end.\
1145 \ Is the closing double quote missing in your code?"
1148 EndOfFile_MultiString ->
1150 "I got to the end of the file while parsing a multi-line string."
1152 "Multi-line strings look like \"\"\"this\"\"\" with three double quotes\
1153 \ on each end. Is the closing triple quote missing in your code?"
1158 "I got to the end of the file while parsing a character."
1160 "Characters look like 'c' with single quotes on each end.\
1161 \ Is the closing single quote missing in your code?"
1166 "This string is missing the closing quote."
1169 "Elm strings like \"this\" cannot contain newlines."
1172 "For strings that CAN contain newlines, say \"\"\"this\"\"\" for Elm’s\
1173 \ multi-line string syntax. It allows unescaped newlines and double quotes."
1179 "This character is missing the closing quote."
1181 "Elm characters must start and end with a single quote. Valid examples\n\
1182 \ include 'a', 'b', '\n', 'ø', and '\\u{00F8}' for unicode code points."
1185 BadNumberDot numberBeforeDot ->
1187 "Numbers cannot end with a decimal points."
1191 D.fromString (show numberBeforeDot)
1193 "Saying " <> D.green number <> " or " <> D.green (number <> ".0") <> " will work though!"
1198 "Numbers cannot have letters or underscores in them."
1200 "Maybe a space is missing between a number and a variable?"
1205 "If you put the letter E in a number, it should followed by more digits."
1207 "If you want to say 1000, you can also say 1e3.\
1208 \ You cannot just end it with an E though!"
1213 "I see the start of a hex number, but not the end."
1215 "A hex number looks like 0x123ABC, where the 0x is followed by hexidecimal\
1216 \ digits. Valid hexidecimal digits include: 0123456789abcdefABCDEF"
1221 "Normal numbers cannot start with zeros. Take the zeros off the front."
1223 "Only numbers like 0x0040 or 0.25 can start with a zero."
1228 "Variable names cannot start with an underscore like this:"
1230 "Delete the underscore and it shoulld be fine!"
1236 badOp stack "A" "\"has type\" operator"
1237 "type annotations and record types"
1238 "Maybe you want :: instead? Or maybe something is indented too much?"
1242 "I was not expecting this equals sign"
1243 <> contextToString " here" " while parsing " stack <> "."
1245 toBadEqualsHint stack
1249 if isCaseRelated stack then
1251 "I ran into a stray arrow while parsing this `case` expression."
1254 "All branches in a `case` must be indented the exact\
1255 \ same amount, so the patterns are vertically\
1256 \ aligned. Maybe this branch is indented too much?"
1260 badOp stack "An" "arrow"
1261 "cases expressions and anonymous functions"
1262 "Maybe you want > or >= instead?"
1265 badOp stack "A" "vertical bar"
1267 "Maybe you want || instead?"
1271 "I was not expecting this dot."
1274 "Dots are for record access and decimal points, so\
1275 \ they cannot float around on their own. Maybe\
1276 \ there is some extra whitespace?"
1279 Theories stack allTheories ->
1282 "Something went wrong while parsing " <> contextToString "your code" "" stack <> "."
1284 case Set.toList (Set.fromList allTheories) of
1288 "I do not have any suggestions though!"
1290 "Can you get it down to a <http://sscce.org> and share it at\
1291 \ <https://github.com/elm/error-message-catalog/issues>?\
1292 \ That way we can figure out how to give better advice!"
1297 "I was expecting to see "
1298 <> addPeriod (theoryToString stack theory)
1302 [ "I was expecting:"
1305 ++ map (bullet . theoryToString stack) theories
1313badOp :: ContextStack -> String -> String -> String -> String -> ( D.Doc, D.Doc )
1314badOp stack article opName setting hint =
1317 "I was not expecting this " <> opName
1318 <> contextToString " here" " while parsing " stack <> "."
1321 article <> " " <> opName <> " should only appear in "
1322 <> setting <> ". " <> hint
1326toBadEqualsHint :: ContextStack -> D.Doc
1327toBadEqualsHint stack =
1331 "Maybe you want == instead? Or maybe something is indented too much?"
1333 (ExprRecord, _) : _ ->
1335 "Records look like { x = 3, y = 4 } with the equals sign right\
1336 \ after the field name. Maybe you forgot a comma?"
1338 (Definition _, _) : rest ->
1340 "Maybe this is supposed to be a separate definition? If so, it\
1341 \ is indented too far. "
1343 if any ((==) ExprLet . fst) rest then
1344 "All definitions in a `let` expression must be vertically aligned."
1346 "Spaces are not allowed before top-level definitions."
1349 toBadEqualsHint rest
1353isCaseRelated :: ContextStack -> Bool
1354isCaseRelated stack =
1359 (context, _) : rest ->
1360 context == ExprCase || isCaseRelated rest
1367contextToString :: String -> String -> ContextStack -> String
1368contextToString defaultString prefixString stack =
1373 (context, _) : rest ->
1374 let anchor = getAnchor rest in
1377 ExprIf -> "an `if` expression" <> anchor
1378 ExprLet -> "a `let` expression" <> anchor
1379 ExprFunc -> "an anonymous function" <> anchor
1380 ExprCase -> "a `case` expression" <> anchor
1381 ExprList -> "a list" <> anchor
1382 ExprTuple -> "an expression (in parentheses)" <> anchor
1383 ExprRecord -> "a record" <> anchor
1384 Definition name -> Name.toChars name <> "'s definition"
1385 Annotation name -> Name.toChars name <> "'s type annotation"
1386 TypeTuple -> "a type (in parentheses)" <> anchor
1387 TypeRecord -> "a record type" <> anchor
1388 PatternList -> "a list pattern" <> anchor
1389 PatternTuple -> "a pattern (in parentheses)" <> anchor
1390 PatternRecord -> "a record pattern" <> anchor
1391 Module -> "a module declaration"
1392 Import -> "an import"
1393 TypeUnion -> "a union type"
1394 TypeAlias -> "a type alias"
1395 Infix -> "an infix declaration"
1396 Port -> "a port declaration"
1399getAnchor :: ContextStack -> String
1405 (context, _) : rest ->
1408 " in " <> Name.toChars name <> "'s definition"
1411 " in " <> Name.toChars name <> "'s type annotation"
1421bullet :: String -> D.Doc
1423 D.hang 4 (" - " <> D.fillSep (map D.fromString (words point)))
1426addPeriod :: String -> String
1428 if last msg `elem` ['`', ')', '.', '!', '?'] then
1434theoryToString :: ContextStack -> Theory -> String
1435theoryToString context theory =
1438 "the `" <> keyword <> "` keyword"
1442 "=" -> equalsTheory context
1443 "->" -> "an arrow (->) followed by an expression"
1444 ":" -> "the \"has type\" symbol (:) followed by a type"
1446 "|" -> barTheory context
1447 "::" -> "the cons operator (::) followed by more list elements"
1449 "-" -> "a minus sign (-)"
1450 "_" -> "an underscore"
1451 "(" -> "a left paren, for grouping or starting tuples"
1452 ")" -> "a closing paren"
1453 "[" -> "a left square bracket, for starting lists"
1454 "]" -> "a right square bracket, to end a list"
1455 "{" -> "a left curly brace, for starting records"
1456 "}" -> "a right curly brace, to end a record"
1457 "{-|" -> "a doc comment, like {-| this -}" --}
1458 _ -> "the (" <> symbol <> ") symbol"
1461 "a lower-case variable, like `x` or `user`"
1464 "an upper-case variable, like `Maybe` or `Just`"
1467 "an infix operator, like (+) or (==)"
1470 "a digit from 0 to 9"
1477 Decl -> "a declaration, like `x = 5` or `type alias Model = { ... }`"
1478 Expr -> "an expression, like x or 42"
1479 AfterOpExpr op -> "an expression after that (" <> Name.toChars op <> ") operator, like x or 42"
1480 ElseBranch -> "an `else` branch. An `if` must handle both possibilities."
1481 Arg -> "an argument, like `name` or `total`"
1482 Pattern -> "a pattern, like `name` or (Just x)"
1483 Type -> "a type, like Int or (List String)"
1484 Listing -> "a list of exposed values and types, like (..) or (x,y,z)"
1485 Exposing -> "something like `exposing (..)`"
1488equalsTheory :: ContextStack -> String
1492 "an equals sign (=)"
1494 (context, _) : rest ->
1496 ExprRecord -> "an equals sign (=) followed by an expression"
1497 Definition name -> "an equals sign (=) followed by " <> Name.toChars name <> "'s definition"
1498 TypeUnion -> "an equals sign (=) followed by the first union type constructor"
1499 TypeAlias -> "an equals sign (=) followed by the aliased type"
1500 _ -> equalsTheory rest
1503barTheory :: ContextStack -> String
1507 "a vertical bar (|)"
1509 (context, _) : rest ->
1511 ExprRecord -> "a vertical bar (|) followed by the record fields you want to update"
1512 TypeRecord -> "a vertical bar (|) followed by some record field types"
1513 TypeUnion -> "a vertical bar (|) followed by more union type constructors"
1517badSpace :: ContextStack -> String
1521 "more indentation? I was not done with that last thing yet."
1523 (context, _) : rest ->
1525 ExprIf -> "the end of that `if`" <> badSpaceExprEnd rest
1526 ExprLet -> "the end of that `let`" <> badSpaceExprEnd rest
1527 ExprFunc -> badSpace rest
1528 ExprCase -> "more of that `case`" <> badSpaceExprEnd rest
1529 ExprList -> "the end of that list" <> badSpaceExprEnd rest
1530 ExprTuple -> "a closing paren" <> badSpaceExprEnd rest
1531 ExprRecord -> "the end of that record" <> badSpaceExprEnd rest
1532 Definition name -> "the rest of " <> Name.toChars name <> "'s definition" <> badSpaceExprEnd stack
1533 Annotation name -> "the rest of " <> Name.toChars name <> "'s type annotation" <> badSpaceEnd
1534 TypeTuple -> "a closing paren" <> badSpaceEnd
1535 TypeRecord -> "the end of that record" <> badSpaceEnd
1536 PatternList -> "the end of that list" <> badSpaceEnd
1537 PatternTuple -> "a closing paren" <> badSpaceEnd
1538 PatternRecord -> "the end of that record" <> badSpaceEnd
1539 Module -> "something like `module Main exposing (..)`"
1540 Import -> "something like `import Html exposing (..)`"
1541 TypeUnion -> "more of that union type" <> badSpaceEnd
1542 TypeAlias -> "more of that type alias" <> badSpaceEnd
1543 Infix -> "more of that infix declaration" <> badSpaceEnd
1544 Port -> "more of that port declaration" <> badSpaceEnd
1547badSpaceEnd :: String
1549 ". Maybe you forgot some code? Or you need more indentation?"
1552badSpaceExprEnd :: ContextStack -> String
1553badSpaceExprEnd stack =
1558 (Definition name, A.Position _ column) : _ ->
1564 "more indentation? (Try " <> show (column + 1) <> "+ spaces.)"
1566 ". Maybe you forgot some code? Or maybe the body of `"
1567 <> Name.toChars name
1568 <> "` needs " <> ending
1571 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