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 | OperatorRight Name.Name 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 Name.Name 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
472 | CharNotString Word16
476 = StringEndless_Single
477 | StringEndless_Multi
478 | StringEscape Escape
483 | BadUnicodeFormat Word16
484 | BadUnicodeCode Word16
485 | BadUnicodeLength Word16 Int Int
492 | NumberNoLeadingZero
501 | EndlessMultiComment
516toReport :: Code.Source -> Error -> Report.Report
519 ModuleNameUnspecified name ->
521 region = toRegion 1 1
523 Report.Report "MODULE NAME MISSING" region [] $
526 "I need the module name to be declared at the top of this file, like this:"
527 , D.indent 4 $ D.green $ D.fromChars $
528 "module " ++ ModuleName.toChars name ++ " exposing (..)"
530 "Try adding that as the first line of your file!"
532 "It is best to replace (..) with an explicit list of types and\
533 \ functions you want to expose. When you know a value is only used\
534 \ within this module, you can refactor without worrying about uses\
535 \ elsewhere. Limiting exposed values can also speed up compilation\
536 \ because I can skip a bunch of work if I see that the exposed API\
540 ModuleNameMismatch expectedName (A.At region actualName) ->
541 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
542 Report.toCodeSnippet source region Nothing
544 "It looks like this module name is out of sync:"
548 "I need it to match the file path, so I was expecting it to see `"
549 ++ ModuleName.toChars expectedName
550 ++ "` here. Make the following change, and you should be all set!"
552 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
554 "I require that module names correspond to file paths. This makes it much\
555 \ easier to explore unfamiliar codebases! So if you want to keep the current\
556 \ module name, try renaming the file instead."
560 UnexpectedPort region ->
561 error "TODO UnexpectedPort" region
564 error "TODO NoPorts" region
567 toParseErrorReport source modul
570toParseErrorReport :: Code.Source -> Module -> Report.Report
571toParseErrorReport source modul =
573 ModuleSpace space row col ->
574 toSpaceReport source space row col
576 ModuleEndOfFile row col ->
578 region = toRegion row col
580 Report.Report "EXPECTING END OF FILE" region [] $
581 Report.toCodeSnippet source region Nothing
584 "I was not expecting to see anything more here:"
587 "I think I have read all the declarations in the file and that there is nothing\
588 \ left to see, so whatever I am running into is confusing me a lot!"
592 error "TODO Module" row col
594 ModuleName row col ->
595 error "TODO ModuleName" row col
597 ModuleExposing row col ->
598 error "TODO ModuleExposing" row col
600 ModuleExposingList exposing row col ->
601 error "TODO ModuleExposingList" exposing row col
604 ModulePortModule row col ->
605 error "TODO ModulePortModule" row col
607 ModuleEffect row col ->
608 error "TODO ModuleEffect" row col
610 ModuleIndentStart row col ->
611 error "TODO ModuleIndentStart" row col
613 ModuleIndentName row col ->
614 error "TODO ModuleIndentName" row col
616 ModuleIndentExposing row col ->
617 error "TODO ModuleIndentExposing" row col
619 ModuleIndentExposingList row col ->
620 error "TODO ModuleIndentExposingList" row col
622 ModuleIndentPortModule row col ->
623 error "TODO ModuleIndentPortModule" row col
625 FreshLineModuleStart row col ->
626 error "TODO FreshLineModuleStart" row col
628 FreshLineAfterModuleLine row col ->
629 error "TODO FreshLineAfterModuleLine" row col
631 FreshLineAfterDocComment row col ->
632 error "TODO FreshLineAfterDocComment" row col
634 ImportStart row col ->
635 error "TODO ImportStart" row col
637 ImportName row col ->
638 error "TODO ImportName" row col
641 error "TODO ImportAs" row col
643 ImportAlias row col ->
644 error "TODO ImportAlias" row col
646 ImportExposing row col ->
647 error "TODO ImportExposing" row col
649 ImportExposingList exposing row col ->
650 error "TODO ImportExposingList" exposing row col
653 error "TODO ImportEnd" row col
655 ImportIndentName row col ->
656 error "TODO ImportIndentName" row col
658 ImportIndentAs row col ->
659 error "TODO ImportIndentAs" row col
661 ImportIndentAlias row col ->
662 error "TODO ImportIndentAlias" row col
664 ImportIndentExposing row col ->
665 error "TODO ImportIndentExposing" row col
667 ImportIndentExposingList row col ->
668 error "TODO ImportIndentExposingList" row col
671 error "TODO Infix" row col
673 Declarations decl _ _ ->
674 toDeclarationsReport source decl
677toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
678toSpaceReport source space row col =
682 region = toRegion row col
684 Report.Report "NO TABS" region [] $
685 Report.toCodeSnippet source region Nothing
688 "I ran into a tab, but tabs are not allowed in Elm files."
691 "Replace the tab with spaces."
694 EndlessMultiComment ->
696 region = toWiderRegion row col 2
698 Report.Report "ENDLESS COMMENT" region [] $
699 Report.toCodeSnippet source region Nothing
702 "I cannot find the end of this multi-line comment:"
705 [ D.reflow "Add a -} somewhere after this to end the comment."
707 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
708 \ that happens to contain another comment. Like parentheses and curly braces,\
709 \ the start and end markers must always be balanced. Maybe that is the problem?"
714toRegion :: Row -> Col -> A.Region
717 pos = A.Position row col
722toWiderRegion :: Row -> Col -> Word16 -> A.Region
723toWiderRegion row col extra =
726 (A.Position row (col + extra))
729toDeclarationsReport :: Code.Source -> Decl -> Report.Report
730toDeclarationsReport source decl =
733 error "TODO DeclStart" row col
735 DeclSpace space row col ->
736 toSpaceReport source space row col
739 error "TODO Port" port row col
741 DeclType declType row col ->
742 error "TODO DeclType" declType row col
744 DeclDef name declDef row col ->
745 toDeclDefReport source name declDef row col
747 DeclFreshLineStart row col ->
748 error "TODO DeclFreshLineStart" row col
750 DeclFreshLineAfterDocComment row col ->
751 error "TODO DeclFreshLineAfterDocComment" row col
754toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
755toDeclDefReport source name declDef _ _ =
757 DeclDefSpace space row col ->
758 toSpaceReport source space row col
760 DeclDefEquals row col ->
761 error "TODO DeclDefEquals" row col
763 DeclDefType tipe row col ->
764 error "TODO DeclDefType" tipe row col
766 DeclDefArg pattern row col ->
767 error "TODO DeclDefArg" pattern row col
769 DeclDefBody expr row col ->
770 toExprReport source name expr row col
772 DeclDefNameRepeat row col ->
773 error "TODO DeclDefNameRepeat" name row col
775 DeclDefNameMatch defName row col ->
776 error "TODO DeclDefNameMatch" name defName row col
778 DeclDefIndentType row col ->
779 error "TODO DeclDefIndentType" row col
781 DeclDefIndentEquals row col ->
782 error "TODO DeclDefIndentEquals" row col
784 DeclDefIndentBody row col ->
785 error "TODO DeclDefIndentBody" row col
787 DeclDefFreshLineAfterType row col ->
788 error "TODO DeclDefFreshLineAfterType" row col
792toExprReport :: Code.Source -> Name.Name -> Expr -> Row -> Col -> Report.Report
793toExprReport source name expr _ _ =
805 toListReport source name list row col
817 toFuncReport source name func row col
820 let region = toRegion row col in
821 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
822 Report.toCodeSnippet source region Nothing
825 "I was expecting to see a record accessor here:"
828 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
829 ,"that","accesses","a","value","from","a","record."
834 let region = toRegion row col in
835 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
836 Report.toCodeSnippet source region Nothing
839 "I am trying to parse a record accessor here:"
844 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
845 ,"that","accesses","a","value","from","a","record."
849 "Record field names must start with a lower case letter!"
853 OperatorRight op row col ->
854 let region = toRegion row col in
855 Report.Report "MISSING EXPRESSION" region [] $
856 Report.toCodeSnippet source region Nothing
859 "I need to see an expression after this " ++ Name.toChars op ++ " operator:"
862 ["You","can","just","put","anything","for","now,","like"
863 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
864 ,"Once","there","is","something","there,","I","can","give","more"
865 ,"specific","hints","about","what","type","of","value","is","needed!"
869 OperatorReserved operator row col ->
870 toOperatorReport source name operator row col
876 toCharReport source char row col
878 String string row col ->
879 toStringReport source string row col
881 Number number row col ->
882 toNumberReport source number row col
884 Space space row col ->
885 toSpaceReport source space row col
887 EndlessShader row col ->
889 region = toWiderRegion row col 6
891 Report.Report "ENDLESS SHADER" region [] $
892 Report.toCodeSnippet source region Nothing
894 D.reflow "I cannot find the end of this shader:"
896 D.reflow "Add a |] somewhere after this to end the shader."
899 ShaderProblem problem row col ->
901 region = toRegion row col
903 Report.Report "SHADER PROBLEM" region [] $
904 Report.toCodeSnippet source region Nothing
907 "I ran into a problem while parsing this GLSL block."
911 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
912 , D.indent 4 $ D.vcat $
913 map D.fromChars (filter (/="") (lines problem))
917 IndentOperatorRight op row col ->
918 let region = toRegion row col in
919 Report.Report "MISSING EXPRESSION" region [] $
920 Report.toCodeSnippet source region Nothing
923 "I need to see an expression after this " ++ Name.toChars op ++ " operator:"
928 ["You","can","just","put","anything","for","now,","like"
929 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
930 ,"Once","there","is","something","there,","I","can","give","more"
931 ,"specific","hints","about","what","type","of","value","is","needed!"
935 "I may be getting confused by your indentation? The easiest way to make sure\
936 \ this is not an indentation problem is to put the expression on the right of\
937 \ the " ++ Name.toChars op ++ " operator on the same line."
941 IndentMoreExpr _ _ ->
942 error "TODO IndentMoreExpr"
945toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
946toCharReport source char row col =
950 region = toRegion row col
952 Report.Report "MISSING SINGLE QUOTE" region [] $
953 Report.toCodeSnippet source region Nothing
956 "I thought I was parsing a character, but I got to the end of\
957 \ the line without seeing the closing single quote:"
960 "Add a closing single quote here!"
964 toEscapeReport source escape row col
966 CharNotString width ->
968 region = toWiderRegion row col width
970 Report.Report "NEEDS DOUBLE QUOTES" region [] $
971 Report.toCodeSnippet source region Nothing
973 "The following string uses single quotes:"
976 [ "Please switch to double quotes instead:"
978 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
980 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
981 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
982 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
983 \ individual characters."
988toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
989toStringReport source string row col =
991 StringEndless_Single ->
993 region = toRegion row col
995 Report.Report "ENDLESS STRING" region [] $
996 Report.toCodeSnippet source region Nothing
999 "I got to the end of the line without seeing the closing double quote:"
1003 ["Strings","look","like",D.green "\"this\"","with","double"
1004 ,"quotes","on","each","end.","Is","the","closing","double"
1005 ,"quote","missing","in","your","code?"
1007 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
1011 StringEndless_Multi ->
1013 region = toWiderRegion row col 3
1015 Report.Report "ENDLESS STRING" region [] $
1016 Report.toCodeSnippet source region Nothing
1019 "I cannot find the end of this multi-line string:"
1022 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
1023 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
1027 StringEscape escape ->
1028 toEscapeReport source escape row col
1031toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1032toEscapeReport source escape row col =
1036 region = toWiderRegion row col 2
1038 Report.Report "UNKNOWN ESCAPE" region [] $
1039 Report.toCodeSnippet source region Nothing
1042 "Backslashes always start escaped characters, but I do not recognize this one:"
1046 "Valid escape characters include:"
1047 , D.dullyellow $ D.indent 4 $ D.vcat $
1057 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1059 "The last style lets encode ANY character by its Unicode code\
1060 \ point. That means \\u{0009} and \\t are the same. You can use\
1061 \ that style for anything not covered by the other six escapes!"
1065 BadUnicodeFormat width ->
1067 region = toWiderRegion row col width
1069 Report.Report "BAD UNICODE ESCAPE" region [] $
1070 Report.toCodeSnippet source region Nothing
1073 "I ran into an invalid Unicode escape:"
1077 "Here are some examples of valid Unicode escapes:"
1078 , D.dullyellow $ D.indent 4 $ D.vcat $
1085 "Notice that the code point is always surrounded by curly braces.\
1086 \ Maybe you are missing the opening or closing curly brace?"
1089 BadUnicodeCode width ->
1091 region = toWiderRegion row col width
1093 Report.Report "BAD UNICODE ESCAPE" region [] $
1094 Report.toCodeSnippet source region Nothing
1097 "This is not a valid code point:"
1100 "The valid code points are between 0 and 10FFFF inclusive."
1103 BadUnicodeLength width numDigits badCode ->
1105 region = toWiderRegion row col width
1107 Report.Report "BAD UNICODE ESCAPE" region [] $
1108 Report.toCodeSnippet source region Nothing $
1109 if numDigits < 4 then
1112 "Every code point needs at least four digits:"
1115 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1116 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1118 D.fillSep ["Try",D.green suggestion,"instead?"]
1124 "This code point has too many digits:"
1127 ["Valid","code","points","are","between"
1128 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1129 ,"so","try","trimming","any","leading","zeros","until"
1130 ,"you","have","between","four","and","six","digits."
1135toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1136toNumberReport source number row col =
1138 region = toRegion row col
1142 Report.Report "WEIRD NUMBER" region [] $
1143 Report.toCodeSnippet source region Nothing
1146 "I thought I was reading a number, but I ran into some weird stuff here:"
1150 "I recognize numbers in the following formats:"
1151 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1153 "So is there a way to write it like one of those?"
1158 Report.Report "WEIRD NUMBER" region [] $
1159 Report.toCodeSnippet source region Nothing
1162 "Numbers cannot end with a dot like this:"
1165 ["Switching","to",D.green (D.fromChars (show int))
1166 ,"or",D.green (D.fromChars (show int ++ ".0"))
1167 ,"will","work","though!"
1172 Report.Report "WEIRD HEXIDECIMAL" region [] $
1173 Report.toCodeSnippet source region Nothing
1176 "I thought I was reading a hexidecimal number until I got here:"
1180 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1181 \ only recognize things like this:"
1182 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1186 NumberNoLeadingZero ->
1187 Report.Report "LEADING ZEROS" region [] $
1188 Report.toCodeSnippet source region Nothing
1191 "I do not accept numbers with leading zeros:"
1195 "Just delete the leading zeros and it should work!"
1197 "Some languages let you to specify octal numbers by adding a leading zero.\
1198 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1199 \ that, but others probably want it to equal 111. Either path is going to\
1200 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1206toOperatorReport :: Code.Source -> Name.Name -> Operator -> Row -> Col -> Report.Report
1207toOperatorReport source name operator row col =
1211 region = toRegion row col
1213 Report.Report "UNEXPECTED SYMBOL" region [] $
1214 Report.toCodeSnippet source region Nothing
1216 "I was not expecting this dot:"
1219 "Dots are for record access and decimal points, so\
1220 \ they cannot float around on their own. Maybe\
1221 \ there is some extra whitespace?"
1226 region = toRegion row col
1228 Report.Report "UNEXPECTED SYMBOL" region [] $
1229 Report.toCodeSnippet source region Nothing
1232 "I was not expecting this vertical bar:"
1235 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
1240 region = toWiderRegion row col 2
1242 Report.Report "UNEXPECTED ARROW" region [] $
1243 Report.toCodeSnippet source region Nothing $
1244 if error "TODO inCase" then
1247 "I was not expecting to see an arrow here:"
1252 "I think I am parsing a `case` expression right now, so it makes sense to\
1253 \ see arrows around here. This one is confusing me though!"
1256 "I may be getting confused by the indentation. Every pattern in a `case` must be\
1257 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
1258 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
1259 \ indented too far?"
1266 "I was not expecting an arrow here:"
1269 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
1270 \ you want > or >= instead?"
1275 region = toRegion row col
1277 Report.Report "UNEXPECTED EQUALS" region [] $
1278 Report.toCodeSnippet source region Nothing
1281 "I was not expecting to see this equals sign:"
1285 D.reflow "Maybe you want == instead? To check if two values are equal?"
1288 if error "TODO is within record?" then
1289 "Records look like { x = 3, y = 4 } with the equals sign right\
1290 \ after the field name. So maybe you forgot a comma?"
1292 "I may be getting confused by your indentation. Is this supposed to be part of\
1293 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1294 \ the problem may be a bit before the equals sign. I need all definitions to\
1295 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1296 \ this new definition is indented a bit too much."
1302 region = toRegion row col
1304 Report.Report "UNEXPECTED SYMBOL" region [] $
1305 Report.toCodeSnippet source region Nothing $
1308 "I was not expecting to run into the \"has type\" symbol here:"
1313 ["Maybe","you","want",D.green "::","instead?"
1314 ,"To","put","something","on","the","front","of","a","list?"
1317 "The single colon is reserved for type annotations and record types, but I think\
1318 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
1321 "I may be getting confused by your indentation. Is this supposed to be part of\
1322 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1323 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
1324 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1325 \ this new definition is indented a bit too much."
1330toListReport :: Code.Source -> Name.Name -> List -> Row -> Col -> Report.Report
1331toListReport source name func startRow startCol =
1333 ListSpace space row col ->
1334 toSpaceReport source space row col
1337 error "TODO ListOpen" row col
1339 ListExpr expr row col ->
1340 toExprReport source name expr row col
1343 error "TODO ListEnd" row col
1345 ListIndentOpen row col ->
1347 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1348 region = toRegion row col
1350 Report.Report "UNFINISHED LIST" region [] $
1351 Report.toCodeSnippet source surroundings (Just region)
1354 "I cannot find the end of this list:"
1358 ["You","could","change","it","to","something","like"
1359 ,D.dullyellow "[3,4,5]"
1361 ,D.dullyellow "[]" <> "."
1362 ,"Anything","where","there","is","an","open","and","close","square","brace,"
1363 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
1366 "I may be confused by indentation. For example, if you are trying to define\
1367 \ a list across multiple lines, I recommend using this format:"
1368 , D.indent 4 $ D.vcat $
1375 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
1376 \ This style can be jarring for people coming from C-like syntax, but folks generally\
1377 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1381 ListIndentEnd row col ->
1383 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1384 region = toRegion row col
1386 Report.Report "UNFINISHED LIST" region [] $
1387 Report.toCodeSnippet source surroundings (Just region)
1390 "I cannot find the end of this list:"
1394 ["You","can","just","add","a","closing",D.dullyellow "]"
1395 ,"right","here,","and","I","will","be","all","set!"
1398 "I may be confused by indentation. For example, if you are trying to define\
1399 \ a list across multiple lines, I recommend using this format:"
1400 , D.indent 4 $ D.vcat $
1407 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
1408 \ This style can be jarring for people coming from C-like syntax, but folks generally\
1409 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1413 ListIndentExpr row col ->
1415 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1416 region = toRegion row col
1418 Report.Report "UNFINISHED LIST" region [] $
1419 Report.toCodeSnippet source surroundings (Just region)
1422 "I was expecting to see another list entry after this comma:"
1426 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
1428 "I recommend using the following format for lists that span multiple lines:"
1429 , D.indent 4 $ D.vcat $
1436 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
1437 \ This style can be jarring for people coming from C-like syntax, but folks generally\
1438 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1443toFuncReport :: Code.Source -> Name.Name -> Func -> Row -> Col -> Report.Report
1444toFuncReport source name func startRow startCol =
1446 FuncSpace space row col ->
1447 toSpaceReport source space row col
1449 FuncArg pattern row col ->
1450 error "TODO FuncArg" pattern row col
1452 FuncBody expr row col ->
1453 toExprReport source name expr row col
1455 FuncArrow row col ->
1457 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1458 region = toRegion row col
1460 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
1461 Report.toCodeSnippet source surroundings (Just region)
1464 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
1467 ["The","syntax","for","anonymous","functions","is"
1468 ,D.dullyellow "(\\x -> x + 1)"
1469 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
1473 FuncIndentArg row col ->
1475 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1476 region = toRegion row col
1478 Report.Report "MISSING ARGUMENT" region [] $
1479 Report.toCodeSnippet source surroundings (Just region)
1482 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
1486 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
1487 ,"Anything","that","starts","with","a","lower","case","letter!"
1490 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
1491 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
1492 \ like a better idea at the time!"
1496 FuncIndentArrow row col ->
1498 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1499 region = toRegion row col
1501 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
1502 Report.toCodeSnippet source surroundings (Just region)
1505 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
1509 ["The","syntax","for","anonymous","functions","is"
1510 ,D.dullyellow "(\\x -> x + 1)"
1511 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
1514 "It is possible that I am confused about indetation! I generally recommend\
1515 \ switching to named functions if the definition cannot fit inline nicely, so\
1516 \ either (1) try to fit the whole anonymous function on one line or (2) break\
1517 \ the whole thing out into a named function. Things tend to be clearer that way!"
1521 FuncIndentBody row col ->
1523 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1524 region = toRegion row col
1526 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
1527 Report.toCodeSnippet source surroundings (Just region)
1530 "I was expecting to see the body of your anonymous function next:"
1534 ["The","syntax","for","anonymous","functions","is"
1535 ,D.dullyellow "(\\x -> x + 1)"
1536 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
1539 "It is possible that I am confused about indetation! I generally recommend\
1540 \ switching to named functions if the definition cannot fit inline nicely, so\
1541 \ either (1) try to fit the whole anonymous function on one line or (2) break\
1542 \ the whole thing out into a named function. Things tend to be clearer that way!"
1551 CommentOnNothing region ->
1552 Report.Report "STRAY COMMENT" region [] $
1553 Report.toCodeSnippet source region Nothing
1555 "This documentation comment is not followed by anything."
1558 "All documentation comments need to be right above the declaration they\
1559 \ describe. Maybe some code got deleted or commented out by accident? Or\
1560 \ maybe this comment is here by accident?"
1563 UnexpectedPort region ->
1564 Report.Report "UNEXPECTED PORTS" region [] $
1565 Report.toCodeSnippet source region Nothing
1568 "You are declaring ports in a normal module."
1572 ["Switch","this","to","say",D.green "port module","instead,"
1573 ,"marking","that","this","module","contains","port","declarations."
1576 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
1578 "to learn the syntax and how to use it effectively."
1583 Report.Report "NO PORTS" region [] $
1584 Report.toCodeSnippet source region Nothing
1587 "This module does not declare any ports, but it says it will:"
1590 ["Switch","this","to",D.green "module"
1591 ,"and","you","should","be","all","set!"
1595 ParseError row col context expectation ->
1597 pos = A.Position row col
1598 region = A.Region pos pos
1603 Report.Report "EXPECTING DOC COMMENT" region [] $
1604 Report.toCodeSnippet source region Nothing
1607 "I was expecting a doc comment here:"
1610 "Check out" "TODO" "for examples of doc comments."
1616 Report.Report "EXPECTING PRECEDENCE" region [] $
1617 Report.toCodeSnippet source region Nothing
1620 "I was expecting the precedence here:"
1623 "I need a single digit between 0 and 9 inclusive."
1627 Report.Report "EXPECTING AN OPERATOR" region [] $
1628 Report.toCodeSnippet source region Nothing
1631 "I was expecting an operator here:"
1634 [ D.reflow "Some of the most common operators are:"
1635 , D.indent 4 $ D.vcat ["+","-","*","&&","||"]
1636 , D.reflow "Something like that!"
1641 Report.Report "EXPECTING A WILDCARD" region [] $
1642 Report.toCodeSnippet source region Nothing
1645 "I was expecting a _ here:"
1648 "An underscore indicates that “I do not care about this value” and is\
1649 \ called a wildcard pattern because it will match with any type of values."
1652 WildcardNotVar startCol endCol ->
1655 A.Region (A.Position row startCol) (A.Position row endCol)
1657 Report.Report "INVALID PATTERN" badRegion [] $
1658 Report.toCodeSnippet source badRegion Nothing
1661 "I was expecting to see an underscore without any additional characters:"
1664 "There are two options. Either (1) remove the extra characters and ignore the\
1665 \ value or (2) remove the starting underscore to give the value a normal name."
1671 Report.Report "INVALID PATTERN" region [] $
1672 Report.toCodeSnippet source region Nothing
1675 "I cannot pattern match with floating point numbers:"
1678 "Equality on floats can be unreliable, so you usually want to check that they\
1679 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
1683 Report.Report "EXPECTING A FIELD NAME" region [] $
1684 Report.toCodeSnippet source region Nothing
1687 "I was expecting a field name here:"
1690 ["A","name","like",D.dullyellow "id" <> ",",D.dullyellow "status" <> ","
1691 ,"or","whatever","field","you","want","to","access."
1697 MatchingName name ->
1698 Report.Report "EXPECTING A DEFINITION" region [] $
1699 Report.toCodeSnippet source region Nothing
1702 "I just saw the type annotation for `" ++ Name.toChars name
1703 ++ "` so I was expecting to see its definition here:"
1706 "Type annotations always appear directly above the relevant\
1707 \ definition, without anything else (even doc comments) in between."
1713 TypeWithBadDefinition region annName defName ->
1714 Report.Report "ANNOTATION MISMATCH" region [] $
1715 Report.toCodeSnippet source region Nothing
1718 "I see a `" <> Name.toChars annName
1719 <> "` annotation, but it is followed by a `"
1720 <> Name.toChars defName <> "` definition."
1723 ["The","annotation","and","definition","names","must","match!"
1724 ,"Is","there","a","typo","between"
1725 , D.dullyellow (D.fromName annName)
1727 , D.dullyellow (D.fromName defName) <> "?"
1735contextToString :: String -> String -> ContextStack -> String
1736contextToString defaultString prefixString stack =
1741 (context, _) : rest ->
1742 let anchor = getAnchor rest in
1745 ExprIf -> "an `if` expression" <> anchor
1746 ExprLet -> "a `let` expression" <> anchor
1747 ExprFunc -> "an anonymous function" <> anchor
1748 ExprCase -> "a `case` expression" <> anchor
1749 ExprList -> "a list" <> anchor
1750 ExprTuple -> "an expression (in parentheses)" <> anchor
1751 ExprRecord -> "a record" <> anchor
1752 Definition name -> Name.toChars name <> "'s definition"
1753 Annotation name -> Name.toChars name <> "'s type annotation"
1754 TypeTuple -> "a type (in parentheses)" <> anchor
1755 TypeRecord -> "a record type" <> anchor
1756 PatternList -> "a list pattern" <> anchor
1757 PatternTuple -> "a pattern (in parentheses)" <> anchor
1758 PatternRecord -> "a record pattern" <> anchor
1759 Module -> "a module declaration"
1760 Import -> "an import"
1761 TypeUnion -> "a union type"
1762 TypeAlias -> "a type alias"
1763 Infix -> "an infix declaration"
1764 Port -> "a port declaration"
1767getAnchor :: ContextStack -> String
1773 (context, _) : rest ->
1776 " in " <> Name.toChars name <> "'s definition"
1779 " in " <> Name.toChars name <> "'s type annotation"
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