1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Syntax
47import Prelude hiding (Char, String)
48import qualified Data.Char as Char
49import qualified Data.Name as Name
50import Data.Word (Word16)
51import Numeric (showHex)
53import qualified Elm.ModuleName as ModuleName
54import Parse.Primitives (Row, Col)
55import Parse.Symbol (BadOperator(..))
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 | ImportIndentAlias Row Col
109 | ImportIndentExposingList Row Col
113 | Declarations Decl Row Col
117 = ExposingSpace Space Row Col
118 | ExposingStart Row Col
119 | ExposingValue Row Col
120 | ExposingOperator Row Col
121 | ExposingOperatorReserved BadOperator Row Col
122 | ExposingOperatorRightParen Row Col
123 | ExposingEnd Row Col
125 | ExposingTypePrivacy Row Col
126 | ExposingTypePrivacyDots Row Col
127 | ExposingTypePrivacyEnd Row Col
129 | ExposingIndentEnd Row Col
130 | ExposingIndentValue Row Col
131 | ExposingIndentValueEnd Row Col
132 | ExposingIndentTypePrivacy Row Col
133 | ExposingIndentTypePrivacyDots Row Col
134 | ExposingIndentTypePrivacyEnd Row Col
143 | DeclSpace Space Row Col
146 | DeclType DeclType Row Col
147 | DeclDef Name.Name DeclDef Row Col
149 | DeclFreshLineStart Row Col
150 | DeclFreshLineAfterDocComment Row Col
154 = DeclDefSpace Space Row Col
155 | DeclDefEquals Row Col
156 | DeclDefType Type Row Col
157 | DeclDefArg Pattern Row Col
158 | DeclDefBody Expr Row Col
159 | DeclDefNameRepeat Row Col
160 | DeclDefNameMatch Name.Name Row Col
162 | DeclDefIndentType Row Col
163 | DeclDefIndentEquals Row Col
164 | DeclDefIndentBody Row Col
166 | DeclDefFreshLineAfterType Row Col
170 = PortSpace Space Row Col
173 | PortType Type Row Col
174 | PortIndentName Row Col
175 | PortIndentColon Row Col
176 | PortIndentType Row Col
184 = DT_Space Space Row Col
186 | DT_Alias TypeAlias Row Col
187 | DT_Union CustomType Row Col
189 | DT_IndentName Row Col
193 = AliasSpace Space Row Col
195 | AliasEquals Row Col
196 | AliasBody Type Row Col
198 | AliasIndentEquals Row Col
199 | AliasIndentBody Row Col
203 = CT_Space Space Row Col
208 | CT_VariantArg Type Row Col
210 | CT_IndentEquals Row Col
211 | CT_IndentBar Row Col
212 | CT_IndentAfterBar Row Col
213 | CT_IndentAfterEquals Row Col
225 | Record Record Row Col
226 | Tuple Tuple Row Col
231 | OperatorRight Name.Name Row Col
232 | OperatorReserved BadOperator Row Col
236 | String String Row Col
237 | Number Number Row Col
238 | Space Space Row Col
239 | EndlessShader Row Col
240 | ShaderProblem [Char.Char] Row Col
241 | IndentOperatorRight Name.Name Row Col
242 | IndentMoreExpr Row Col
248 | RecordField Row Col
249 | RecordEquals Row Col
250 | RecordExpr Expr Row Col
251 | RecordSpace Space Row Col
253 | RecordIndentOpen Row Col
254 | RecordIndentEnd Row Col
255 | RecordIndentField Row Col
256 | RecordIndentEquals Row Col
257 | RecordIndentExpr Row Col
261 = TupleExpr Expr Row Col
262 | TupleSpace Space Row Col
264 | TupleOperatorClose Row Col
265 | TupleOperatorReserved BadOperator Row Col
267 | TupleIndentExpr1 Row Col
268 | TupleIndentExprN Row Col
269 | TupleIndentEnd Row Col
273 = ListSpace Space Row Col
275 | ListExpr Expr Row Col
278 | ListIndentOpen Row Col
279 | ListIndentEnd Row Col
280 | ListIndentExpr Row Col
284 = FuncSpace Space Row Col
285 | FuncArg Pattern Row Col
286 | FuncBody Expr Row Col
289 | FuncIndentArg Row Col
290 | FuncIndentArrow Row Col
291 | FuncIndentBody Row Col
295 = CaseSpace Space Row Col
297 | CasePattern Pattern Row Col
299 | CaseExpr Expr Row Col
300 | CaseBranch Expr Row Col
302 | CaseIndentOf Row Col
303 | CaseIndentExpr Row Col
304 | CaseIndentPattern Row Col
305 | CaseIndentArrow Row Col
306 | CaseIndentBranch Row Col
307 | CasePatternAlignment Word16 Row Col
311 = IfSpace Space Row Col
314 | IfElseBranchStart Row Col
316 | IfCondition Expr Row Col
317 | IfThenBranch Expr Row Col
318 | IfElseBranch Expr Row Col
320 | IfIndentCondition Row Col
321 | IfIndentThen Row Col
322 | IfIndentThenBranch Row Col
323 | IfIndentElseBranch Row Col
324 | IfIndentElse Row Col
328 = LetSpace Space Row Col
330 | LetDefAlignment Word16 Row Col
332 | LetDef Name.Name Def Row Col
333 | LetDestruct Destruct Row Col
334 | LetBody Expr Row Col
335 | LetIndentDef Row Col
336 | LetIndentIn Row Col
337 | LetIndentBody Row Col
341 = DefSpace Space Row Col
342 | DefType Type Row Col
343 | DefNameRepeat Name.Name Row Col
344 | DefNameMatch Name.Name Name.Name Row Col
345 | DefArg Pattern Row Col
347 | DefBody Expr Row Col
348 | DefIndentEquals Row Col
349 | DefIndentType Row Col
350 | DefIndentBody Row Col
351 | DefAlignment Word16 Row Col
355 = DestructSpace Space Row Col
356 | DestructPattern Pattern Row Col
357 | DestructEquals Row Col
358 | DestructBody Expr Row Col
359 | DestructIndentEquals Row Col
360 | DestructIndentBody Row Col
368 = PRecord PRecord Row Col
369 | PTuple PTuple Row Col
370 | PList PList Row Col
374 | PString String Row Col
375 | PNumber Number Row Col
378 | PWildcardNotVar Int Row Col
379 | PSpace Space Row Col
381 | PIndentStart Row Col
382 | PIndentAlias Row Col
386 = PRecordOpen Row Col
388 | PRecordField Row Col
389 | PRecordSpace Space Row Col
391 | PRecordIndentOpen Row Col
392 | PRecordIndentEnd Row Col
393 | PRecordIndentField Row Col
399 | PTupleExpr Pattern Row Col
400 | PTupleSpace Space Row Col
402 | PTupleIndentOpen Row Col
403 | PTupleIndentEnd Row Col
404 | PTupleIndentExpr Row Col
410 | PListExpr Pattern Row Col
411 | PListSpace Space Row Col
413 | PListIndentOpen Row Col
414 | PListIndentEnd Row Col
415 | PListIndentExpr Row Col
423 = TRecord TRecord Row Col
424 | TTuple TTuple Row Col
429 | TSpace Space Row Col
431 | TIndentStart Row Col
435 = TRecordOpen Row Col
438 | TRecordField Row Col
439 | TRecordColon Row Col
440 | TRecordType Type Row Col
442 | TRecordSpace Space Row Col
444 | TRecordIndentOpen Row Col
445 | TRecordIndentField Row Col
446 | TRecordIndentColon Row Col
447 | TRecordIndentType Row Col
448 | TRecordIndentEnd Row Col
454 | TTupleType Type Row Col
455 | TTupleSpace Space Row Col
457 | TTupleIndentOpen Row Col
458 | TTupleIndentType Row Col
459 | TTupleIndentEnd Row Col
469 | CharNotString Word16
473 = StringEndless_Single
474 | StringEndless_Multi
475 | StringEscape Escape
480 | BadUnicodeFormat Word16
481 | BadUnicodeCode Word16
482 | BadUnicodeLength Word16 Int Int
489 | NumberNoLeadingZero
498 | EndlessMultiComment
505toReport :: Code.Source -> Error -> Report.Report
508 ModuleNameUnspecified name ->
510 region = toRegion 1 1
512 Report.Report "MODULE NAME MISSING" region [] $
515 "I need the module name to be declared at the top of this file, like this:"
516 , D.indent 4 $ D.green $ D.fromChars $
517 "module " ++ ModuleName.toChars name ++ " exposing (..)"
519 "Try adding that as the first line of your file!"
521 "It is best to replace (..) with an explicit list of types and\
522 \ functions you want to expose. When you know a value is only used\
523 \ within this module, you can refactor without worrying about uses\
524 \ elsewhere. Limiting exposed values can also speed up compilation\
525 \ because I can skip a bunch of work if I see that the exposed API\
529 ModuleNameMismatch expectedName (A.At region actualName) ->
530 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
531 Code.toSnippet source region Nothing
533 "It looks like this module name is out of sync:"
537 "I need it to match the file path, so I was expecting it to see `"
538 ++ ModuleName.toChars expectedName
539 ++ "` here. Make the following change, and you should be all set!"
541 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
543 "I require that module names correspond to file paths. This makes it much\
544 \ easier to explore unfamiliar codebases! So if you want to keep the current\
545 \ module name, try renaming the file instead."
549 UnexpectedPort region ->
550 error "TODO UnexpectedPort" region
553 error "TODO NoPorts" region
556 toParseErrorReport source modul
559toParseErrorReport :: Code.Source -> Module -> Report.Report
560toParseErrorReport source modul =
562 ModuleSpace space row col ->
563 toSpaceReport source space row col
565 ModuleEndOfFile row col ->
567 region = toRegion row col
569 Report.Report "EXPECTING END OF FILE" region [] $
570 Code.toSnippet source region Nothing
573 "I was not expecting to see anything more here:"
576 "I think I have read all the declarations in the file and that there is nothing\
577 \ left to see, so whatever I am running into is confusing me a lot!"
581 error "TODO Module" row col
583 ModuleName row col ->
584 error "TODO ModuleName" row col
586 ModuleExposing row col ->
587 error "TODO ModuleExposing" row col
589 ModuleExposingList exposing row col ->
590 error "TODO ModuleExposingList" exposing row col
592 ModulePortModule row col ->
593 error "TODO ModulePortModule" row col
595 ModuleEffect row col ->
596 error "TODO ModuleEffect" row col
598 ModuleIndentStart row col ->
599 error "TODO ModuleIndentStart" row col
601 ModuleIndentName row col ->
602 error "TODO ModuleIndentName" row col
604 ModuleIndentExposing row col ->
605 error "TODO ModuleIndentExposing" row col
607 ModuleIndentExposingList row col ->
608 error "TODO ModuleIndentExposingList" row col
610 ModuleIndentPortModule row col ->
611 error "TODO ModuleIndentPortModule" row col
613 FreshLineModuleStart row col ->
614 error "TODO FreshLineModuleStart" row col
616 FreshLineAfterModuleLine row col ->
617 error "TODO FreshLineAfterModuleLine" row col
619 FreshLineAfterDocComment row col ->
620 error "TODO FreshLineAfterDocComment" row col
622 ImportStart row col ->
623 toImportReport source row col
625 ImportName row col ->
627 region = toRegion row col
629 Report.Report "EXPECTING IMPORT NAME" region [] $
630 Code.toSnippet source region Nothing
633 "I was parsing an `import` until I got stuck here:"
637 "I was expecting to see a module name next, like in these examples:"
638 , D.indent 4 $ D.vcat $
639 [ D.fillSep [D.blue "import","Dict"]
640 , D.fillSep [D.blue "import","Maybe"]
641 , D.fillSep [D.blue "import","Html.Attributes"]
642 , D.fillSep [D.blue "import","Json.Decode"]
645 "Notice that the module names all start with capital letters. That is required!"
650 toImportReport source row col
652 ImportAlias row col ->
654 region = toRegion row col
656 Report.Report "EXECTING IMPORT ALIAS" region [] $
657 Code.toSnippet source region Nothing
660 "I was parsing an `import` until I got stuck here:"
664 "I was expecting to see an alias next, like in these examples:"
665 , D.indent 4 $ D.vcat $
666 [ D.fillSep [D.blue "import","Html.Attributes",D.blue "as","Attr"]
667 , D.fillSep [D.blue "import","WebGL.Texture",D.blue "as","Texture"]
668 , D.fillSep [D.blue "import","Json.Decode",D.blue "as","D"]
671 "Notice that the alias always starts with a capital letter. That is required!"
675 ImportExposing row col ->
676 toImportReport source row col
678 ImportExposingList exposing row col ->
679 error "TODO ImportExposingList" exposing row col
682 toImportReport source row col
684 ImportIndentName row col ->
685 toImportReport source row col
687 ImportIndentAlias row col ->
688 toImportReport source row col
690 ImportIndentExposingList row col ->
692 region = toRegion row col
694 Report.Report "UNFINISHED IMPORT" region [] $
695 Code.toSnippet source region Nothing
698 "I was parsing an `import` until I got stuck here:"
702 "I was expecting to see the list of exposed values next. For example, here\
703 \ are two ways to expose values from the `Html` module:"
704 , D.indent 4 $ D.vcat $
705 [ D.fillSep [D.blue "import","Html",D.blue "exposing","(..)"]
706 , D.fillSep [D.blue "import","Html",D.blue "exposing","(Html, div, text)"]
709 "I generally recommend the second style. It is more explicit, making it\
710 \ much easier to figure out where values are coming from in large projects!"
716 region = toRegion row col
718 Report.Report "BAD INFIX" region [] $
719 Code.toSnippet source region Nothing
722 "Something went wrong in this infix operator declaration:"
725 "This feature is used by the @elm organization to define the\
726 \ languages built-in operators."
729 Declarations decl _ _ ->
730 toDeclarationsReport source decl
737toImportReport :: Code.Source -> Row -> Col -> Report.Report
738toImportReport source row col =
740 region = toRegion row col
742 Report.Report "UNFINISHED IMPORT" region [] $
743 Code.toSnippet source region Nothing
746 "I am partway through parsing an import, but I got stuck here:"
750 "Here are some examples of valid `import` declarations:"
751 , D.indent 4 $ D.vcat $
752 [ D.fillSep [D.blue "import","Html"]
753 , D.fillSep [D.blue "import","Html",D.blue "as","H"]
754 , D.fillSep [D.blue "import","Html",D.blue "exposing","(Html, div, text)"]
755 , D.fillSep [D.blue "import","Html",D.blue "as","H",D.blue "exposing","(..)"]
758 "You are probably trying to import a different module, but try to make it look like one of these examples!"
767toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
768toSpaceReport source space row col =
772 region = toRegion row col
774 Report.Report "NO TABS" region [] $
775 Code.toSnippet source region Nothing
778 "I ran into a tab, but tabs are not allowed in Elm files."
781 "Replace the tab with spaces."
784 EndlessMultiComment ->
786 region = toWiderRegion row col 2
788 Report.Report "ENDLESS COMMENT" region [] $
789 Code.toSnippet source region Nothing
792 "I cannot find the end of this multi-line comment:"
795 [ D.reflow "Add a -} somewhere after this to end the comment."
797 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
798 \ that happens to contain another comment. Like parentheses and curly braces,\
799 \ the start and end markers must always be balanced. Maybe that is the problem?"
808toRegion :: Row -> Col -> A.Region
811 pos = A.Position row col
816toWiderRegion :: Row -> Col -> Word16 -> A.Region
817toWiderRegion row col extra =
820 (A.Position row (col + extra))
823toDeclarationsReport :: Code.Source -> Decl -> Report.Report
824toDeclarationsReport source decl =
827 error "TODO DeclStart" row col
829 DeclSpace space row col ->
830 toSpaceReport source space row col
833 error "TODO Port" port row col
835 DeclType declType row col ->
836 error "TODO DeclType" declType row col
838 DeclDef name declDef row col ->
839 toDeclDefReport source name declDef row col
841 DeclFreshLineStart row col ->
842 error "TODO DeclFreshLineStart" row col
844 DeclFreshLineAfterDocComment row col ->
845 error "TODO DeclFreshLineAfterDocComment" row col
848toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
849toDeclDefReport source name declDef startRow startCol =
851 DeclDefSpace space row col ->
852 toSpaceReport source space row col
854 DeclDefEquals row col ->
855 error "TODO DeclDefEquals" row col
857 DeclDefType tipe row col ->
858 error "TODO DeclDefType" tipe row col
860 DeclDefArg pattern row col ->
861 error "TODO DeclDefArg" pattern row col
863 DeclDefBody expr row col ->
864 toExprReport source (InDef name startRow startCol) expr row col
866 DeclDefNameRepeat row col ->
867 error "TODO DeclDefNameRepeat" name row col
869 DeclDefNameMatch defName row col ->
870 error "TODO DeclDefNameMatch" name defName row col
872 DeclDefIndentType row col ->
873 error "TODO DeclDefIndentType" row col
875 DeclDefIndentEquals row col ->
876 error "TODO DeclDefIndentEquals" row col
878 DeclDefIndentBody row col ->
879 error "TODO DeclDefIndentBody" row col
881 DeclDefFreshLineAfterType row col ->
882 error "TODO DeclDefFreshLineAfterType" row col
890 = InNode Node Row Col Context
891 | InDef Name.Name Row Col
905getDefName :: Context -> Name.Name
908 InDef name _ _ -> name
909 InNode _ _ _ c -> getDefName c
912isWithin :: Node -> Context -> Bool
913isWithin desiredNode context =
916 InNode actualNode _ _ _ -> desiredNode == actualNode
923toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
924toExprReport source context expr startRow startCol =
933 toIfReport source context if_ row col
936 toListReport source context list row col
938 Record record row col ->
939 toRecordReport source context record row col
941 Tuple tuple row col ->
942 toTupleReport source context tuple row col
945 toFuncReport source context func row col
948 let region = toRegion row col in
949 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
950 Code.toSnippet source region Nothing
953 "I was expecting to see a record accessor here:"
956 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
957 ,"that","accesses","a","value","from","a","record."
962 let region = toRegion row col in
963 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
964 Code.toSnippet source region Nothing
967 "I am trying to parse a record accessor here:"
972 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
973 ,"that","accesses","a","value","from","a","record."
977 "Record field names must start with a lower case letter!"
981 OperatorRight op row col ->
982 let region = toRegion row col in
983 Report.Report "MISSING EXPRESSION" region [] $
984 Code.toSnippet source region Nothing
987 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
991 ["You","can","just","put","anything","for","now,","like"
992 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
993 ,"Once","there","is","something","there,","I","can","probably"
994 ,"give","a","more","specific","hint!"
997 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
998 \ Or if I run into operators in unexpected spots. Point is, there are a\
999 \ couple ways I can get confused and give sort of weird advice!"
1003 OperatorReserved operator row col ->
1004 toOperatorReport source context operator row col
1008 (contextRow, contextCol, aThing) =
1010 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
1011 InNode NRecord r c _ -> (r, c, "a record")
1012 InNode NParens r c _ -> (r, c, "some parentheses")
1013 InNode NList r c _ -> (r, c, "a list")
1014 InNode NFunc r c _ -> (r, c, "an anonymous function")
1015 InNode NCond r c _ -> (r, c, "an `if` expression")
1016 InNode NThen r c _ -> (r, c, "an `if` expression")
1017 InNode NElse r c _ -> (r, c, "an `if` expression")
1018 -- TODO check if this is actually the best way to get error messages here
1020 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
1021 region = toRegion row col
1023 Report.Report "MISSING EXPRESSION" region [] $
1024 Code.toSnippet source surroundings (Just region)
1027 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
1031 ["I","was","expecting","to","see","an","expression","like"
1032 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1033 ,"Once","there","is","something","there,","I","can","probably"
1034 ,"give","a","more","specific","hint!"
1037 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
1038 \ Or if I run into operators in unexpected spots. Point is, there are a\
1039 \ couple ways I can get confused and give sort of weird advice!"
1043 Char char row col ->
1044 toCharReport source char row col
1046 String string row col ->
1047 toStringReport source string row col
1049 Number number row col ->
1050 toNumberReport source number row col
1052 Space space row col ->
1053 toSpaceReport source space row col
1055 EndlessShader row col ->
1057 region = toWiderRegion row col 6
1059 Report.Report "ENDLESS SHADER" region [] $
1060 Code.toSnippet source region Nothing
1062 D.reflow "I cannot find the end of this shader:"
1064 D.reflow "Add a |] somewhere after this to end the shader."
1067 ShaderProblem problem row col ->
1069 region = toRegion row col
1071 Report.Report "SHADER PROBLEM" region [] $
1072 Code.toSnippet source region Nothing
1075 "I ran into a problem while parsing this GLSL block."
1079 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
1080 , D.indent 4 $ D.vcat $
1081 map D.fromChars (filter (/="") (lines problem))
1085 IndentOperatorRight op row col ->
1087 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1088 region = toRegion row col
1090 Report.Report "MISSING EXPRESSION" region [] $
1091 Code.toSnippet source surroundings (Just region)
1094 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1099 ["You","can","just","put","anything","for","now,","like"
1100 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1101 ,"Once","there","is","something","there,","I","can","probably"
1102 ,"give","a","more","specific","hint!"
1106 "I may be getting confused by your indentation? The easiest way to make sure\
1107 \ this is not an indentation problem is to put the expression on the right of\
1108 \ the " ++ Name.toChars op ++ " operator on the same line."
1112 IndentMoreExpr _ _ ->
1113 error "TODO IndentMoreExpr"
1120toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
1121toCharReport source char row col =
1125 region = toRegion row col
1127 Report.Report "MISSING SINGLE QUOTE" region [] $
1128 Code.toSnippet source region Nothing
1131 "I thought I was parsing a character, but I got to the end of\
1132 \ the line without seeing the closing single quote:"
1135 "Add a closing single quote here!"
1138 CharEscape escape ->
1139 toEscapeReport source escape row col
1141 CharNotString width ->
1143 region = toWiderRegion row col width
1145 Report.Report "NEEDS DOUBLE QUOTES" region [] $
1146 Code.toSnippet source region Nothing
1148 "The following string uses single quotes:"
1151 [ "Please switch to double quotes instead:"
1153 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
1155 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
1156 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
1157 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
1158 \ individual characters."
1167toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
1168toStringReport source string row col =
1170 StringEndless_Single ->
1172 region = toRegion row col
1174 Report.Report "ENDLESS STRING" region [] $
1175 Code.toSnippet source region Nothing
1178 "I got to the end of the line without seeing the closing double quote:"
1182 ["Strings","look","like",D.green "\"this\"","with","double"
1183 ,"quotes","on","each","end.","Is","the","closing","double"
1184 ,"quote","missing","in","your","code?"
1186 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
1190 StringEndless_Multi ->
1192 region = toWiderRegion row col 3
1194 Report.Report "ENDLESS STRING" region [] $
1195 Code.toSnippet source region Nothing
1198 "I cannot find the end of this multi-line string:"
1201 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
1202 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
1206 StringEscape escape ->
1207 toEscapeReport source escape row col
1214toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1215toEscapeReport source escape row col =
1219 region = toWiderRegion row col 2
1221 Report.Report "UNKNOWN ESCAPE" region [] $
1222 Code.toSnippet source region Nothing
1225 "Backslashes always start escaped characters, but I do not recognize this one:"
1229 "Valid escape characters include:"
1230 , D.dullyellow $ D.indent 4 $ D.vcat $
1240 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1242 "The last style lets encode ANY character by its Unicode code\
1243 \ point. That means \\u{0009} and \\t are the same. You can use\
1244 \ that style for anything not covered by the other six escapes!"
1248 BadUnicodeFormat width ->
1250 region = toWiderRegion row col width
1252 Report.Report "BAD UNICODE ESCAPE" region [] $
1253 Code.toSnippet source region Nothing
1256 "I ran into an invalid Unicode escape:"
1260 "Here are some examples of valid Unicode escapes:"
1261 , D.dullyellow $ D.indent 4 $ D.vcat $
1268 "Notice that the code point is always surrounded by curly braces.\
1269 \ Maybe you are missing the opening or closing curly brace?"
1272 BadUnicodeCode width ->
1274 region = toWiderRegion row col width
1276 Report.Report "BAD UNICODE ESCAPE" region [] $
1277 Code.toSnippet source region Nothing
1280 "This is not a valid code point:"
1283 "The valid code points are between 0 and 10FFFF inclusive."
1286 BadUnicodeLength width numDigits badCode ->
1288 region = toWiderRegion row col width
1290 Report.Report "BAD UNICODE ESCAPE" region [] $
1291 Code.toSnippet source region Nothing $
1292 if numDigits < 4 then
1295 "Every code point needs at least four digits:"
1298 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1299 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1301 D.fillSep ["Try",D.green suggestion,"instead?"]
1307 "This code point has too many digits:"
1310 ["Valid","code","points","are","between"
1311 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1312 ,"so","try","trimming","any","leading","zeros","until"
1313 ,"you","have","between","four","and","six","digits."
1322toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1323toNumberReport source number row col =
1325 region = toRegion row col
1329 Report.Report "WEIRD NUMBER" region [] $
1330 Code.toSnippet source region Nothing
1333 "I thought I was reading a number, but I ran into some weird stuff here:"
1337 "I recognize numbers in the following formats:"
1338 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1340 "So is there a way to write it like one of those?"
1345 Report.Report "WEIRD NUMBER" region [] $
1346 Code.toSnippet source region Nothing
1349 "Numbers cannot end with a dot like this:"
1352 ["Switching","to",D.green (D.fromChars (show int))
1353 ,"or",D.green (D.fromChars (show int ++ ".0"))
1354 ,"will","work","though!"
1359 Report.Report "WEIRD HEXIDECIMAL" region [] $
1360 Code.toSnippet source region Nothing
1363 "I thought I was reading a hexidecimal number until I got here:"
1367 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1368 \ only recognize things like this:"
1369 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1373 NumberNoLeadingZero ->
1374 Report.Report "LEADING ZEROS" region [] $
1375 Code.toSnippet source region Nothing
1378 "I do not accept numbers with leading zeros:"
1382 "Just delete the leading zeros and it should work!"
1384 "Some languages let you to specify octal numbers by adding a leading zero.\
1385 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1386 \ that, but others probably want it to equal 111. Either path is going to\
1387 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1397toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
1398toOperatorReport source context operator row col =
1402 region = toRegion row col
1404 Report.Report "UNEXPECTED SYMBOL" region [] $
1405 Code.toSnippet source region Nothing
1407 "I was not expecting this dot:"
1410 "Dots are for record access and decimal points, so\
1411 \ they cannot float around on their own. Maybe\
1412 \ there is some extra whitespace?"
1417 region = toRegion row col
1419 Report.Report "UNEXPECTED SYMBOL" region [] $
1420 Code.toSnippet source region Nothing
1423 "I was not expecting this vertical bar:"
1426 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
1431 region = toWiderRegion row col 2
1433 Report.Report "UNEXPECTED ARROW" region [] $
1434 Code.toSnippet source region Nothing $
1435 if error "TODO inCase" then
1438 "I was not expecting to see an arrow here:"
1443 "I think I am parsing a `case` expression right now, so it makes sense to\
1444 \ see arrows around here. This one is confusing me though!"
1447 "I may be getting confused by the indentation. Every pattern in a `case` must be\
1448 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
1449 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
1450 \ indented too far?"
1457 "I was not expecting an arrow here:"
1460 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
1461 \ you want > or >= instead?"
1466 region = toRegion row col
1467 name = getDefName context
1469 Report.Report "UNEXPECTED EQUALS" region [] $
1470 Code.toSnippet source region Nothing
1473 "I was not expecting to see this equals sign:"
1477 D.reflow "Maybe you want == instead? To check if two values are equal?"
1480 if isWithin NRecord context then
1481 "Records look like { x = 3, y = 4 } with the equals sign right\
1482 \ after the field name. So maybe you forgot a comma?"
1484 "I may be getting confused by your indentation. Is this supposed to be part of\
1485 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1486 \ the problem may be a bit before the equals sign. I need all definitions to\
1487 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1488 \ this new definition is indented a bit too much."
1494 region = toRegion row col
1495 name = getDefName context
1497 Report.Report "UNEXPECTED SYMBOL" region [] $
1498 Code.toSnippet source region Nothing $
1501 "I was not expecting to run into the \"has type\" symbol here:"
1506 ["Maybe","you","want",D.green "::","instead?"
1507 ,"To","put","something","on","the","front","of","a","list?"
1510 "The single colon is reserved for type annotations and record types, but I think\
1511 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
1514 "I may be getting confused by your indentation. Is this supposed to be part of\
1515 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1516 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
1517 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1518 \ this new definition is indented a bit too much."
1527toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
1528toIfReport source context if_ startRow startCol =
1530 IfSpace space row col ->
1531 toSpaceReport source space row col
1535 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1536 region = toRegion row col
1538 Report.Report "UNFINISHED IF" region [] $
1539 Code.toSnippet source surroundings (Just region)
1542 "I was expecting to see more of this `if` expression, but I got stuck here:"
1545 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1551 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1552 region = toRegion row col
1554 Report.Report "UNFINISHED IF" region [] $
1555 Code.toSnippet source surroundings (Just region)
1558 "I was expecting to see more of this `if` expression, but I got stuck here:"
1561 ["I","was","expecting","to","see","the",D.green "else","keyword","next."
1565 IfElseBranchStart row col ->
1567 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1568 region = toRegion row col
1570 Report.Report "UNFINISHED IF" region [] $
1571 Code.toSnippet source surroundings (Just region)
1574 "I just saw the start of an `else` branch, but then I got stuck here:"
1577 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1580 IfCondition expr row col ->
1581 toExprReport source (InNode NCond startRow startCol context) expr row col
1583 IfThenBranch expr row col ->
1584 toExprReport source (InNode NThen startRow startCol context) expr row col
1586 IfElseBranch expr row col ->
1587 toExprReport source (InNode NElse startRow startCol context) expr row col
1589 IfIndentCondition row col ->
1591 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1592 region = toRegion row col
1594 Report.Report "UNFINISHED IF" region [] $
1595 Code.toSnippet source surroundings (Just region)
1598 "I was expecting to see more of this `if` expression, but I got stuck here:"
1602 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
1603 ,"that","evaluates","to","True","or","False."
1606 "I can be confused by indentation. Maybe something is not indented enough?"
1610 IfIndentThen row col ->
1612 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1613 region = toRegion row col
1615 Report.Report "UNFINISHED IF" region [] $
1616 Code.toSnippet source surroundings (Just region)
1619 "I was expecting to see more of this `if` expression, but I got stuck here:"
1623 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1626 "I can be confused by indentation. Maybe something is not indented enough?"
1630 IfIndentThenBranch row col ->
1632 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1633 region = toRegion row col
1635 Report.Report "UNFINISHED IF" region [] $
1636 Code.toSnippet source surroundings (Just region)
1639 "I got stuck after the start of this `then` branch:"
1643 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1645 "I can be confused by indentation, so if the `then` branch is already\
1646 \ present, it may not be indented enough for me to recognize it."
1650 IfIndentElseBranch row col ->
1652 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1653 region = toRegion row col
1655 Report.Report "UNFINISHED IF" region [] $
1656 Code.toSnippet source surroundings (Just region)
1659 "I got stuck after the start of this `else` branch:"
1663 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1665 "I can be confused by indentation, so if the `else` branch is already\
1666 \ present, it may not be indented enough for me to recognize it."
1670 IfIndentElse row col ->
1672 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1673 region = toRegion row col
1675 Report.Report "UNFINISHED IF" region [] $
1676 Code.toSnippet source surroundings (Just region)
1679 "I was expecting to see an `else` branch after this:"
1683 "I know what to do when the condition is `True`, but not when it is `False`."
1685 ["Add","an",D.green "else","branch","to","handle","that","scenario!"]
1694toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
1695toRecordReport source context record startRow startCol =
1697 RecordOpen row col ->
1699 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1700 region = toRegion row col
1702 case Code.whatIsNext source row col of
1703 Code.Keyword keyword ->
1704 Report.Report "RESERVED WORD" region [] $
1705 Code.toSnippet source surroundings (Just region)
1708 "I just started parsing a record, but I got stuck on this field name:"
1711 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
1712 \ that is a reserved word. Try using a different name!"
1716 Report.Report "UNFINISHED RECORD" region [] $
1717 Code.toSnippet source surroundings (Just region)
1720 "I just started parsing a record, but I got stuck here:"
1723 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
1724 ,"so","I","was","expecting","to","see","a","field","name","next."
1728 RecordEnd row col ->
1730 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1731 region = toRegion row col
1733 Report.Report "UNFINISHED RECORD" region [] $
1734 Code.toSnippet source surroundings (Just region)
1737 "I am partway through parsing a record, but I got stuck here:"
1741 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
1742 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
1745 "When I get stuck like this, it usually means that there is a missing parenthesis\
1746 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
1750 RecordField row col ->
1752 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1753 region = toRegion row col
1755 case Code.whatIsNext source row col of
1756 Code.Keyword keyword ->
1757 Report.Report "RESERVED WORD" region [] $
1758 Code.toSnippet source surroundings (Just region)
1761 "I am partway through parsing a record, but I got stuck on this field name:"
1764 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
1765 \ that is a reserved word. Try using a different name!"
1769 Report.Report "UNFINISHED RECORD" region [] $
1770 Code.toSnippet source surroundings (Just region)
1773 "I am partway through parsing a record, but I got stuck after that last comma:"
1775 addNoteForRecordError $
1777 "Trailing commas are not allowed in records, so I was expecting to see another\
1778 \ record field defined next. If you are done defining the record, the fix may\
1779 \ be to delete that last comma?"
1782 RecordEquals row col ->
1784 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1785 region = toRegion row col
1787 Report.Report "UNFINISHED RECORD" region [] $
1788 Code.toSnippet source surroundings (Just region)
1791 "I am partway through parsing a record, but I got stuck here:"
1793 addNoteForRecordError $
1795 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
1796 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
1800 RecordExpr expr row col ->
1801 toExprReport source (InNode NRecord startRow startCol context) expr row col
1803 RecordSpace space row col ->
1804 toSpaceReport source space row col
1806 RecordIndentOpen row col ->
1808 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1809 region = toRegion row col
1811 Report.Report "UNFINISHED RECORD" region [] $
1812 Code.toSnippet source surroundings (Just region)
1815 "I just saw the opening curly brace of a record, but then I got stuck here:"
1817 addNoteForRecordIndentError $
1819 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
1820 ,"Try","defining","some","fields","of","your","own?"
1824 RecordIndentEnd row col ->
1826 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1827 region = toRegion row col
1829 Report.Report "UNFINISHED RECORD" region [] $
1830 Code.toSnippet source surroundings (Just region)
1833 "I was expecting to see a closing curly brace next:"
1835 addNoteForRecordIndentError $
1837 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
1841 RecordIndentField row col ->
1843 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1844 region = toRegion row col
1846 Report.Report "UNFINISHED RECORD" region [] $
1847 Code.toSnippet source surroundings (Just region)
1850 "I am partway through parsing a record, but I got stuck after that last comma:"
1852 addNoteForRecordError $
1854 "Trailing commas are not allowed in records, so the fix may be to\
1855 \ delete that last comma? Or maybe you were in the middle of defining\
1856 \ an additional field?"
1859 RecordIndentEquals row col ->
1861 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1862 region = toRegion row col
1864 Report.Report "UNFINISHED RECORD" region [] $
1865 Code.toSnippet source surroundings (Just region)
1868 "I am partway through parsing a record. I just saw a record\
1869 \ field, so I was expecting to see an equals sign next:"
1871 addNoteForRecordIndentError $
1873 ["Try","putting","an",D.green "=","followed","by","an","expression?"
1877 RecordIndentExpr row col ->
1879 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1880 region = toRegion row col
1882 Report.Report "UNFINISHED RECORD" region [] $
1883 Code.toSnippet source surroundings (Just region)
1886 "I am partway through parsing a record, and I was expecting to run into an expression next:"
1888 addNoteForRecordIndentError $
1890 ["Try","putting","something,","like"
1891 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
1896addNoteForRecordError :: D.Doc -> D.Doc
1897addNoteForRecordError normalRecommendation =
1899 normalRecommendation
1902 "If you are trying to define a record across multiple lines, I recommend using this format:"
1903 , D.indent 4 $ D.vcat $
1904 [ "{ name = \"Alice\""
1910 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1911 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1912 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1916addNoteForRecordIndentError :: D.Doc -> D.Doc
1917addNoteForRecordIndentError normalRecommendation =
1919 normalRecommendation
1922 "I may be confused by indentation. For example, if you are trying to define\
1923 \ a record across multiple lines, I recommend using this format:"
1924 , D.indent 4 $ D.vcat $
1931 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1932 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1933 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1941toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
1942toTupleReport source context tuple startRow startCol =
1944 TupleExpr expr row col ->
1945 toExprReport source (InNode NParens startRow startCol context) expr row col
1947 TupleSpace space row col ->
1948 toSpaceReport source space row col
1952 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1953 region = toRegion row col
1955 Report.Report "UNFINISHED PARENTHESES" region [] $
1956 Code.toSnippet source surroundings (Just region)
1959 "I was expecting to see a closing parentheses next, but I got stuck here:"
1962 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
1964 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1965 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
1966 \ or missing brackets) that is confusing me."
1970 TupleOperatorClose row col ->
1972 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1973 region = toRegion row col
1975 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
1976 Code.toSnippet source surroundings (Just region)
1978 D.reflow "I was expecting a closing parenthesis here:"
1981 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
1983 "I think I am parsing an operator function right now, so I am expecting to see\
1984 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
1989 TupleOperatorReserved operator row col ->
1991 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1992 region = toRegion row col
1994 Report.Report "UNEXPECTED SYMBOL" region [] $
1995 Code.toSnippet source surroundings (Just region)
1998 "I ran into an unexpected symbol here:"
2002 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
2003 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
2004 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
2005 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
2006 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
2009 TupleIndentExpr1 row col ->
2011 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2012 region = toRegion row col
2014 Report.Report "UNFINISHED PARENTHESES" region [] $
2015 Code.toSnippet source surroundings (Just region)
2018 "I just saw an open parenthesis, so I was expecting to see an expression next."
2022 ["Something","like",D.dullyellow "(4 + 5)","or"
2023 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
2024 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
2027 "I can get confused by indentation in cases like this, so\
2028 \ maybe you have an expression but it is not indented enough?"
2032 TupleIndentExprN row col ->
2034 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2035 region = toRegion row col
2037 Report.Report "UNFINISHED TUPLE" region [] $
2038 Code.toSnippet source surroundings (Just region)
2041 "I think I am in the middle of parsing a tuple. I just saw a comma, so I was expecting to see expression next."
2045 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
2046 ,D.dullyellow "(\"Tom\",42)" <> ","
2047 ,"so","I","think","there","is","an","expression","missing","here?"
2050 "I can get confused by indentation in cases like this, so\
2051 \ maybe you have an expression but it is not indented enough?"
2055 TupleIndentEnd row col ->
2057 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2058 region = toRegion row col
2060 Report.Report "UNFINISHED PARENTHESES" region [] $
2061 Code.toSnippet source surroundings (Just region)
2064 "I was expecting to see a closing parenthesis next:"
2067 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
2069 "I can get confused by indentation in cases like this, so\
2070 \ maybe you have a closing parenthesis but it is not indented enough?"
2075toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
2076toListReport source context list startRow startCol =
2078 ListSpace space row col ->
2079 toSpaceReport source space 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 Code.toSnippet source surroundings (Just region)
2090 "I am partway through parsing a list, but I got stuck here:"
2094 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2095 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2098 "When I get stuck like this, it usually means that there is a missing parenthesis\
2099 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2103 ListExpr expr row col ->
2107 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
2108 region = toRegion r c
2110 Report.Report "UNFINISHED LIST" region [] $
2111 Code.toSnippet source surroundings (Just region)
2114 "I was expecting to see another list entry after that last comma:"
2118 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2120 "I recommend using the following format for lists that span multiple lines:"
2121 , D.indent 4 $ D.vcat $
2128 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2129 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2130 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2135 toExprReport source (InNode NList startRow startCol context) expr row col
2139 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2140 region = toRegion row col
2142 Report.Report "UNFINISHED LIST" region [] $
2143 Code.toSnippet source surroundings (Just region)
2146 "I am partway through parsing a list, but I got stuck here:"
2150 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2151 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2154 "When I get stuck like this, it usually means that there is a missing parenthesis\
2155 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2159 ListIndentOpen row col ->
2161 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2162 region = toRegion row col
2164 Report.Report "UNFINISHED LIST" region [] $
2165 Code.toSnippet source surroundings (Just region)
2168 "I cannot find the end of this list:"
2172 ["You","could","change","it","to","something","like"
2173 ,D.dullyellow "[3,4,5]"
2175 ,D.dullyellow "[]" <> "."
2176 ,"Anything","where","there","is","an","open","and","close","square","brace,"
2177 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
2180 "I may be confused by indentation. For example, if you are trying to define\
2181 \ a list across multiple lines, I recommend using this format:"
2182 , D.indent 4 $ D.vcat $
2189 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2190 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2191 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2195 ListIndentEnd row col ->
2197 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2198 region = toRegion row col
2200 Report.Report "UNFINISHED LIST" region [] $
2201 Code.toSnippet source surroundings (Just region)
2204 "I cannot find the end of this list:"
2208 ["You","can","just","add","a","closing",D.dullyellow "]"
2209 ,"right","here,","and","I","will","be","all","set!"
2212 "I may be confused by indentation. For example, if you are trying to define\
2213 \ a list across multiple lines, I recommend using this format:"
2214 , D.indent 4 $ D.vcat $
2221 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2222 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2223 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2227 ListIndentExpr row col ->
2229 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2230 region = toRegion row col
2232 Report.Report "UNFINISHED LIST" region [] $
2233 Code.toSnippet source surroundings (Just region)
2236 "I was expecting to see another list entry after this comma:"
2240 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2242 "I recommend using the following format for lists that span multiple lines:"
2243 , D.indent 4 $ D.vcat $
2250 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2251 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2252 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2257toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
2258toFuncReport source context func startRow startCol =
2260 FuncSpace space row col ->
2261 toSpaceReport source space row col
2263 FuncArg pattern row col ->
2264 error "TODO FuncArg" pattern row col
2266 FuncBody expr row col ->
2267 toExprReport source (InNode NFunc startRow startCol context) expr row col
2269 FuncArrow row col ->
2271 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2272 region = toRegion row col
2274 case Code.whatIsNext source row col of
2275 Code.Keyword keyword ->
2276 Report.Report "RESERVED WORD" region [] $
2277 Code.toSnippet source surroundings (Just region)
2280 "I was parsing an anonymous function, but I got stuck here:"
2283 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
2284 \ it is a reserved word in this language. Try using a different argument name!"
2288 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2289 Code.toSnippet source surroundings (Just region)
2292 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2295 ["The","syntax","for","anonymous","functions","is"
2296 ,D.dullyellow "(\\x -> x + 1)"
2297 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2301 FuncIndentArg row col ->
2303 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2304 region = toRegion row col
2306 Report.Report "MISSING ARGUMENT" region [] $
2307 Code.toSnippet source surroundings (Just region)
2310 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
2314 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
2315 ,"Anything","that","starts","with","a","lower","case","letter!"
2318 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
2319 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
2320 \ like a better idea at the time!"
2324 FuncIndentArrow row col ->
2326 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2327 region = toRegion row col
2329 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2330 Code.toSnippet source surroundings (Just region)
2333 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2337 ["The","syntax","for","anonymous","functions","is"
2338 ,D.dullyellow "(\\x -> x + 1)"
2339 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2342 "It is possible that I am confused about indetation! I generally recommend\
2343 \ switching to named functions if the definition cannot fit inline nicely, so\
2344 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2345 \ the whole thing out into a named function. Things tend to be clearer that way!"
2349 FuncIndentBody row col ->
2351 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2352 region = toRegion row col
2354 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2355 Code.toSnippet source surroundings (Just region)
2358 "I was expecting to see the body of your anonymous function next:"
2362 ["The","syntax","for","anonymous","functions","is"
2363 ,D.dullyellow "(\\x -> x + 1)"
2364 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
2367 "It is possible that I am confused about indetation! I generally recommend\
2368 \ switching to named functions if the definition cannot fit inline nicely, so\
2369 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2370 \ the whole thing out into a named function. Things tend to be clearer that way!"
2379 CommentOnNothing region ->
2380 Report.Report "STRAY COMMENT" region [] $
2381 Code.toSnippet source region Nothing
2383 "This documentation comment is not followed by anything."
2386 "All documentation comments need to be right above the declaration they\
2387 \ describe. Maybe some code got deleted or commented out by accident? Or\
2388 \ maybe this comment is here by accident?"
2391 UnexpectedPort region ->
2392 Report.Report "UNEXPECTED PORTS" region [] $
2393 Code.toSnippet source region Nothing
2396 "You are declaring ports in a normal module."
2400 ["Switch","this","to","say",D.green "port module","instead,"
2401 ,"marking","that","this","module","contains","port","declarations."
2404 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
2406 "to learn the syntax and how to use it effectively."
2411 Report.Report "NO PORTS" region [] $
2412 Code.toSnippet source region Nothing
2415 "This module does not declare any ports, but it says it will:"
2418 ["Switch","this","to",D.green "module"
2419 ,"and","you","should","be","all","set!"
2423 ParseError row col context expectation ->
2425 pos = A.Position row col
2426 region = A.Region pos pos
2431 Report.Report "EXPECTING DOC COMMENT" region [] $
2432 Code.toSnippet source region Nothing
2435 "I was expecting a doc comment here:"
2438 "Check out" "TODO" "for examples of doc comments."
2444 Report.Report "EXPECTING PRECEDENCE" region [] $
2445 Code.toSnippet source region Nothing
2448 "I was expecting the precedence here:"
2451 "I need a single digit between 0 and 9 inclusive."
2455 Report.Report "EXPECTING A WILDCARD" region [] $
2456 Code.toSnippet source region Nothing
2459 "I was expecting a _ here:"
2462 "An underscore indicates that “I do not care about this value” and is\
2463 \ called a wildcard pattern because it will match with any type of values."
2466 WildcardNotVar startCol endCol ->
2469 A.Region (A.Position row startCol) (A.Position row endCol)
2471 Report.Report "INVALID PATTERN" badRegion [] $
2472 Code.toSnippet source badRegion Nothing
2475 "I was expecting to see an underscore without any additional characters:"
2478 "There are two options. Either (1) remove the extra characters and ignore the\
2479 \ value or (2) remove the starting underscore to give the value a normal name."
2485 Report.Report "INVALID PATTERN" region [] $
2486 Code.toSnippet source region Nothing
2489 "I cannot pattern match with floating point numbers:"
2492 "Equality on floats can be unreliable, so you usually want to check that they\
2493 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
2498 MatchingName name ->
2499 Report.Report "EXPECTING A DEFINITION" region [] $
2500 Code.toSnippet source region Nothing
2503 "I just saw the type annotation for `" ++ Name.toChars name
2504 ++ "` so I was expecting to see its definition here:"
2507 "Type annotations always appear directly above the relevant\
2508 \ definition, without anything else (even doc comments) in between."
2514 TypeWithBadDefinition region annName defName ->
2515 Report.Report "ANNOTATION MISMATCH" region [] $
2516 Code.toSnippet source region Nothing
2519 "I see a `" <> Name.toChars annName
2520 <> "` annotation, but it is followed by a `"
2521 <> Name.toChars defName <> "` definition."
2524 ["The","annotation","and","definition","names","must","match!"
2525 ,"Is","there","a","typo","between"
2526 , D.dullyellow (D.fromName annName)
2528 , D.dullyellow (D.fromName defName) <> "?"
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