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)
52import Numeric (showHex)
54import qualified Elm.ModuleName as ModuleName
55import Parse.Primitives (Row, Col)
56import qualified Reporting.Annotation as A
57import qualified Reporting.Doc as D
58import qualified Reporting.Report as Report
59import qualified Reporting.Render.Code as Code
67 = ModuleNameUnspecified ModuleName.Raw
68 | ModuleNameMismatch ModuleName.Raw (A.Located ModuleName.Raw)
69 | UnexpectedPort A.Region
79 = ModuleSpace Space Row Col
80 | ModuleEndOfFile Row Col
83 | ModuleExposing Row Col
84 | ModuleExposingList Exposing Row Col
86 | ModulePortModule Row Col
87 | ModuleEffect Row Col
89 | ModuleIndentStart Row Col
90 | ModuleIndentName Row Col
91 | ModuleIndentExposing Row Col
92 | ModuleIndentExposingList Row Col
93 | ModuleIndentPortModule Row Col
95 | FreshLineModuleStart Row Col
96 | FreshLineAfterModuleLine Row Col
97 | FreshLineAfterDocComment Row Col
102 | ImportAlias Row Col
103 | ImportExposing Row Col
104 | ImportExposingList Exposing Row Col
105 | ImportEnd Row Col -- different based on col=1 or if greater
107 | ImportIndentName Row Col
108 | ImportIndentAs Row Col
109 | ImportIndentAlias Row Col
110 | ImportIndentExposing Row Col
111 | ImportIndentExposingList Row Col
115 | Declarations Decl Row Col
119 = ExposingSpace Space Row Col
120 | ExposingStart Row Col
121 | ExposingValue Row Col
122 | ExposingOperator Row Col
123 | ExposingOperatorReserved Operator Row Col
124 | ExposingOperatorRightParen Row Col
125 | ExposingEnd Row Col
127 | ExposingTypePrivacy Row Col
128 | ExposingTypePrivacyDots Row Col
129 | ExposingTypePrivacyEnd Row Col
131 | ExposingIndentEnd Row Col
132 | ExposingIndentValue Row Col
133 | ExposingIndentValueEnd Row Col
134 | ExposingIndentTypePrivacy Row Col
135 | ExposingIndentTypePrivacyDots Row Col
136 | ExposingIndentTypePrivacyEnd Row Col
145 | DeclSpace Space Row Col
148 | DeclType DeclType Row Col
149 | DeclDef Name.Name DeclDef Row Col
151 | DeclFreshLineStart Row Col
152 | DeclFreshLineAfterDocComment Row Col
156 = DeclDefSpace Space Row Col
157 | DeclDefEquals Row Col
158 | DeclDefType Type Row Col
159 | DeclDefArg Pattern Row Col
160 | DeclDefBody Expr Row Col
161 | DeclDefNameRepeat Row Col
162 | DeclDefNameMatch Name.Name Row Col
164 | DeclDefIndentType Row Col
165 | DeclDefIndentEquals Row Col
166 | DeclDefIndentBody Row Col
168 | DeclDefFreshLineAfterType Row Col
172 = PortSpace Space Row Col
175 | PortType Type Row Col
176 | PortIndentName Row Col
177 | PortIndentColon Row Col
178 | PortIndentType Row Col
186 = DT_Space Space Row Col
188 | DT_Alias TypeAlias Row Col
189 | DT_Union CustomType Row Col
191 | DT_IndentName Row Col
195 = AliasSpace Space Row Col
197 | AliasEquals Row Col
198 | AliasBody Type Row Col
200 | AliasIndentEquals Row Col
201 | AliasIndentBody Row Col
205 = CT_Space Space Row Col
210 | CT_VariantArg Type Row Col
212 | CT_IndentEquals Row Col
213 | CT_IndentBar Row Col
214 | CT_IndentAfterBar Row Col
215 | CT_IndentAfterEquals Row Col
227 | Record Record Row Col
228 | Update Expr Row Col
229 | Tuple Tuple Row Col
234 | OperatorRHS Row Col
235 | OperatorRight Row Col
236 | OperatorReserved Operator Row Col
240 | String String Row Col
241 | Number Number Row Col
242 | Space Space Row Col
243 | EndlessShader Row Col
244 | ShaderProblem [Char.Char] Row Col
245 | IndentOperatorRight Row Col
246 | IndentMoreExpr Row Col
252 | RecordField Row Col
253 | RecordEquals Row Col
254 | RecordExpr Expr Row Col
255 | RecordSpace Space Row Col
257 | RecordIndentOpen Row Col
258 | RecordIndentEnd Row Col
259 | RecordIndentField Row Col
260 | RecordIndentEquals Row Col
261 | RecordIndentExpr Row Col
266 | TupleExpr Expr Row Col
267 | TupleSpace Space Row Col
269 | TupleOperatorClose Row Col
270 | TupleOperatorReserved Operator Row Col
272 | TupleIndentExpr Row Col
273 | TupleIndentEnd Row Col
277 = ListSpace Space Row Col
279 | ListExpr Expr Row Col
282 | ListIndentOpen Row Col
283 | ListIndentEnd Row Col
284 | ListIndentExpr Row Col
288 = FuncSpace Space Row Col
289 | FuncArg Pattern Row Col
290 | FuncBody Expr Row Col
293 | FuncIndentArg Row Col
294 | FuncIndentArrow Row Col
295 | FuncIndentBody Row Col
299 = CaseSpace Space Row Col
301 | CasePattern Pattern Row Col
303 | CaseExpr Expr Row Col
304 | CaseBranch Expr Row Col
306 | CaseIndentOf Row Col
307 | CaseIndentExpr Row Col
308 | CaseIndentPattern Row Col
309 | CaseIndentArrow Row Col
310 | CaseIndentBranch Row Col
311 | CasePatternAlignment Word16 Row Col
315 = IfSpace Space Row Col
318 | IfElseBranchStart Row Col
320 | IfCondition Expr Row Col
321 | IfThenBranch Expr Row Col
322 | IfElseBranch Expr Row Col
324 | IfIndentCondition Row Col
325 | IfIndentThen Row Col
326 | IfIndentThenBranch Row Col
327 | IfIndentElseBranch Row Col
328 | IfIndentElse Row Col
332 = LetSpace Space Row Col
334 | LetDefAlignment Word16 Row Col
336 | LetDef Name.Name Def Row Col
337 | LetDestruct Destruct Row Col
338 | LetBody Expr Row Col
339 | LetIndentDef Row Col
340 | LetIndentIn Row Col
341 | LetIndentBody Row Col
345 = DefSpace Space Row Col
346 | DefType Type Row Col
347 | DefNameRepeat Name.Name Row Col
348 | DefNameMatch Name.Name Name.Name Row Col
349 | DefArg Pattern Row Col
351 | DefBody Expr Row Col
352 | DefIndentEquals Row Col
353 | DefIndentType Row Col
354 | DefIndentBody Row Col
355 | DefAlignment Word16 Row Col
359 = DestructSpace Space Row Col
360 | DestructPattern Pattern Row Col
361 | DestructEquals Row Col
362 | DestructBody Expr Row Col
363 | DestructIndentEquals Row Col
364 | DestructIndentBody Row Col
372 = PRecord PRecord Row Col
373 | PTuple PTuple Row Col
374 | PList PList Row Col
378 | PString String Row Col
379 | PNumber Number Row Col
382 | PWildcardNotVar Int Row Col
383 | PSpace Space Row Col
385 | PIndentStart Row Col
386 | PIndentAlias Row Col
390 = PRecordOpen Row Col
392 | PRecordField Row Col
393 | PRecordSpace Space Row Col
395 | PRecordIndentOpen Row Col
396 | PRecordIndentEnd Row Col
397 | PRecordIndentField Row Col
403 | PTupleExpr Pattern Row Col
404 | PTupleSpace Space Row Col
406 | PTupleIndentOpen Row Col
407 | PTupleIndentEnd Row Col
408 | PTupleIndentExpr Row Col
414 | PListExpr Pattern Row Col
415 | PListSpace Space Row Col
417 | PListIndentOpen Row Col
418 | PListIndentEnd Row Col
419 | PListIndentExpr Row Col
427 = TRecord TRecord Row Col
428 | TTuple TTuple Row Col
433 | TSpace Space Row Col
435 | TIndentStart Row Col
439 = TRecordOpen Row Col
442 | TRecordField Row Col
443 | TRecordColon Row Col
444 | TRecordType Type Row Col
446 | TRecordSpace Space Row Col
448 | TRecordIndentOpen Row Col
449 | TRecordIndentField Row Col
450 | TRecordIndentColon Row Col
451 | TRecordIndentType Row Col
452 | TRecordIndentEnd Row Col
458 | TTupleType Type Row Col
459 | TTupleSpace Space Row Col
461 | TTupleIndentOpen Row Col
462 | TTupleIndentType Row Col
463 | TTupleIndentEnd Row Col
473 | CharNotString Word16
477 = StringEndless_Single
478 | StringEndless_Multi
479 | StringEscape Escape
484 | BadUnicodeFormat Word16
485 | BadUnicodeCode Word16
486 | BadUnicodeLength Word16 Int Int
493 | NumberNoLeadingZero
502 | EndlessMultiComment
517toReport :: Code.Source -> Error -> Report.Report
520 ModuleNameUnspecified name ->
522 region = toRegion 1 1
524 Report.Report "MODULE NAME MISSING" region [] $
527 "I need the module name to be declared at the top of this file, like this:"
528 , D.indent 4 $ D.green $ D.fromChars $
529 "module " ++ ModuleName.toChars name ++ " exposing (..)"
531 "Try adding that as the first line of your file!"
533 "It is best to replace (..) with an explicit list of types and\
534 \ functions you want to expose. When you know a value is only used\
535 \ within this module, you can refactor without worrying about uses\
536 \ elsewhere. Limiting exposed values can also speed up compilation\
537 \ because I can skip a bunch of work if I see that the exposed API\
541 ModuleNameMismatch expectedName (A.At region actualName) ->
542 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
543 Report.toCodeSnippet source region Nothing
545 "It looks like this module name is out of sync:"
549 "I need it to match the file path, so I was expecting it to see `"
550 ++ ModuleName.toChars expectedName
551 ++ "` here. Make the following change, and you should be all set!"
553 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
555 "I require that module names correspond to file paths. This makes it much\
556 \ easier to explore unfamiliar codebases! So if you want to keep the current\
557 \ module name, try renaming the file instead."
561 UnexpectedPort region ->
562 error "TODO UnexpectedPort" region
565 error "TODO NoPorts" region
568 toParseErrorReport source modul
571toParseErrorReport :: Code.Source -> Module -> Report.Report
572toParseErrorReport source modul =
574 ModuleSpace space row col ->
575 toSpaceReport source space row col
577 ModuleEndOfFile row col ->
579 region = toRegion row col
581 Report.Report "EXPECTING END OF FILE" region [] $
582 Report.toCodeSnippet source region Nothing
585 "I was not expecting to see anything more here:"
588 "I think I have read all the declarations in the file and that there is nothing\
589 \ left to see, so whatever I am running into is confusing me a lot!"
593 error "TODO Module" row col
595 ModuleName row col ->
596 error "TODO ModuleName" row col
598 ModuleExposing row col ->
599 error "TODO ModuleExposing" row col
601 ModuleExposingList exposing row col ->
602 error "TODO ModuleExposingList" exposing row col
605 ModulePortModule row col ->
606 error "TODO ModulePortModule" row col
608 ModuleEffect row col ->
609 error "TODO ModuleEffect" row col
611 ModuleIndentStart row col ->
612 error "TODO ModuleIndentStart" row col
614 ModuleIndentName row col ->
615 error "TODO ModuleIndentName" row col
617 ModuleIndentExposing row col ->
618 error "TODO ModuleIndentExposing" row col
620 ModuleIndentExposingList row col ->
621 error "TODO ModuleIndentExposingList" row col
623 ModuleIndentPortModule row col ->
624 error "TODO ModuleIndentPortModule" row col
626 FreshLineModuleStart row col ->
627 error "TODO FreshLineModuleStart" row col
629 FreshLineAfterModuleLine row col ->
630 error "TODO FreshLineAfterModuleLine" row col
632 FreshLineAfterDocComment row col ->
633 error "TODO FreshLineAfterDocComment" row col
635 ImportStart row col ->
636 error "TODO ImportStart" row col
638 ImportName row col ->
639 error "TODO ImportName" row col
642 error "TODO ImportAs" row col
644 ImportAlias row col ->
645 error "TODO ImportAlias" row col
647 ImportExposing row col ->
648 error "TODO ImportExposing" row col
650 ImportExposingList exposing row col ->
651 error "TODO ImportExposingList" exposing row col
654 error "TODO ImportEnd" row col
656 ImportIndentName row col ->
657 error "TODO ImportIndentName" row col
659 ImportIndentAs row col ->
660 error "TODO ImportIndentAs" row col
662 ImportIndentAlias row col ->
663 error "TODO ImportIndentAlias" row col
665 ImportIndentExposing row col ->
666 error "TODO ImportIndentExposing" row col
668 ImportIndentExposingList row col ->
669 error "TODO ImportIndentExposingList" row col
672 error "TODO Infix" row col
674 Declarations decl _ _ ->
675 toDeclarationsReport source decl
678toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
679toSpaceReport source space row col =
683 region = toRegion row col
685 Report.Report "NO TABS" region [] $
686 Report.toCodeSnippet source region Nothing
689 "I ran into a tab, but tabs are not allowed in Elm files."
692 "Replace the tab with spaces."
695 EndlessMultiComment ->
697 region = toWiderRegion row col 2
699 Report.Report "ENDLESS COMMENT" region [] $
700 Report.toCodeSnippet source region Nothing
703 "I cannot find the end of this multi-line comment:"
706 [ D.reflow "Add a -} somewhere after this to end the comment."
708 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
709 \ that happens to contain another comment. Like parentheses and curly braces,\
710 \ the start and end markers must always be balanced. Maybe that is the problem?"
715toRegion :: Row -> Col -> A.Region
718 pos = A.Position row col
723toWiderRegion :: Row -> Col -> Word16 -> A.Region
724toWiderRegion row col extra =
727 (A.Position row (col + extra))
730toDeclarationsReport :: Code.Source -> Decl -> Report.Report
731toDeclarationsReport source decl =
734 error "TODO DeclStart" row col
736 DeclSpace space row col ->
737 toSpaceReport source space row col
740 error "TODO Port" port row col
742 DeclType declType row col ->
743 error "TODO DeclType" declType row col
745 DeclDef name declDef row col ->
746 toDeclDefReport source name declDef row col
748 DeclFreshLineStart row col ->
749 error "TODO DeclFreshLineStart" row col
751 DeclFreshLineAfterDocComment row col ->
752 error "TODO DeclFreshLineAfterDocComment" row col
755toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
756toDeclDefReport source name declDef _ _ =
758 DeclDefSpace space row col ->
759 toSpaceReport source space row col
761 DeclDefEquals row col ->
762 error "TODO DeclDefEquals" row col
764 DeclDefType tipe row col ->
765 error "TODO DeclDefType" tipe row col
767 DeclDefArg pattern row col ->
768 error "TODO DeclDefArg" pattern row col
770 DeclDefBody expr row col ->
771 toExprReport source name expr row col
773 DeclDefNameRepeat row col ->
774 error "TODO DeclDefNameRepeat" name row col
776 DeclDefNameMatch defName row col ->
777 error "TODO DeclDefNameMatch" name defName row col
779 DeclDefIndentType row col ->
780 error "TODO DeclDefIndentType" row col
782 DeclDefIndentEquals row col ->
783 error "TODO DeclDefIndentEquals" row col
785 DeclDefIndentBody row col ->
786 error "TODO DeclDefIndentBody" row col
788 DeclDefFreshLineAfterType row col ->
789 error "TODO DeclDefFreshLineAfterType" row col
793toExprReport :: Code.Source -> Name.Name -> Expr -> Row -> Col -> Report.Report
794toExprReport source _ expr _ _ =
827 error "TODO OperatorRHS"
830 error "TODO OperatorRight"
832 OperatorReserved _ _ _ ->
833 error "TODO OperatorReserved"
839 toCharReport source char row col
841 String string row col ->
842 toStringReport source string row col
844 Number number row col ->
845 toNumberReport source number row col
847 Space space row col ->
848 toSpaceReport source space row col
850 EndlessShader row col ->
852 region = toWiderRegion row col 6
854 Report.Report "ENDLESS SHADER" region [] $
855 Report.toCodeSnippet source region Nothing
857 D.reflow "I cannot find the end of this shader:"
859 D.reflow "Add a |] somewhere after this to end the shader."
862 ShaderProblem problem row col ->
864 region = toRegion row col
866 Report.Report "SHADER PROBLEM" region [] $
867 Report.toCodeSnippet source region Nothing
870 "I ran into a problem while parsing this GLSL block."
874 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
875 , D.indent 4 $ D.vcat $
876 map D.fromChars (filter (/="") (lines problem))
880 IndentOperatorRight _ _ ->
881 error "TODO IndentOperatorRight"
883 IndentMoreExpr _ _ ->
884 error "TODO IndentMoreExpr"
887toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
888toCharReport source char row col =
892 region = toRegion row col
894 Report.Report "MISSING SINGLE QUOTE" region [] $
895 Report.toCodeSnippet source region Nothing
898 "I thought I was parsing a character, but I got to the end of\
899 \ the line without seeing the closing single quote:"
902 "Add a closing single quote here!"
906 toEscapeReport source escape row col
908 CharNotString width ->
910 region = toWiderRegion row col width
912 Report.Report "NEEDS DOUBLE QUOTES" region [] $
913 Report.toCodeSnippet source region Nothing
915 "The following string uses single quotes:"
918 [ "Please switch to double quotes instead:"
920 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
922 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
923 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
924 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
925 \ individual characters."
930toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
931toStringReport source string row col =
933 StringEndless_Single ->
935 region = toRegion row col
937 Report.Report "ENDLESS STRING" region [] $
938 Report.toCodeSnippet source region Nothing
941 "I got to the end of the line without seeing the closing double quote:"
945 ["Strings","look","like",D.green "\"this\"","with","double"
946 ,"quotes","on","each","end.","Is","the","closing","double"
947 ,"quote","missing","in","your","code?"
949 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
953 StringEndless_Multi ->
955 region = toWiderRegion row col 3
957 Report.Report "ENDLESS STRING" region [] $
958 Report.toCodeSnippet source region Nothing
961 "I cannot find the end of this multi-line string:"
964 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
965 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
969 StringEscape escape ->
970 toEscapeReport source escape row col
973toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
974toEscapeReport source escape row col =
978 region = toWiderRegion row col 2
980 Report.Report "UNKNOWN ESCAPE" region [] $
981 Report.toCodeSnippet source region Nothing
984 "Backslashes always start escaped characters, but I do not recognize this one:"
988 "Valid escape characters include:"
989 , D.dullyellow $ D.indent 4 $ D.vcat $
999 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1001 "The last style lets encode ANY character by its Unicode code\
1002 \ point. That means \\u{0009} and \\t are the same. You can use\
1003 \ that style for anything not covered by the other six escapes!"
1007 BadUnicodeFormat width ->
1009 region = toWiderRegion row col width
1011 Report.Report "BAD UNICODE ESCAPE" region [] $
1012 Report.toCodeSnippet source region Nothing
1015 "I ran into an invalid Unicode escape:"
1019 "Here are some examples of valid Unicode escapes:"
1020 , D.dullyellow $ D.indent 4 $ D.vcat $
1027 "Notice that the code point is always surrounded by curly braces.\
1028 \ Maybe you are missing the opening or closing curly brace?"
1031 BadUnicodeCode width ->
1033 region = toWiderRegion row col width
1035 Report.Report "BAD UNICODE ESCAPE" region [] $
1036 Report.toCodeSnippet source region Nothing
1039 "This is not a valid code point:"
1042 "The valid code points are between 0 and 10FFFF inclusive."
1045 BadUnicodeLength width numDigits badCode ->
1047 region = toWiderRegion row col width
1049 Report.Report "BAD UNICODE ESCAPE" region [] $
1050 Report.toCodeSnippet source region Nothing $
1051 if numDigits < 4 then
1054 "Every code point needs at least four digits:"
1057 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1058 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1060 D.fillSep ["Try",D.green suggestion,"instead?"]
1066 "This code point has too many digits:"
1069 ["Valid","code","points","are","between"
1070 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1071 ,"so","try","trimming","any","leading","zeros","until"
1072 ,"you","have","between","four","and","six","digits."
1077toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1078toNumberReport source number row col =
1080 region = toRegion row col
1084 Report.Report "WEIRD NUMBER" region [] $
1085 Report.toCodeSnippet source region Nothing
1088 "I thought I was reading a number, but I ran into some weird stuff here:"
1092 "I recognize numbers in the following formats:"
1093 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1095 "So is there a way to write it like one of those?"
1100 Report.Report "WEIRD NUMBER" region [] $
1101 Report.toCodeSnippet source region Nothing
1104 "Numbers cannot end with a dot like this:"
1107 ["Switching","to",D.green (D.fromChars (show int))
1108 ,"or",D.green (D.fromChars (show int ++ ".0"))
1109 ,"will","work","though!"
1114 Report.Report "WEIRD HEXIDECIMAL" region [] $
1115 Report.toCodeSnippet source region Nothing
1118 "I thought I was reading a hexidecimal number until I got here:"
1122 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1123 \ only recognize things like this:"
1124 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1128 NumberNoLeadingZero ->
1129 Report.Report "LEADING ZEROS" region [] $
1130 Report.toCodeSnippet source region Nothing
1133 "I do not accept numbers with leading zeros:"
1137 "Just delete the leading zeros and it should work!"
1139 "Some languages let you to specify octal numbers by adding a leading zero.\
1140 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1141 \ that, but others probably want it to equal 111. Either path is going to\
1142 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1151 CommentOnNothing region ->
1152 Report.Report "STRAY COMMENT" region [] $
1153 Report.toCodeSnippet source region Nothing
1155 "This documentation comment is not followed by anything."
1158 "All documentation comments need to be right above the declaration they\
1159 \ describe. Maybe some code got deleted or commented out by accident? Or\
1160 \ maybe this comment is here by accident?"
1163 UnexpectedPort region ->
1164 Report.Report "UNEXPECTED PORTS" region [] $
1165 Report.toCodeSnippet source region Nothing
1168 "You are declaring ports in a normal module."
1172 ["Switch","this","to","say",D.green "port module","instead,"
1173 ,"marking","that","this","module","contains","port","declarations."
1176 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
1178 "to learn the syntax and how to use it effectively."
1183 Report.Report "NO PORTS" region [] $
1184 Report.toCodeSnippet source region Nothing
1187 "This module does not declare any ports, but it says it will:"
1190 ["Switch","this","to",D.green "module"
1191 ,"and","you","should","be","all","set!"
1195 ParseError row col context expectation ->
1197 pos = A.Position row col
1198 region = A.Region pos pos
1202 error "TODO no parse error yet"
1205 error "TODO no parse error yet"
1210 Report.Report "NO TABS" region [] $
1211 Report.toCodeSnippet source region Nothing
1214 "I ran into a tab, but tabs are not allowed in Elm files."
1217 "Replace the tab with spaces."
1221 Report.Report "EXPECTING DOC COMMENT" region [] $
1222 Report.toCodeSnippet source region Nothing
1225 "I was expecting a doc comment here:"
1228 "Check out" "TODO" "for examples of doc comments."
1234 Report.Report "EXPECTING PRECEDENCE" region [] $
1235 Report.toCodeSnippet source region Nothing
1238 "I was expecting the precedence here:"
1241 "I need a single digit between 0 and 9 inclusive."
1245 Report.Report "EXPECTING AN OPERATOR" region [] $
1246 Report.toCodeSnippet source region Nothing
1249 "I was expecting an operator here:"
1252 [ D.reflow "Some of the most common operators are:"
1253 , D.indent 4 $ D.vcat ["+","-","*","&&","||"]
1254 , D.reflow "Something like that!"
1258 ReservedOperator op ->
1259 error "TODO ReservedOperator" op
1262 Report.Report "EXPECTING A WILDCARD" region [] $
1263 Report.toCodeSnippet source region Nothing
1266 "I was expecting a _ here:"
1269 "An underscore indicates that “I do not care about this value” and is\
1270 \ called a wildcard pattern because it will match with any type of values."
1273 WildcardNotVar startCol endCol ->
1276 A.Region (A.Position row startCol) (A.Position row endCol)
1278 Report.Report "INVALID PATTERN" badRegion [] $
1279 Report.toCodeSnippet source badRegion Nothing
1282 "I was expecting to see an underscore without any additional characters:"
1285 "There are two options. Either (1) remove the extra characters and ignore the\
1286 \ value or (2) remove the starting underscore to give the value a normal name."
1292 Report.Report "INVALID PATTERN" region [] $
1293 Report.toCodeSnippet source region Nothing
1296 "I cannot pattern match with floating point numbers:"
1299 "Equality on floats can be unreliable, so you usually want to check that they\
1300 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
1304 Report.Report "EXPECTING A FIELD NAME" region [] $
1305 Report.toCodeSnippet source region Nothing
1308 "I was expecting a field name here:"
1311 ["A","name","like",D.dullyellow "id" <> ",",D.dullyellow "status" <> ","
1312 ,"or","whatever","field","you","want","to","access."
1318 MatchingName name ->
1319 Report.Report "EXPECTING A DEFINITION" region [] $
1320 Report.toCodeSnippet source region Nothing
1323 "I just saw the type annotation for `" ++ Name.toChars name
1324 ++ "` so I was expecting to see its definition here:"
1327 "Type annotations always appear directly above the relevant\
1328 \ definition, without anything else (even doc comments) in between."
1334 TypeWithBadDefinition region annName defName ->
1335 Report.Report "ANNOTATION MISMATCH" region [] $
1336 Report.toCodeSnippet source region Nothing
1339 "I see a `" <> Name.toChars annName
1340 <> "` annotation, but it is followed by a `"
1341 <> Name.toChars defName <> "` definition."
1344 ["The","annotation","and","definition","names","must","match!"
1345 ,"Is","there","a","typo","between"
1346 , D.dullyellow (D.fromName annName)
1348 , D.dullyellow (D.fromName defName) <> "?"
1353-- PARSE ERROR TO DOCS
1356problemToDocs :: Problem -> (D.Doc, D.Doc)
1357problemToDocs problem =
1361 "I ran into a tab, but tabs are not allowed in Elm files."
1363 "Replace the tab with spaces."
1366 EndOfFile_Comment ->
1368 "I got to the end of the file while parsing a multi-line comment."
1371 "Multi-line comments look like {- comment -}, and it looks like\
1372 \ you are missing the closing marker."
1375 "Nested multi-line comments like {- this {- and this -} -} are allowed.\
1376 \ The opening and closing markers must be balanced though, just\
1377 \ like parentheses in normal code. Maybe that is the problem?"
1383 "I got to the end of the file while parsing a string."
1385 "Strings look like \"this\" with double quotes on each end.\
1386 \ Is the closing double quote missing in your code?"
1389 EndOfFile_MultiString ->
1391 "I got to the end of the file while parsing a multi-line string."
1393 "Multi-line strings look like \"\"\"this\"\"\" with three double quotes\
1394 \ on each end. Is the closing triple quote missing in your code?"
1399 "I got to the end of the file while parsing a character."
1401 "Characters look like 'c' with single quotes on each end.\
1402 \ Is the closing single quote missing in your code?"
1407 "This string is missing the closing quote."
1410 "Elm strings like \"this\" cannot contain newlines."
1413 "For strings that CAN contain newlines, say \"\"\"this\"\"\" for Elm’s\
1414 \ multi-line string syntax. It allows unescaped newlines and double quotes."
1420 "This character is missing the closing quote."
1422 "Elm characters must start and end with a single quote. Valid examples\n\
1423 \ include 'a', 'b', '\n', 'ø', and '\\u{00F8}' for unicode code points."
1426 BadNumberDot numberBeforeDot ->
1428 "Numbers cannot end with a decimal points."
1432 D.fromString (show numberBeforeDot)
1434 "Saying " <> D.green number <> " or " <> D.green (number <> ".0") <> " will work though!"
1439 "Numbers cannot have letters or underscores in them."
1441 "Maybe a space is missing between a number and a variable?"
1446 "If you put the letter E in a number, it should followed by more digits."
1448 "If you want to say 1000, you can also say 1e3.\
1449 \ You cannot just end it with an E though!"
1454 "I see the start of a hex number, but not the end."
1456 "A hex number looks like 0x123ABC, where the 0x is followed by hexidecimal\
1457 \ digits. Valid hexidecimal digits include: 0123456789abcdefABCDEF"
1462 "Normal numbers cannot start with zeros. Take the zeros off the front."
1464 "Only numbers like 0x0040 or 0.25 can start with a zero."
1469 "Variable names cannot start with an underscore like this:"
1471 "Delete the underscore and it shoulld be fine!"
1477 badOp stack "A" "\"has type\" operator"
1478 "type annotations and record types"
1479 "Maybe you want :: instead? Or maybe something is indented too much?"
1483 "I was not expecting this equals sign"
1484 <> contextToString " here" " while parsing " stack <> "."
1486 toBadEqualsHint stack
1490 if isCaseRelated stack then
1492 "I ran into a stray arrow while parsing this `case` expression."
1495 "All branches in a `case` must be indented the exact\
1496 \ same amount, so the patterns are vertically\
1497 \ aligned. Maybe this branch is indented too much?"
1501 badOp stack "An" "arrow"
1502 "cases expressions and anonymous functions"
1503 "Maybe you want > or >= instead?"
1506 badOp stack "A" "vertical bar"
1508 "Maybe you want || instead?"
1512 "I was not expecting this dot."
1515 "Dots are for record access and decimal points, so\
1516 \ they cannot float around on their own. Maybe\
1517 \ there is some extra whitespace?"
1520 Theories stack allTheories ->
1523 "Something went wrong while parsing " <> contextToString "your code" "" stack <> "."
1525 case Set.toList (Set.fromList allTheories) of
1529 "I do not have any suggestions though!"
1531 "Can you get it down to a <http://sscce.org> and share it at\
1532 \ <https://github.com/elm/error-message-catalog/issues>?\
1533 \ That way we can figure out how to give better advice!"
1538 "I was expecting to see "
1539 <> addPeriod (theoryToString stack theory)
1543 [ "I was expecting:"
1546 ++ map (bullet . theoryToString stack) theories
1554badOp :: ContextStack -> String -> String -> String -> String -> ( D.Doc, D.Doc )
1555badOp stack article opName setting hint =
1558 "I was not expecting this " <> opName
1559 <> contextToString " here" " while parsing " stack <> "."
1562 article <> " " <> opName <> " should only appear in "
1563 <> setting <> ". " <> hint
1567toBadEqualsHint :: ContextStack -> D.Doc
1568toBadEqualsHint stack =
1572 "Maybe you want == instead? Or maybe something is indented too much?"
1574 (ExprRecord, _) : _ ->
1576 "Records look like { x = 3, y = 4 } with the equals sign right\
1577 \ after the field name. Maybe you forgot a comma?"
1579 (Definition _, _) : rest ->
1581 "Maybe this is supposed to be a separate definition? If so, it\
1582 \ is indented too far. "
1584 if any ((==) ExprLet . fst) rest then
1585 "All definitions in a `let` expression must be vertically aligned."
1587 "Spaces are not allowed before top-level definitions."
1590 toBadEqualsHint rest
1594isCaseRelated :: ContextStack -> Bool
1595isCaseRelated stack =
1600 (context, _) : rest ->
1601 context == ExprCase || isCaseRelated rest
1608contextToString :: String -> String -> ContextStack -> String
1609contextToString defaultString prefixString stack =
1614 (context, _) : rest ->
1615 let anchor = getAnchor rest in
1618 ExprIf -> "an `if` expression" <> anchor
1619 ExprLet -> "a `let` expression" <> anchor
1620 ExprFunc -> "an anonymous function" <> anchor
1621 ExprCase -> "a `case` expression" <> anchor
1622 ExprList -> "a list" <> anchor
1623 ExprTuple -> "an expression (in parentheses)" <> anchor
1624 ExprRecord -> "a record" <> anchor
1625 Definition name -> Name.toChars name <> "'s definition"
1626 Annotation name -> Name.toChars name <> "'s type annotation"
1627 TypeTuple -> "a type (in parentheses)" <> anchor
1628 TypeRecord -> "a record type" <> anchor
1629 PatternList -> "a list pattern" <> anchor
1630 PatternTuple -> "a pattern (in parentheses)" <> anchor
1631 PatternRecord -> "a record pattern" <> anchor
1632 Module -> "a module declaration"
1633 Import -> "an import"
1634 TypeUnion -> "a union type"
1635 TypeAlias -> "a type alias"
1636 Infix -> "an infix declaration"
1637 Port -> "a port declaration"
1640getAnchor :: ContextStack -> String
1646 (context, _) : rest ->
1649 " in " <> Name.toChars name <> "'s definition"
1652 " in " <> Name.toChars name <> "'s type annotation"
1662bullet :: String -> D.Doc
1664 D.hang 4 (" - " <> D.fillSep (map D.fromString (words point)))
1667addPeriod :: String -> String
1669 if last msg `elem` ['`', ')', '.', '!', '?'] then
1675theoryToString :: ContextStack -> Theory -> String
1676theoryToString context theory =
1679 "the `" <> keyword <> "` keyword"
1683 "=" -> equalsTheory context
1684 "->" -> "an arrow (->) followed by an expression"
1685 ":" -> "the \"has type\" symbol (:) followed by a type"
1687 "|" -> barTheory context
1688 "::" -> "the cons operator (::) followed by more list elements"
1690 "-" -> "a minus sign (-)"
1691 "_" -> "an underscore"
1692 "(" -> "a left paren, for grouping or starting tuples"
1693 ")" -> "a closing paren"
1694 "[" -> "a left square bracket, for starting lists"
1695 "]" -> "a right square bracket, to end a list"
1696 "{" -> "a left curly brace, for starting records"
1697 "}" -> "a right curly brace, to end a record"
1698 "{-|" -> "a doc comment, like {-| this -}" --}
1699 _ -> "the (" <> symbol <> ") symbol"
1702 "a lower-case variable, like `x` or `user`"
1705 "an upper-case variable, like `Maybe` or `Just`"
1708 "an infix operator, like (+) or (==)"
1711 "a digit from 0 to 9"
1718 Decl -> "a declaration, like `x = 5` or `type alias Model = { ... }`"
1719 Expr -> "an expression, like x or 42"
1720 AfterOpExpr op -> "an expression after that (" <> Name.toChars op <> ") operator, like x or 42"
1721 ElseBranch -> "an `else` branch. An `if` must handle both possibilities."
1722 Arg -> "an argument, like `name` or `total`"
1723 Pattern -> "a pattern, like `name` or (Just x)"
1724 Type -> "a type, like Int or (List String)"
1725 Listing -> "a list of exposed values and types, like (..) or (x,y,z)"
1726 Exposing -> "something like `exposing (..)`"
1729equalsTheory :: ContextStack -> String
1733 "an equals sign (=)"
1735 (context, _) : rest ->
1737 ExprRecord -> "an equals sign (=) followed by an expression"
1738 Definition name -> "an equals sign (=) followed by " <> Name.toChars name <> "'s definition"
1739 TypeUnion -> "an equals sign (=) followed by the first union type constructor"
1740 TypeAlias -> "an equals sign (=) followed by the aliased type"
1741 _ -> equalsTheory rest
1744barTheory :: ContextStack -> String
1748 "a vertical bar (|)"
1750 (context, _) : rest ->
1752 ExprRecord -> "a vertical bar (|) followed by the record fields you want to update"
1753 TypeRecord -> "a vertical bar (|) followed by some record field types"
1754 TypeUnion -> "a vertical bar (|) followed by more union type constructors"
1758badSpace :: ContextStack -> String
1762 "more indentation? I was not done with that last thing yet."
1764 (context, _) : rest ->
1766 ExprIf -> "the end of that `if`" <> badSpaceExprEnd rest
1767 ExprLet -> "the end of that `let`" <> badSpaceExprEnd rest
1768 ExprFunc -> badSpace rest
1769 ExprCase -> "more of that `case`" <> badSpaceExprEnd rest
1770 ExprList -> "the end of that list" <> badSpaceExprEnd rest
1771 ExprTuple -> "a closing paren" <> badSpaceExprEnd rest
1772 ExprRecord -> "the end of that record" <> badSpaceExprEnd rest
1773 Definition name -> "the rest of " <> Name.toChars name <> "'s definition" <> badSpaceExprEnd stack
1774 Annotation name -> "the rest of " <> Name.toChars name <> "'s type annotation" <> badSpaceEnd
1775 TypeTuple -> "a closing paren" <> badSpaceEnd
1776 TypeRecord -> "the end of that record" <> badSpaceEnd
1777 PatternList -> "the end of that list" <> badSpaceEnd
1778 PatternTuple -> "a closing paren" <> badSpaceEnd
1779 PatternRecord -> "the end of that record" <> badSpaceEnd
1780 Module -> "something like `module Main exposing (..)`"
1781 Import -> "something like `import Html exposing (..)`"
1782 TypeUnion -> "more of that union type" <> badSpaceEnd
1783 TypeAlias -> "more of that type alias" <> badSpaceEnd
1784 Infix -> "more of that infix declaration" <> badSpaceEnd
1785 Port -> "more of that port declaration" <> badSpaceEnd
1788badSpaceEnd :: String
1790 ". Maybe you forgot some code? Or you need more indentation?"
1793badSpaceExprEnd :: ContextStack -> String
1794badSpaceExprEnd stack =
1799 (Definition name, A.Position _ column) : _ ->
1805 "more indentation? (Try " <> show (column + 1) <> "+ spaces.)"
1807 ". Maybe you forgot some code? Or maybe the body of `"
1808 <> Name.toChars name
1809 <> "` needs " <> ending
1812 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