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 | Tuple Tuple Row Col
233 | OperatorRight Name.Name Row Col
234 | OperatorReserved Operator Row Col
238 | String String Row Col
239 | Number Number Row Col
240 | Space Space Row Col
241 | EndlessShader Row Col
242 | ShaderProblem [Char.Char] Row Col
243 | IndentOperatorRight Name.Name Row Col
244 | IndentMoreExpr Row Col
250 | RecordField Row Col
251 | RecordEquals Row Col
252 | RecordExpr Expr Row Col
253 | RecordSpace Space Row Col
255 | RecordIndentOpen Row Col
256 | RecordIndentEnd Row Col
257 | RecordIndentField Row Col
258 | RecordIndentEquals Row Col
259 | RecordIndentExpr Row Col
263 = TupleExpr Expr Row Col
264 | TupleSpace Space Row Col
266 | TupleOperatorClose Row Col
267 | TupleOperatorReserved Operator Row Col
269 | TupleIndentExpr1 Row Col
270 | TupleIndentExprN Row Col
271 | TupleIndentEnd Row Col
275 = ListSpace Space Row Col
277 | ListExpr Expr Row Col
280 | ListIndentOpen Row Col
281 | ListIndentEnd Row Col
282 | ListIndentExpr Row Col
286 = FuncSpace Space Row Col
287 | FuncArg Pattern Row Col
288 | FuncBody Expr Row Col
291 | FuncIndentArg Row Col
292 | FuncIndentArrow Row Col
293 | FuncIndentBody Row Col
297 = CaseSpace Space Row Col
299 | CasePattern Pattern Row Col
301 | CaseExpr Expr Row Col
302 | CaseBranch Expr Row Col
304 | CaseIndentOf Row Col
305 | CaseIndentExpr Row Col
306 | CaseIndentPattern Row Col
307 | CaseIndentArrow Row Col
308 | CaseIndentBranch Row Col
309 | CasePatternAlignment Word16 Row Col
313 = IfSpace Space Row Col
316 | IfElseBranchStart Row Col
318 | IfCondition Expr Row Col
319 | IfThenBranch Expr Row Col
320 | IfElseBranch Expr Row Col
322 | IfIndentCondition Row Col
323 | IfIndentThen Row Col
324 | IfIndentThenBranch Row Col
325 | IfIndentElseBranch Row Col
326 | IfIndentElse Row Col
330 = LetSpace Space Row Col
332 | LetDefAlignment Word16 Row Col
334 | LetDef Name.Name Def Row Col
335 | LetDestruct Destruct Row Col
336 | LetBody Expr Row Col
337 | LetIndentDef Row Col
338 | LetIndentIn Row Col
339 | LetIndentBody Row Col
343 = DefSpace Space Row Col
344 | DefType Type Row Col
345 | DefNameRepeat Name.Name Row Col
346 | DefNameMatch Name.Name Name.Name Row Col
347 | DefArg Pattern Row Col
349 | DefBody Expr Row Col
350 | DefIndentEquals Row Col
351 | DefIndentType Row Col
352 | DefIndentBody Row Col
353 | DefAlignment Word16 Row Col
357 = DestructSpace Space Row Col
358 | DestructPattern Pattern Row Col
359 | DestructEquals Row Col
360 | DestructBody Expr Row Col
361 | DestructIndentEquals Row Col
362 | DestructIndentBody Row Col
370 = PRecord PRecord Row Col
371 | PTuple PTuple Row Col
372 | PList PList Row Col
376 | PString String Row Col
377 | PNumber Number Row Col
380 | PWildcardNotVar Int Row Col
381 | PSpace Space Row Col
383 | PIndentStart Row Col
384 | PIndentAlias Row Col
388 = PRecordOpen Row Col
390 | PRecordField Row Col
391 | PRecordSpace Space Row Col
393 | PRecordIndentOpen Row Col
394 | PRecordIndentEnd Row Col
395 | PRecordIndentField Row Col
401 | PTupleExpr Pattern Row Col
402 | PTupleSpace Space Row Col
404 | PTupleIndentOpen Row Col
405 | PTupleIndentEnd Row Col
406 | PTupleIndentExpr Row Col
412 | PListExpr Pattern Row Col
413 | PListSpace Space Row Col
415 | PListIndentOpen Row Col
416 | PListIndentEnd Row Col
417 | PListIndentExpr Row Col
425 = TRecord TRecord Row Col
426 | TTuple TTuple Row Col
431 | TSpace Space Row Col
433 | TIndentStart Row Col
437 = TRecordOpen Row Col
440 | TRecordField Row Col
441 | TRecordColon Row Col
442 | TRecordType Type Row Col
444 | TRecordSpace Space Row Col
446 | TRecordIndentOpen Row Col
447 | TRecordIndentField Row Col
448 | TRecordIndentColon Row Col
449 | TRecordIndentType Row Col
450 | TRecordIndentEnd Row Col
456 | TTupleType Type Row Col
457 | TTupleSpace Space Row Col
459 | TTupleIndentOpen Row Col
460 | TTupleIndentType Row Col
461 | TTupleIndentEnd Row Col
471 | CharNotString Word16
475 = StringEndless_Single
476 | StringEndless_Multi
477 | StringEscape Escape
482 | BadUnicodeFormat Word16
483 | BadUnicodeCode Word16
484 | BadUnicodeLength Word16 Int Int
491 | NumberNoLeadingZero
500 | EndlessMultiComment
515toReport :: Code.Source -> Error -> Report.Report
518 ModuleNameUnspecified name ->
520 region = toRegion 1 1
522 Report.Report "MODULE NAME MISSING" region [] $
525 "I need the module name to be declared at the top of this file, like this:"
526 , D.indent 4 $ D.green $ D.fromChars $
527 "module " ++ ModuleName.toChars name ++ " exposing (..)"
529 "Try adding that as the first line of your file!"
531 "It is best to replace (..) with an explicit list of types and\
532 \ functions you want to expose. When you know a value is only used\
533 \ within this module, you can refactor without worrying about uses\
534 \ elsewhere. Limiting exposed values can also speed up compilation\
535 \ because I can skip a bunch of work if I see that the exposed API\
539 ModuleNameMismatch expectedName (A.At region actualName) ->
540 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
541 Report.toCodeSnippet source region Nothing
543 "It looks like this module name is out of sync:"
547 "I need it to match the file path, so I was expecting it to see `"
548 ++ ModuleName.toChars expectedName
549 ++ "` here. Make the following change, and you should be all set!"
551 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
553 "I require that module names correspond to file paths. This makes it much\
554 \ easier to explore unfamiliar codebases! So if you want to keep the current\
555 \ module name, try renaming the file instead."
559 UnexpectedPort region ->
560 error "TODO UnexpectedPort" region
563 error "TODO NoPorts" region
566 toParseErrorReport source modul
569toParseErrorReport :: Code.Source -> Module -> Report.Report
570toParseErrorReport source modul =
572 ModuleSpace space row col ->
573 toSpaceReport source space row col
575 ModuleEndOfFile row col ->
577 region = toRegion row col
579 Report.Report "EXPECTING END OF FILE" region [] $
580 Report.toCodeSnippet source region Nothing
583 "I was not expecting to see anything more here:"
586 "I think I have read all the declarations in the file and that there is nothing\
587 \ left to see, so whatever I am running into is confusing me a lot!"
591 error "TODO Module" row col
593 ModuleName row col ->
594 error "TODO ModuleName" row col
596 ModuleExposing row col ->
597 error "TODO ModuleExposing" row col
599 ModuleExposingList exposing row col ->
600 error "TODO ModuleExposingList" exposing row col
603 ModulePortModule row col ->
604 error "TODO ModulePortModule" row col
606 ModuleEffect row col ->
607 error "TODO ModuleEffect" row col
609 ModuleIndentStart row col ->
610 error "TODO ModuleIndentStart" row col
612 ModuleIndentName row col ->
613 error "TODO ModuleIndentName" row col
615 ModuleIndentExposing row col ->
616 error "TODO ModuleIndentExposing" row col
618 ModuleIndentExposingList row col ->
619 error "TODO ModuleIndentExposingList" row col
621 ModuleIndentPortModule row col ->
622 error "TODO ModuleIndentPortModule" row col
624 FreshLineModuleStart row col ->
625 error "TODO FreshLineModuleStart" row col
627 FreshLineAfterModuleLine row col ->
628 error "TODO FreshLineAfterModuleLine" row col
630 FreshLineAfterDocComment row col ->
631 error "TODO FreshLineAfterDocComment" row col
633 ImportStart row col ->
634 error "TODO ImportStart" row col
636 ImportName row col ->
637 error "TODO ImportName" row col
640 error "TODO ImportAs" row col
642 ImportAlias row col ->
643 error "TODO ImportAlias" row col
645 ImportExposing row col ->
646 error "TODO ImportExposing" row col
648 ImportExposingList exposing row col ->
649 error "TODO ImportExposingList" exposing row col
652 error "TODO ImportEnd" row col
654 ImportIndentName row col ->
655 error "TODO ImportIndentName" row col
657 ImportIndentAs row col ->
658 error "TODO ImportIndentAs" row col
660 ImportIndentAlias row col ->
661 error "TODO ImportIndentAlias" row col
663 ImportIndentExposing row col ->
664 error "TODO ImportIndentExposing" row col
666 ImportIndentExposingList row col ->
667 error "TODO ImportIndentExposingList" row col
670 error "TODO Infix" row col
672 Declarations decl _ _ ->
673 toDeclarationsReport source decl
676toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
677toSpaceReport source space row col =
681 region = toRegion row col
683 Report.Report "NO TABS" region [] $
684 Report.toCodeSnippet source region Nothing
687 "I ran into a tab, but tabs are not allowed in Elm files."
690 "Replace the tab with spaces."
693 EndlessMultiComment ->
695 region = toWiderRegion row col 2
697 Report.Report "ENDLESS COMMENT" region [] $
698 Report.toCodeSnippet source region Nothing
701 "I cannot find the end of this multi-line comment:"
704 [ D.reflow "Add a -} somewhere after this to end the comment."
706 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
707 \ that happens to contain another comment. Like parentheses and curly braces,\
708 \ the start and end markers must always be balanced. Maybe that is the problem?"
713toRegion :: Row -> Col -> A.Region
716 pos = A.Position row col
721toWiderRegion :: Row -> Col -> Word16 -> A.Region
722toWiderRegion row col extra =
725 (A.Position row (col + extra))
728toDeclarationsReport :: Code.Source -> Decl -> Report.Report
729toDeclarationsReport source decl =
732 error "TODO DeclStart" row col
734 DeclSpace space row col ->
735 toSpaceReport source space row col
738 error "TODO Port" port row col
740 DeclType declType row col ->
741 error "TODO DeclType" declType row col
743 DeclDef name declDef row col ->
744 toDeclDefReport source name declDef row col
746 DeclFreshLineStart row col ->
747 error "TODO DeclFreshLineStart" row col
749 DeclFreshLineAfterDocComment row col ->
750 error "TODO DeclFreshLineAfterDocComment" row col
753toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
754toDeclDefReport source name declDef startRow startCol =
756 DeclDefSpace space row col ->
757 toSpaceReport source space row col
759 DeclDefEquals row col ->
760 error "TODO DeclDefEquals" row col
762 DeclDefType tipe row col ->
763 error "TODO DeclDefType" tipe row col
765 DeclDefArg pattern row col ->
766 error "TODO DeclDefArg" pattern row col
768 DeclDefBody expr row col ->
769 toExprReport source (InDef name startRow startCol) expr row col
771 DeclDefNameRepeat row col ->
772 error "TODO DeclDefNameRepeat" name row col
774 DeclDefNameMatch defName row col ->
775 error "TODO DeclDefNameMatch" name defName row col
777 DeclDefIndentType row col ->
778 error "TODO DeclDefIndentType" row col
780 DeclDefIndentEquals row col ->
781 error "TODO DeclDefIndentEquals" row col
783 DeclDefIndentBody row col ->
784 error "TODO DeclDefIndentBody" row col
786 DeclDefFreshLineAfterType row col ->
787 error "TODO DeclDefFreshLineAfterType" row col
795 = InNode Node Row Col Context
796 | InDef Name.Name Row Col
810getDefName :: Context -> Name.Name
813 InDef name _ _ -> name
814 InNode _ _ _ c -> getDefName c
817isWithin :: Node -> Context -> Bool
818isWithin desiredNode context =
821 InNode actualNode _ _ _ -> desiredNode == actualNode
828toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
829toExprReport source context expr startRow startCol =
838 toIfReport source context if_ row col
841 toListReport source context list row col
843 Record record row col ->
844 toRecordReport source context record row col
846 Tuple tuple row col ->
847 toTupleReport source context tuple row col
850 toFuncReport source context func row col
853 let region = toRegion row col in
854 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
855 Report.toCodeSnippet source region Nothing
858 "I was expecting to see a record accessor here:"
861 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
862 ,"that","accesses","a","value","from","a","record."
867 let region = toRegion row col in
868 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
869 Report.toCodeSnippet source region Nothing
872 "I am trying to parse a record accessor here:"
877 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
878 ,"that","accesses","a","value","from","a","record."
882 "Record field names must start with a lower case letter!"
886 OperatorRight op row col ->
887 let region = toRegion row col in
888 Report.Report "MISSING EXPRESSION" region [] $
889 Report.toCodeSnippet source region Nothing
892 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
896 ["You","can","just","put","anything","for","now,","like"
897 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
898 ,"Once","there","is","something","there,","I","can","probably"
899 ,"give","a","more","specific","hint!"
902 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
903 \ Or if I run into operators in unexpected spots. Point is, there are a\
904 \ couple ways I can get confused and give sort of weird advice!"
908 OperatorReserved operator row col ->
909 toOperatorReport source context operator row col
913 (contextRow, contextCol, aThing) =
915 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
916 InNode NRecord r c _ -> (r, c, "a record")
917 InNode NParens r c _ -> (r, c, "some parentheses")
918 InNode NList r c _ -> (r, c, "a list")
919 InNode NFunc r c _ -> (r, c, "an anonymous function")
920 InNode NCond r c _ -> (r, c, "an `if` expression")
921 InNode NThen r c _ -> (r, c, "an `if` expression")
922 InNode NElse r c _ -> (r, c, "an `if` expression")
923 -- TODO check if this is actually the best way to get error messages here
925 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
926 region = toRegion row col
928 Report.Report "MISSING EXPRESSION" region [] $
929 Report.toCodeSnippet source surroundings (Just region)
932 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
936 ["I","was","expecting","to","see","an","expression","like"
937 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
938 ,"Once","there","is","something","there,","I","can","probably"
939 ,"give","a","more","specific","hint!"
942 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
943 \ Or if I run into operators in unexpected spots. Point is, there are a\
944 \ couple ways I can get confused and give sort of weird advice!"
949 toCharReport source char row col
951 String string row col ->
952 toStringReport source string row col
954 Number number row col ->
955 toNumberReport source number row col
957 Space space row col ->
958 toSpaceReport source space row col
960 EndlessShader row col ->
962 region = toWiderRegion row col 6
964 Report.Report "ENDLESS SHADER" region [] $
965 Report.toCodeSnippet source region Nothing
967 D.reflow "I cannot find the end of this shader:"
969 D.reflow "Add a |] somewhere after this to end the shader."
972 ShaderProblem problem row col ->
974 region = toRegion row col
976 Report.Report "SHADER PROBLEM" region [] $
977 Report.toCodeSnippet source region Nothing
980 "I ran into a problem while parsing this GLSL block."
984 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
985 , D.indent 4 $ D.vcat $
986 map D.fromChars (filter (/="") (lines problem))
990 IndentOperatorRight op row col ->
992 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
993 region = toRegion row col
995 Report.Report "MISSING EXPRESSION" region [] $
996 Report.toCodeSnippet source surroundings (Just region)
999 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1004 ["You","can","just","put","anything","for","now,","like"
1005 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1006 ,"Once","there","is","something","there,","I","can","probably"
1007 ,"give","a","more","specific","hint!"
1011 "I may be getting confused by your indentation? The easiest way to make sure\
1012 \ this is not an indentation problem is to put the expression on the right of\
1013 \ the " ++ Name.toChars op ++ " operator on the same line."
1017 IndentMoreExpr _ _ ->
1018 error "TODO IndentMoreExpr"
1021toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
1022toCharReport source char row col =
1026 region = toRegion row col
1028 Report.Report "MISSING SINGLE QUOTE" region [] $
1029 Report.toCodeSnippet source region Nothing
1032 "I thought I was parsing a character, but I got to the end of\
1033 \ the line without seeing the closing single quote:"
1036 "Add a closing single quote here!"
1039 CharEscape escape ->
1040 toEscapeReport source escape row col
1042 CharNotString width ->
1044 region = toWiderRegion row col width
1046 Report.Report "NEEDS DOUBLE QUOTES" region [] $
1047 Report.toCodeSnippet source region Nothing
1049 "The following string uses single quotes:"
1052 [ "Please switch to double quotes instead:"
1054 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
1056 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
1057 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
1058 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
1059 \ individual characters."
1064toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
1065toStringReport source string row col =
1067 StringEndless_Single ->
1069 region = toRegion row col
1071 Report.Report "ENDLESS STRING" region [] $
1072 Report.toCodeSnippet source region Nothing
1075 "I got to the end of the line without seeing the closing double quote:"
1079 ["Strings","look","like",D.green "\"this\"","with","double"
1080 ,"quotes","on","each","end.","Is","the","closing","double"
1081 ,"quote","missing","in","your","code?"
1083 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
1087 StringEndless_Multi ->
1089 region = toWiderRegion row col 3
1091 Report.Report "ENDLESS STRING" region [] $
1092 Report.toCodeSnippet source region Nothing
1095 "I cannot find the end of this multi-line string:"
1098 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
1099 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
1103 StringEscape escape ->
1104 toEscapeReport source escape row col
1107toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1108toEscapeReport source escape row col =
1112 region = toWiderRegion row col 2
1114 Report.Report "UNKNOWN ESCAPE" region [] $
1115 Report.toCodeSnippet source region Nothing
1118 "Backslashes always start escaped characters, but I do not recognize this one:"
1122 "Valid escape characters include:"
1123 , D.dullyellow $ D.indent 4 $ D.vcat $
1133 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1135 "The last style lets encode ANY character by its Unicode code\
1136 \ point. That means \\u{0009} and \\t are the same. You can use\
1137 \ that style for anything not covered by the other six escapes!"
1141 BadUnicodeFormat width ->
1143 region = toWiderRegion row col width
1145 Report.Report "BAD UNICODE ESCAPE" region [] $
1146 Report.toCodeSnippet source region Nothing
1149 "I ran into an invalid Unicode escape:"
1153 "Here are some examples of valid Unicode escapes:"
1154 , D.dullyellow $ D.indent 4 $ D.vcat $
1161 "Notice that the code point is always surrounded by curly braces.\
1162 \ Maybe you are missing the opening or closing curly brace?"
1165 BadUnicodeCode width ->
1167 region = toWiderRegion row col width
1169 Report.Report "BAD UNICODE ESCAPE" region [] $
1170 Report.toCodeSnippet source region Nothing
1173 "This is not a valid code point:"
1176 "The valid code points are between 0 and 10FFFF inclusive."
1179 BadUnicodeLength width numDigits badCode ->
1181 region = toWiderRegion row col width
1183 Report.Report "BAD UNICODE ESCAPE" region [] $
1184 Report.toCodeSnippet source region Nothing $
1185 if numDigits < 4 then
1188 "Every code point needs at least four digits:"
1191 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1192 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1194 D.fillSep ["Try",D.green suggestion,"instead?"]
1200 "This code point has too many digits:"
1203 ["Valid","code","points","are","between"
1204 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1205 ,"so","try","trimming","any","leading","zeros","until"
1206 ,"you","have","between","four","and","six","digits."
1211toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1212toNumberReport source number row col =
1214 region = toRegion row col
1218 Report.Report "WEIRD NUMBER" region [] $
1219 Report.toCodeSnippet source region Nothing
1222 "I thought I was reading a number, but I ran into some weird stuff here:"
1226 "I recognize numbers in the following formats:"
1227 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1229 "So is there a way to write it like one of those?"
1234 Report.Report "WEIRD NUMBER" region [] $
1235 Report.toCodeSnippet source region Nothing
1238 "Numbers cannot end with a dot like this:"
1241 ["Switching","to",D.green (D.fromChars (show int))
1242 ,"or",D.green (D.fromChars (show int ++ ".0"))
1243 ,"will","work","though!"
1248 Report.Report "WEIRD HEXIDECIMAL" region [] $
1249 Report.toCodeSnippet source region Nothing
1252 "I thought I was reading a hexidecimal number until I got here:"
1256 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1257 \ only recognize things like this:"
1258 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1262 NumberNoLeadingZero ->
1263 Report.Report "LEADING ZEROS" region [] $
1264 Report.toCodeSnippet source region Nothing
1267 "I do not accept numbers with leading zeros:"
1271 "Just delete the leading zeros and it should work!"
1273 "Some languages let you to specify octal numbers by adding a leading zero.\
1274 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1275 \ that, but others probably want it to equal 111. Either path is going to\
1276 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1282toOperatorReport :: Code.Source -> Context -> Operator -> Row -> Col -> Report.Report
1283toOperatorReport source context operator row col =
1287 region = toRegion row col
1289 Report.Report "UNEXPECTED SYMBOL" region [] $
1290 Report.toCodeSnippet source region Nothing
1292 "I was not expecting this dot:"
1295 "Dots are for record access and decimal points, so\
1296 \ they cannot float around on their own. Maybe\
1297 \ there is some extra whitespace?"
1302 region = toRegion row col
1304 Report.Report "UNEXPECTED SYMBOL" region [] $
1305 Report.toCodeSnippet source region Nothing
1308 "I was not expecting this vertical bar:"
1311 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
1316 region = toWiderRegion row col 2
1318 Report.Report "UNEXPECTED ARROW" region [] $
1319 Report.toCodeSnippet source region Nothing $
1320 if error "TODO inCase" then
1323 "I was not expecting to see an arrow here:"
1328 "I think I am parsing a `case` expression right now, so it makes sense to\
1329 \ see arrows around here. This one is confusing me though!"
1332 "I may be getting confused by the indentation. Every pattern in a `case` must be\
1333 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
1334 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
1335 \ indented too far?"
1342 "I was not expecting an arrow here:"
1345 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
1346 \ you want > or >= instead?"
1351 region = toRegion row col
1352 name = getDefName context
1354 Report.Report "UNEXPECTED EQUALS" region [] $
1355 Report.toCodeSnippet source region Nothing
1358 "I was not expecting to see this equals sign:"
1362 D.reflow "Maybe you want == instead? To check if two values are equal?"
1365 if isWithin NRecord context then
1366 "Records look like { x = 3, y = 4 } with the equals sign right\
1367 \ after the field name. So maybe you forgot a comma?"
1369 "I may be getting confused by your indentation. Is this supposed to be part of\
1370 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1371 \ the problem may be a bit before the equals sign. I need all definitions to\
1372 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1373 \ this new definition is indented a bit too much."
1379 region = toRegion row col
1380 name = getDefName context
1382 Report.Report "UNEXPECTED SYMBOL" region [] $
1383 Report.toCodeSnippet source region Nothing $
1386 "I was not expecting to run into the \"has type\" symbol here:"
1391 ["Maybe","you","want",D.green "::","instead?"
1392 ,"To","put","something","on","the","front","of","a","list?"
1395 "The single colon is reserved for type annotations and record types, but I think\
1396 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
1399 "I may be getting confused by your indentation. Is this supposed to be part of\
1400 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1401 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
1402 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1403 \ this new definition is indented a bit too much."
1412toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
1413toIfReport source context if_ startRow startCol =
1415 IfSpace space row col ->
1416 toSpaceReport source space row col
1420 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1421 region = toRegion row col
1423 Report.Report "UNFINISHED IF" region [] $
1424 Report.toCodeSnippet source surroundings (Just region)
1427 "I was expecting to see more of this `if` expression, but I got stuck here:"
1430 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1436 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1437 region = toRegion row col
1439 Report.Report "UNFINISHED IF" region [] $
1440 Report.toCodeSnippet source surroundings (Just region)
1443 "I was expecting to see more of this `if` expression, but I got stuck here:"
1446 ["I","was","expecting","to","see","the",D.green "else","keyword","next."
1450 IfElseBranchStart row col ->
1452 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1453 region = toRegion row col
1455 Report.Report "UNFINISHED IF" region [] $
1456 Report.toCodeSnippet source surroundings (Just region)
1459 "I just saw the start of an `else` branch, but then I got stuck here:"
1462 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1465 IfCondition expr row col ->
1466 toExprReport source (InNode NCond startRow startCol context) expr row col
1468 IfThenBranch expr row col ->
1469 toExprReport source (InNode NThen startRow startCol context) expr row col
1471 IfElseBranch expr row col ->
1472 toExprReport source (InNode NElse startRow startCol context) expr row col
1474 IfIndentCondition row col ->
1476 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1477 region = toRegion row col
1479 Report.Report "UNFINISHED IF" region [] $
1480 Report.toCodeSnippet source surroundings (Just region)
1483 "I was expecting to see more of this `if` expression, but I got stuck here:"
1487 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
1488 ,"that","evaluates","to","True","or","False."
1491 "I can be confused by indentation. Maybe something is not indented enough?"
1495 IfIndentThen row col ->
1497 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1498 region = toRegion row col
1500 Report.Report "UNFINISHED IF" region [] $
1501 Report.toCodeSnippet source surroundings (Just region)
1504 "I was expecting to see more of this `if` expression, but I got stuck here:"
1508 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1511 "I can be confused by indentation. Maybe something is not indented enough?"
1515 IfIndentThenBranch row col ->
1517 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1518 region = toRegion row col
1520 Report.Report "UNFINISHED IF" region [] $
1521 Report.toCodeSnippet source surroundings (Just region)
1524 "I got stuck after the start of this `then` branch:"
1528 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1530 "I can be confused by indentation, so if the `then` branch is already\
1531 \ present, it may not be indented enough for me to recognize it."
1535 IfIndentElseBranch row col ->
1537 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1538 region = toRegion row col
1540 Report.Report "UNFINISHED IF" region [] $
1541 Report.toCodeSnippet source surroundings (Just region)
1544 "I got stuck after the start of this `else` branch:"
1548 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1550 "I can be confused by indentation, so if the `else` branch is already\
1551 \ present, it may not be indented enough for me to recognize it."
1555 IfIndentElse row col ->
1557 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1558 region = toRegion row col
1560 Report.Report "UNFINISHED IF" region [] $
1561 Report.toCodeSnippet source surroundings (Just region)
1564 "I was expecting to see an `else` branch after this:"
1568 "I know what to do when the condition is `True`, but not when it is `False`."
1570 ["Add","an",D.green "else","branch","to","handle","that","scenario!"]
1579toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
1580toRecordReport source context record startRow startCol =
1582 RecordOpen row col ->
1584 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1585 region = toRegion row col
1587 Report.Report "UNFINISHED PARENTHESES" region [] $
1588 Report.toCodeSnippet source surroundings (Just region)
1591 "I was expecting to see a closing curly brace next, but I got stuck here:"
1594 [ D.fillSep ["Try","adding","a",D.dullyellow "}","to","see","if","that","helps?"]
1596 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1597 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1598 \ parenthesis?) that is confusing me."
1602 RecordEnd row col ->
1604 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1605 region = toRegion row col
1607 Report.Report "UNFINISHED PARENTHESES" region [] $
1608 Report.toCodeSnippet source surroundings (Just region)
1611 "I was expecting to see a closing curly brace next, but I got stuck here:"
1614 [ D.fillSep ["Try","adding","a",D.dullyellow "}","to","see","if","that","helps?"]
1616 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1617 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1618 \ parenthesis?) that is confusing me."
1622 RecordField row col ->
1624 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1625 region = toRegion row col
1627 Report.Report "UNFINISHED RECORD" region [] $
1628 Report.toCodeSnippet source surroundings (Just region)
1631 "I am partway through parsing a record, but I got stuck after that last comma:"
1633 addNoteForRecordError $
1635 "Trailing commas are not allowed in records, so I was expecting to see another\
1636 \ record field defined next. If you are done defining the record, the fix may\
1637 \ be to delete that last comma?"
1640 RecordEquals row col ->
1642 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1643 region = toRegion row col
1645 Report.Report "UNFINISHED RECORD" region [] $
1646 Report.toCodeSnippet source surroundings (Just region)
1649 "I am partway through parsing a record, but I got stuck here:"
1651 addNoteForRecordError $
1653 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
1654 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
1658 RecordExpr expr row col ->
1659 toExprReport source (InNode NRecord startRow startCol context) expr row col
1661 RecordSpace space row col ->
1662 toSpaceReport source space row col
1664 RecordIndentOpen row col ->
1666 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1667 region = toRegion row col
1669 Report.Report "UNFINISHED RECORD" region [] $
1670 Report.toCodeSnippet source surroundings (Just region)
1673 "I just saw the opening curly brace of a record, but then I got stuck here:"
1675 addNoteForRecordIndentError $
1677 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
1678 ,"Try","defining","some","fields","of","your","own?"
1682 RecordIndentEnd row col ->
1684 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1685 region = toRegion row col
1687 Report.Report "UNFINISHED RECORD" region [] $
1688 Report.toCodeSnippet source surroundings (Just region)
1691 "I was expecting to see a closing curly brace next:"
1693 addNoteForRecordIndentError $
1695 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
1699 RecordIndentField row col ->
1701 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1702 region = toRegion row col
1704 Report.Report "UNFINISHED RECORD" region [] $
1705 Report.toCodeSnippet source surroundings (Just region)
1708 "I am partway through parsing a record, but I got stuck after that last comma:"
1710 addNoteForRecordError $
1712 "Trailing commas are not allowed in records, so the fix may be to\
1713 \ delete that last comma? Or maybe you were in the middle of defining\
1714 \ an additional field?"
1717 RecordIndentEquals row col ->
1719 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1720 region = toRegion row col
1722 Report.Report "UNFINISHED RECORD" region [] $
1723 Report.toCodeSnippet source surroundings (Just region)
1726 "I am partway through parsing a record. I just saw a record\
1727 \ field, so I was expecting to see an equals sign next:"
1729 addNoteForRecordIndentError $
1731 ["Try","putting","an",D.green "=","followed","by","an","expression?"
1735 RecordIndentExpr row col ->
1737 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1738 region = toRegion row col
1740 Report.Report "UNFINISHED RECORD" region [] $
1741 Report.toCodeSnippet source surroundings (Just region)
1744 "I am partway through parsing a record, and I was expecting to run into an expression next:"
1746 addNoteForRecordIndentError $
1748 ["Try","putting","something,","like"
1749 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
1754addNoteForRecordError :: D.Doc -> D.Doc
1755addNoteForRecordError normalRecommendation =
1757 normalRecommendation
1760 "If you are trying to define a record across multiple lines, I recommend using this format:"
1761 , D.indent 4 $ D.vcat $
1762 [ "{ name = \"Alice\""
1768 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1769 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1770 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1774addNoteForRecordIndentError :: D.Doc -> D.Doc
1775addNoteForRecordIndentError normalRecommendation =
1777 normalRecommendation
1780 "I may be confused by indentation. For example, if you are trying to define\
1781 \ a record across multiple lines, I recommend using this format:"
1782 , D.indent 4 $ D.vcat $
1789 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1790 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1791 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1799toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
1800toTupleReport source context tuple startRow startCol =
1802 TupleExpr expr row col ->
1803 toExprReport source (InNode NParens startRow startCol context) expr row col
1805 TupleSpace space row col ->
1806 toSpaceReport source space row col
1810 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1811 region = toRegion row col
1813 Report.Report "UNFINISHED PARENTHESES" region [] $
1814 Report.toCodeSnippet source surroundings (Just region)
1817 "I was expecting to see a closing parentheses next, but I got stuck here:"
1820 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
1822 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1823 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1824 \ square bracket?) that is confusing me."
1828 TupleOperatorClose row col ->
1830 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1831 region = toRegion row col
1833 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
1834 Report.toCodeSnippet source surroundings (Just region)
1836 D.reflow "I was expecting a closing parenthesis here:"
1839 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
1841 "I think I am parsing an operator function right now, so I am expecting to see\
1842 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
1847 TupleOperatorReserved operator row col ->
1849 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1850 region = toRegion row col
1852 Report.Report "UNEXPECTED SYMBOL" region [] $
1853 Report.toCodeSnippet source surroundings (Just region)
1856 "I ran into an unexpected symbol here:"
1860 OpDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
1861 OpPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
1862 OpArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
1863 OpEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
1864 OpHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
1867 TupleIndentExpr1 row col ->
1869 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1870 region = toRegion row col
1872 Report.Report "UNFINISHED PARENTHESES" region [] $
1873 Report.toCodeSnippet source surroundings (Just region)
1876 "I just saw an open parenthesis, so I was expecting to see an expression next."
1880 ["Something","like",D.dullyellow "(4 + 5)","or"
1881 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
1882 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
1885 "I can get confused by indentation in cases like this, so\
1886 \ maybe you have an expression but it is not indented enough?"
1890 TupleIndentExprN row col ->
1892 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1893 region = toRegion row col
1895 Report.Report "UNFINISHED TUPLE" region [] $
1896 Report.toCodeSnippet source surroundings (Just region)
1899 "I think I am in the middle of parsing a tuple. I just saw a comma, so I was expecting to see expression next."
1903 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
1904 ,D.dullyellow "(\"Tom\",42)" <> ","
1905 ,"so","I","think","there","is","an","expression","missing","here?"
1908 "I can get confused by indentation in cases like this, so\
1909 \ maybe you have an expression but it is not indented enough?"
1913 TupleIndentEnd row col ->
1915 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1916 region = toRegion row col
1918 Report.Report "UNFINISHED PARENTHESES" region [] $
1919 Report.toCodeSnippet source surroundings (Just region)
1922 "I was expecting to see a closing parenthesis next:"
1925 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
1927 "I can get confused by indentation in cases like this, so\
1928 \ maybe you have a closing parenthesis but it is not indented enough?"
1933toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
1934toListReport source context list startRow startCol =
1936 ListSpace space row col ->
1937 toSpaceReport source space row col
1941 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1942 region = toRegion row col
1944 Report.Report "UNFINISHED LIST" region [] $
1945 Report.toCodeSnippet source surroundings (Just region)
1948 "I was expecting to see a closing square bracket next, but I got stuck here:"
1951 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
1953 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1954 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1955 \ parenthesis?) that is confusing me."
1959 ListExpr expr row col ->
1963 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
1964 region = toRegion r c
1966 Report.Report "UNFINISHED LIST" region [] $
1967 Report.toCodeSnippet source surroundings (Just region)
1970 "I was expecting to see another list entry after that last comma:"
1974 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
1976 "I recommend using the following format for lists that span multiple lines:"
1977 , D.indent 4 $ D.vcat $
1984 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
1985 \ This style can be jarring for people coming from C-like syntax, but folks generally\
1986 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1991 toExprReport source (InNode NList startRow startCol context) expr row col
1995 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1996 region = toRegion row col
1998 Report.Report "UNFINISHED LIST" region [] $
1999 Report.toCodeSnippet source surroundings (Just region)
2002 "I was expecting to see a closing square bracket next, but I got stuck here:"
2005 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
2007 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
2008 \ unexpectedly. So there may be some other syntax trouble (like an extra\
2009 \ parenthesis?) that is confusing me."
2013 ListIndentOpen row col ->
2015 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2016 region = toRegion row col
2018 Report.Report "UNFINISHED LIST" region [] $
2019 Report.toCodeSnippet source surroundings (Just region)
2022 "I cannot find the end of this list:"
2026 ["You","could","change","it","to","something","like"
2027 ,D.dullyellow "[3,4,5]"
2029 ,D.dullyellow "[]" <> "."
2030 ,"Anything","where","there","is","an","open","and","close","square","brace,"
2031 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
2034 "I may be confused by indentation. For example, if you are trying to define\
2035 \ a list across multiple lines, I recommend using this format:"
2036 , D.indent 4 $ D.vcat $
2043 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2044 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2045 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2049 ListIndentEnd row col ->
2051 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2052 region = toRegion row col
2054 Report.Report "UNFINISHED LIST" region [] $
2055 Report.toCodeSnippet source surroundings (Just region)
2058 "I cannot find the end of this list:"
2062 ["You","can","just","add","a","closing",D.dullyellow "]"
2063 ,"right","here,","and","I","will","be","all","set!"
2066 "I may be confused by indentation. For example, if you are trying to define\
2067 \ a list across multiple lines, I recommend using this format:"
2068 , D.indent 4 $ D.vcat $
2075 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2076 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2077 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2081 ListIndentExpr row col ->
2083 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2084 region = toRegion row col
2086 Report.Report "UNFINISHED LIST" region [] $
2087 Report.toCodeSnippet source surroundings (Just region)
2090 "I was expecting to see another list entry after this comma:"
2094 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2096 "I recommend using the following format for lists that span multiple lines:"
2097 , D.indent 4 $ D.vcat $
2104 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2105 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2106 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2111toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
2112toFuncReport source context func startRow startCol =
2114 FuncSpace space row col ->
2115 toSpaceReport source space row col
2117 FuncArg pattern row col ->
2118 error "TODO FuncArg" pattern row col
2120 FuncBody expr row col ->
2121 toExprReport source (InNode NFunc startRow startCol context) expr row col
2123 FuncArrow row col ->
2125 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2126 region = toRegion row col
2128 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2129 Report.toCodeSnippet source surroundings (Just region)
2132 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2135 ["The","syntax","for","anonymous","functions","is"
2136 ,D.dullyellow "(\\x -> x + 1)"
2137 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2141 FuncIndentArg row col ->
2143 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2144 region = toRegion row col
2146 Report.Report "MISSING ARGUMENT" region [] $
2147 Report.toCodeSnippet source surroundings (Just region)
2150 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
2154 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
2155 ,"Anything","that","starts","with","a","lower","case","letter!"
2158 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
2159 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
2160 \ like a better idea at the time!"
2164 FuncIndentArrow row col ->
2166 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2167 region = toRegion row col
2169 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2170 Report.toCodeSnippet source surroundings (Just region)
2173 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2177 ["The","syntax","for","anonymous","functions","is"
2178 ,D.dullyellow "(\\x -> x + 1)"
2179 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2182 "It is possible that I am confused about indetation! I generally recommend\
2183 \ switching to named functions if the definition cannot fit inline nicely, so\
2184 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2185 \ the whole thing out into a named function. Things tend to be clearer that way!"
2189 FuncIndentBody row col ->
2191 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2192 region = toRegion row col
2194 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2195 Report.toCodeSnippet source surroundings (Just region)
2198 "I was expecting to see the body of your anonymous function next:"
2202 ["The","syntax","for","anonymous","functions","is"
2203 ,D.dullyellow "(\\x -> x + 1)"
2204 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
2207 "It is possible that I am confused about indetation! I generally recommend\
2208 \ switching to named functions if the definition cannot fit inline nicely, so\
2209 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2210 \ the whole thing out into a named function. Things tend to be clearer that way!"
2219 CommentOnNothing region ->
2220 Report.Report "STRAY COMMENT" region [] $
2221 Report.toCodeSnippet source region Nothing
2223 "This documentation comment is not followed by anything."
2226 "All documentation comments need to be right above the declaration they\
2227 \ describe. Maybe some code got deleted or commented out by accident? Or\
2228 \ maybe this comment is here by accident?"
2231 UnexpectedPort region ->
2232 Report.Report "UNEXPECTED PORTS" region [] $
2233 Report.toCodeSnippet source region Nothing
2236 "You are declaring ports in a normal module."
2240 ["Switch","this","to","say",D.green "port module","instead,"
2241 ,"marking","that","this","module","contains","port","declarations."
2244 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
2246 "to learn the syntax and how to use it effectively."
2251 Report.Report "NO PORTS" region [] $
2252 Report.toCodeSnippet source region Nothing
2255 "This module does not declare any ports, but it says it will:"
2258 ["Switch","this","to",D.green "module"
2259 ,"and","you","should","be","all","set!"
2263 ParseError row col context expectation ->
2265 pos = A.Position row col
2266 region = A.Region pos pos
2271 Report.Report "EXPECTING DOC COMMENT" region [] $
2272 Report.toCodeSnippet source region Nothing
2275 "I was expecting a doc comment here:"
2278 "Check out" "TODO" "for examples of doc comments."
2284 Report.Report "EXPECTING PRECEDENCE" region [] $
2285 Report.toCodeSnippet source region Nothing
2288 "I was expecting the precedence here:"
2291 "I need a single digit between 0 and 9 inclusive."
2295 Report.Report "EXPECTING AN OPERATOR" region [] $
2296 Report.toCodeSnippet source region Nothing
2299 "I was expecting an operator here:"
2302 [ D.reflow "Some of the most common operators are:"
2303 , D.indent 4 $ D.vcat ["+","-","*","&&","||"]
2304 , D.reflow "Something like that!"
2309 Report.Report "EXPECTING A WILDCARD" region [] $
2310 Report.toCodeSnippet source region Nothing
2313 "I was expecting a _ here:"
2316 "An underscore indicates that “I do not care about this value” and is\
2317 \ called a wildcard pattern because it will match with any type of values."
2320 WildcardNotVar startCol endCol ->
2323 A.Region (A.Position row startCol) (A.Position row endCol)
2325 Report.Report "INVALID PATTERN" badRegion [] $
2326 Report.toCodeSnippet source badRegion Nothing
2329 "I was expecting to see an underscore without any additional characters:"
2332 "There are two options. Either (1) remove the extra characters and ignore the\
2333 \ value or (2) remove the starting underscore to give the value a normal name."
2339 Report.Report "INVALID PATTERN" region [] $
2340 Report.toCodeSnippet source region Nothing
2343 "I cannot pattern match with floating point numbers:"
2346 "Equality on floats can be unreliable, so you usually want to check that they\
2347 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
2351 Report.Report "EXPECTING A FIELD NAME" region [] $
2352 Report.toCodeSnippet source region Nothing
2355 "I was expecting a field name here:"
2358 ["A","name","like",D.dullyellow "id" <> ",",D.dullyellow "status" <> ","
2359 ,"or","whatever","field","you","want","to","access."
2365 MatchingName name ->
2366 Report.Report "EXPECTING A DEFINITION" region [] $
2367 Report.toCodeSnippet source region Nothing
2370 "I just saw the type annotation for `" ++ Name.toChars name
2371 ++ "` so I was expecting to see its definition here:"
2374 "Type annotations always appear directly above the relevant\
2375 \ definition, without anything else (even doc comments) in between."
2381 TypeWithBadDefinition region annName defName ->
2382 Report.Report "ANNOTATION MISMATCH" region [] $
2383 Report.toCodeSnippet source region Nothing
2386 "I see a `" <> Name.toChars annName
2387 <> "` annotation, but it is followed by a `"
2388 <> Name.toChars defName <> "` definition."
2391 ["The","annotation","and","definition","names","must","match!"
2392 ,"Is","there","a","typo","between"
2393 , D.dullyellow (D.fromName annName)
2395 , D.dullyellow (D.fromName defName) <> "?"
2403contextToString :: String -> String -> ContextStack -> String
2404contextToString defaultString prefixString stack =
2409 (context, _) : rest ->
2410 let anchor = getAnchor rest in
2413 ExprIf -> "an `if` expression" <> anchor
2414 ExprLet -> "a `let` expression" <> anchor
2415 ExprFunc -> "an anonymous function" <> anchor
2416 ExprCase -> "a `case` expression" <> anchor
2417 ExprList -> "a list" <> anchor
2418 ExprTuple -> "an expression (in parentheses)" <> anchor
2419 ExprRecord -> "a record" <> anchor
2420 Definition name -> Name.toChars name <> "'s definition"
2421 Annotation name -> Name.toChars name <> "'s type annotation"
2422 TypeTuple -> "a type (in parentheses)" <> anchor
2423 TypeRecord -> "a record type" <> anchor
2424 PatternList -> "a list pattern" <> anchor
2425 PatternTuple -> "a pattern (in parentheses)" <> anchor
2426 PatternRecord -> "a record pattern" <> anchor
2427 Module -> "a module declaration"
2428 Import -> "an import"
2429 TypeUnion -> "a union type"
2430 TypeAlias -> "a type alias"
2431 Infix -> "an infix declaration"
2432 Port -> "a port declaration"
2435getAnchor :: ContextStack -> String
2441 (context, _) : rest ->
2444 " in " <> Name.toChars name <> "'s definition"
2447 " 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