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
82 | ModuleProblem Row Col
84 | ModuleExposing Exposing Row Col
86 | PortModuleProblem Row Col
87 | PortModuleName Row Col
88 | PortModuleExposing Exposing Row Col
98 | ImportExposing Row Col
99 | ImportExposingList Exposing Row Col
100 | ImportEnd Row Col -- different based on col=1 or if greater
102 | ImportIndentName Row Col
103 | ImportIndentAlias Row Col
104 | ImportIndentExposingList Row Col
108 | Declarations Decl Row Col
112 = ExposingSpace Space Row Col
113 | ExposingStart Row Col
114 | ExposingValue Row Col
115 | ExposingOperator Row Col
116 | ExposingOperatorReserved BadOperator Row Col
117 | ExposingOperatorRightParen Row Col
118 | ExposingEnd Row Col
120 | ExposingTypePrivacy Row Col
121 | ExposingTypePrivacyDots Row Col
122 | ExposingTypePrivacyEnd Row Col
124 | ExposingIndentEnd Row Col
125 | ExposingIndentValue Row Col
126 | ExposingIndentValueEnd Row Col
127 | ExposingIndentTypePrivacy Row Col
128 | ExposingIndentTypePrivacyDots Row Col
129 | ExposingIndentTypePrivacyEnd Row Col
138 | DeclSpace Space Row Col
141 | DeclType DeclType Row Col
142 | DeclDef Name.Name DeclDef Row Col
144 | DeclFreshLineStart Row Col
145 | DeclFreshLineAfterDocComment Row Col
149 = DeclDefSpace Space Row Col
150 | DeclDefEquals Row Col
151 | DeclDefType Type Row Col
152 | DeclDefArg Pattern Row Col
153 | DeclDefBody Expr Row Col
154 | DeclDefNameRepeat Row Col
155 | DeclDefNameMatch Name.Name Row Col
157 | DeclDefIndentType Row Col
158 | DeclDefIndentEquals Row Col
159 | DeclDefIndentBody Row Col
161 | DeclDefFreshLineAfterType Row Col
165 = PortSpace Space Row Col
168 | PortType Type Row Col
169 | PortIndentName Row Col
170 | PortIndentColon Row Col
171 | PortIndentType Row Col
179 = DT_Space Space Row Col
181 | DT_Alias TypeAlias Row Col
182 | DT_Union CustomType Row Col
184 | DT_IndentName Row Col
188 = AliasSpace Space Row Col
190 | AliasEquals Row Col
191 | AliasBody Type Row Col
193 | AliasIndentEquals Row Col
194 | AliasIndentBody Row Col
198 = CT_Space Space Row Col
203 | CT_VariantArg Type Row Col
205 | CT_IndentEquals Row Col
206 | CT_IndentBar Row Col
207 | CT_IndentAfterBar Row Col
208 | CT_IndentAfterEquals Row Col
220 | Record Record Row Col
221 | Tuple Tuple Row Col
226 | OperatorRight Name.Name Row Col
227 | OperatorReserved BadOperator Row Col
231 | String String Row Col
232 | Number Number Row Col
233 | Space Space Row Col
234 | EndlessShader Row Col
235 | ShaderProblem [Char.Char] Row Col
236 | IndentOperatorRight Name.Name Row Col
237 | IndentMoreExpr Row Col
243 | RecordField Row Col
244 | RecordEquals Row Col
245 | RecordExpr Expr Row Col
246 | RecordSpace Space Row Col
248 | RecordIndentOpen Row Col
249 | RecordIndentEnd Row Col
250 | RecordIndentField Row Col
251 | RecordIndentEquals Row Col
252 | RecordIndentExpr Row Col
256 = TupleExpr Expr Row Col
257 | TupleSpace Space Row Col
259 | TupleOperatorClose Row Col
260 | TupleOperatorReserved BadOperator Row Col
262 | TupleIndentExpr1 Row Col
263 | TupleIndentExprN Row Col
264 | TupleIndentEnd Row Col
268 = ListSpace Space Row Col
270 | ListExpr Expr Row Col
273 | ListIndentOpen Row Col
274 | ListIndentEnd Row Col
275 | ListIndentExpr Row Col
279 = FuncSpace Space Row Col
280 | FuncArg Pattern Row Col
281 | FuncBody Expr Row Col
284 | FuncIndentArg Row Col
285 | FuncIndentArrow Row Col
286 | FuncIndentBody Row Col
290 = CaseSpace Space Row Col
292 | CasePattern Pattern Row Col
294 | CaseExpr Expr Row Col
295 | CaseBranch Expr Row Col
297 | CaseIndentOf Row Col
298 | CaseIndentExpr Row Col
299 | CaseIndentPattern Row Col
300 | CaseIndentArrow Row Col
301 | CaseIndentBranch Row Col
302 | CasePatternAlignment Word16 Row Col
306 = IfSpace Space Row Col
309 | IfElseBranchStart Row Col
311 | IfCondition Expr Row Col
312 | IfThenBranch Expr Row Col
313 | IfElseBranch Expr Row Col
315 | IfIndentCondition Row Col
316 | IfIndentThen Row Col
317 | IfIndentThenBranch Row Col
318 | IfIndentElseBranch Row Col
319 | IfIndentElse Row Col
323 = LetSpace Space Row Col
325 | LetDefAlignment Word16 Row Col
327 | LetDef Name.Name Def Row Col
328 | LetDestruct Destruct Row Col
329 | LetBody Expr Row Col
330 | LetIndentDef Row Col
331 | LetIndentIn Row Col
332 | LetIndentBody Row Col
336 = DefSpace Space Row Col
337 | DefType Type Row Col
338 | DefNameRepeat Name.Name Row Col
339 | DefNameMatch Name.Name Name.Name Row Col
340 | DefArg Pattern Row Col
342 | DefBody Expr Row Col
343 | DefIndentEquals Row Col
344 | DefIndentType Row Col
345 | DefIndentBody Row Col
346 | DefAlignment Word16 Row Col
350 = DestructSpace Space Row Col
351 | DestructPattern Pattern Row Col
352 | DestructEquals Row Col
353 | DestructBody Expr Row Col
354 | DestructIndentEquals Row Col
355 | DestructIndentBody Row Col
363 = PRecord PRecord Row Col
364 | PTuple PTuple Row Col
365 | PList PList Row Col
369 | PString String Row Col
370 | PNumber Number Row Col
371 | PFloat Word16 Row Col
373 | PWildcardNotVar Name.Name Int Row Col
374 | PSpace Space Row Col
376 | PIndentStart Row Col
377 | PIndentAlias Row Col
381 = PRecordOpen Row Col
383 | PRecordField Row Col
384 | PRecordSpace Space Row Col
386 | PRecordIndentOpen Row Col
387 | PRecordIndentEnd Row Col
388 | PRecordIndentField Row Col
394 | PTupleExpr Pattern Row Col
395 | PTupleSpace Space Row Col
397 | PTupleIndentEnd Row Col
398 | PTupleIndentExpr1 Row Col
399 | PTupleIndentExprN Row Col
405 | PListExpr Pattern Row Col
406 | PListSpace Space Row Col
408 | PListIndentOpen Row Col
409 | PListIndentEnd Row Col
410 | PListIndentExpr Row Col
418 = TRecord TRecord Row Col
419 | TTuple TTuple Row Col
424 | TSpace Space Row Col
426 | TIndentStart Row Col
430 = TRecordOpen Row Col
433 | TRecordField Row Col
434 | TRecordColon Row Col
435 | TRecordType Type Row Col
437 | TRecordSpace Space Row Col
439 | TRecordIndentOpen Row Col
440 | TRecordIndentField Row Col
441 | TRecordIndentColon Row Col
442 | TRecordIndentType Row Col
443 | TRecordIndentEnd Row Col
449 | TTupleType Type Row Col
450 | TTupleSpace Space Row Col
452 | TTupleIndentOpen Row Col
453 | TTupleIndentType Row Col
454 | TTupleIndentEnd Row Col
464 | CharNotString Word16
468 = StringEndless_Single
469 | StringEndless_Multi
470 | StringEscape Escape
475 | BadUnicodeFormat Word16
476 | BadUnicodeCode Word16
477 | BadUnicodeLength Word16 Int Int
484 | NumberNoLeadingZero
493 | EndlessMultiComment
500toReport :: Code.Source -> Error -> Report.Report
503 ModuleNameUnspecified name ->
505 region = toRegion 1 1
507 Report.Report "MODULE NAME MISSING" region [] $
510 "I need the module name to be declared at the top of this file, like this:"
511 , D.indent 4 $ D.fillSep $
512 [ D.cyan "module", D.fromName name, D.cyan "exposing", "(..)" ]
514 "Try adding that as the first line of your file!"
516 "It is best to replace (..) with an explicit list of types and\
517 \ functions you want to expose. When you know a value is only used\
518 \ within this module, you can refactor without worrying about uses\
519 \ elsewhere. Limiting exposed values can also speed up compilation\
520 \ because I can skip a bunch of work if I see that the exposed API\
524 ModuleNameMismatch expectedName (A.At region actualName) ->
525 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
526 Code.toSnippet source region Nothing
528 "It looks like this module name is out of sync:"
532 "I need it to match the file path, so I was expecting it to see `"
533 ++ ModuleName.toChars expectedName
534 ++ "` here. Make the following change, and you should be all set!"
536 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
538 "I require that module names correspond to file paths. This makes it much\
539 \ easier to explore unfamiliar codebases! So if you want to keep the current\
540 \ module name, try renaming the file instead."
544 UnexpectedPort region ->
545 Report.Report "UNEXPECTED PORTS" region [] $
546 Code.toSnippet source region Nothing
549 "You are declaring ports in a normal module."
553 ["Switch","this","to","say",D.cyan "port module","instead,"
554 ,"marking","that","this","module","contains","port","declarations."
557 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
559 "to learn the syntax and how to use it effectively."
564 Report.Report "NO PORTS" region [] $
565 Code.toSnippet source region Nothing
568 "This module does not declare any ports, but it says it will:"
571 ["Switch","this","to",D.cyan "module"
572 ,"and","you","should","be","all","set!"
577 toParseErrorReport source modul
580toParseErrorReport :: Code.Source -> Module -> Report.Report
581toParseErrorReport source modul =
583 ModuleSpace space row col ->
584 toSpaceReport source space row col
586 ModuleEndOfFile row col ->
588 region = toRegion row col
590 Report.Report "EXPECTING END OF FILE" region [] $
591 Code.toSnippet source region Nothing
594 "I was not expecting to see anything more here:"
597 "I think I have read all the declarations in the file and that there is nothing\
598 \ left to see, so whatever I am running into is confusing me a lot!"
601 ModuleProblem row col ->
603 region = toRegion row col
605 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
606 Code.toSnippet source region Nothing
609 "I am parsing an `module` declaration, but I got stuck here:"
613 "Here are some examples of valid `module` declarations:"
614 , D.indent 4 $ D.vcat $
615 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
616 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
619 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
620 \ of files when the public interface of a module stays the same, so exposing fewer\
621 \ values can help improve compile times!"
625 ModuleName row col ->
627 region = toRegion row col
629 Report.Report "EXPECTING MODULE NAME" region [] $
630 Code.toSnippet source region Nothing
633 "I was parsing an `module` declaration until I got stuck here:"
637 "I was expecting to see the module name next, like in these examples:"
638 , D.indent 4 $ D.vcat $
639 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
640 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
641 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
642 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
645 "Notice that the module names all start with capital letters. That is required!"
649 ModuleExposing exposing row col ->
650 error "TODO ModuleExposing" exposing row col
652 PortModuleProblem row col ->
654 region = toRegion row col
656 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
657 Code.toSnippet source region Nothing
660 "I am parsing an `port module` declaration, but I got stuck here:"
664 "Here are some examples of valid `port module` declarations:"
665 , D.indent 4 $ D.vcat $
666 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
667 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
669 , D.link "Note" "Read" "ports" "for more help."
673 PortModuleName row col ->
675 region = toRegion row col
677 Report.Report "EXPECTING MODULE NAME" region [] $
678 Code.toSnippet source region Nothing
681 "I was parsing an `module` declaration until I got stuck here:"
685 "I was expecting to see the module name next, like in these examples:"
686 , D.indent 4 $ D.vcat $
687 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
688 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
691 "Notice that the module names start with capital letters. That is required!"
695 PortModuleExposing exposing row col ->
696 error "TODO PortModuleExposing" exposing row col
700 region = toRegion row col
702 Report.Report "BAD MODULE DECLARATION" region [] $
703 Code.toSnippet source region Nothing
706 "I cannot parse this module declaration:"
709 "This type of module is reserved for the @elm organization. It is used to\
710 \ define certain effects, avoiding building them into the compiler."
715 region = toRegion row col
717 toBadFirstLineReport keyword =
718 Report.Report "TOO MUCH INDENTATION" region [] $
719 Code.toSnippet source region Nothing
722 "This `" ++ keyword ++ "` should not have any spaces before it:"
725 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
729 case Code.whatIsNext source row col of
730 Code.Keyword "module" -> toBadFirstLineReport "module"
731 Code.Keyword "import" -> toBadFirstLineReport "import"
732 Code.Keyword "type" -> toBadFirstLineReport "type"
733 Code.Keyword "port" -> toBadFirstLineReport "port"
735 Report.Report "SYNTAX PROBLEM" region [] $
736 Code.toSnippet source region Nothing
743 "I am not sure what is going on, but I recommend starting an Elm\
744 \ file with the following lines:"
746 [ D.fillSep [D.cyan "import","Html"]
748 , D.fillSep [D.green "main","="]
749 , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
752 "You should be able to copy those lines directly into your file. Check out\
753 \ some of the examples on https://elm-lang.org for more help getting started!"
755 "This can also happen when something is indented too much!"
759 ImportStart row col ->
760 toImportReport source row col
762 ImportName row col ->
764 region = toRegion row col
766 Report.Report "EXPECTING IMPORT NAME" region [] $
767 Code.toSnippet source region Nothing
770 "I was parsing an `import` until I got stuck here:"
774 "I was expecting to see a module name next, like in these examples:"
775 , D.indent 4 $ D.vcat $
776 [ D.fillSep [D.cyan "import","Dict"]
777 , D.fillSep [D.cyan "import","Maybe"]
778 , D.fillSep [D.cyan "import","Html.Attributes"]
779 , D.fillSep [D.cyan "import","Json.Decode"]
782 "Notice that the module names all start with capital letters. That is required!"
787 toImportReport source row col
789 ImportAlias row col ->
791 region = toRegion row col
793 Report.Report "EXECTING IMPORT ALIAS" region [] $
794 Code.toSnippet source region Nothing
797 "I was parsing an `import` until I got stuck here:"
801 "I was expecting to see an alias next, like in these examples:"
802 , D.indent 4 $ D.vcat $
803 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
804 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
805 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
808 "Notice that the alias always starts with a capital letter. That is required!"
812 ImportExposing row col ->
813 toImportReport source row col
815 ImportExposingList exposing row col ->
816 error "TODO ImportExposingList" exposing row col
819 toImportReport source row col
821 ImportIndentName row col ->
822 toImportReport source row col
824 ImportIndentAlias row col ->
825 toImportReport source row col
827 ImportIndentExposingList row col ->
829 region = toRegion row col
831 Report.Report "UNFINISHED IMPORT" region [] $
832 Code.toSnippet source region Nothing
835 "I was parsing an `import` until I got stuck here:"
839 "I was expecting to see the list of exposed values next. For example, here\
840 \ are two ways to expose values from the `Html` module:"
841 , D.indent 4 $ D.vcat $
842 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
843 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
846 "I generally recommend the second style. It is more explicit, making it\
847 \ much easier to figure out where values are coming from in large projects!"
853 region = toRegion row col
855 Report.Report "BAD INFIX" region [] $
856 Code.toSnippet source region Nothing
859 "Something went wrong in this infix operator declaration:"
862 "This feature is used by the @elm organization to define the\
863 \ languages built-in operators."
866 Declarations decl _ _ ->
867 toDeclarationsReport source decl
874toImportReport :: Code.Source -> Row -> Col -> Report.Report
875toImportReport source row col =
877 region = toRegion row col
879 Report.Report "UNFINISHED IMPORT" region [] $
880 Code.toSnippet source region Nothing
883 "I am partway through parsing an import, but I got stuck here:"
887 "Here are some examples of valid `import` declarations:"
888 , D.indent 4 $ D.vcat $
889 [ D.fillSep [D.cyan "import","Html"]
890 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
891 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
892 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
895 "You are probably trying to import a different module, but try to make it look like one of these examples!"
904toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
905toSpaceReport source space row col =
909 region = toRegion row col
911 Report.Report "NO TABS" region [] $
912 Code.toSnippet source region Nothing
915 "I ran into a tab, but tabs are not allowed in Elm files."
918 "Replace the tab with spaces."
921 EndlessMultiComment ->
923 region = toWiderRegion row col 2
925 Report.Report "ENDLESS COMMENT" region [] $
926 Code.toSnippet source region Nothing
929 "I cannot find the end of this multi-line comment:"
932 [ D.reflow "Add a -} somewhere after this to end the comment."
934 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
935 \ that happens to contain another comment. Like parentheses and curly braces,\
936 \ the start and end markers must always be balanced. Maybe that is the problem?"
945toRegion :: Row -> Col -> A.Region
948 pos = A.Position row col
953toWiderRegion :: Row -> Col -> Word16 -> A.Region
954toWiderRegion row col extra =
957 (A.Position row (col + extra))
960toDeclarationsReport :: Code.Source -> Decl -> Report.Report
961toDeclarationsReport source decl =
964 error "TODO DeclStart" row col
966 DeclSpace space row col ->
967 toSpaceReport source space row col
970 error "TODO Port" port row col
972 DeclType declType row col ->
973 error "TODO DeclType" declType row col
975 DeclDef name declDef row col ->
976 toDeclDefReport source name declDef row col
978 DeclFreshLineStart row col ->
979 error "TODO DeclFreshLineStart" row col
981 DeclFreshLineAfterDocComment row col ->
982 error "TODO DeclFreshLineAfterDocComment" row col
985toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
986toDeclDefReport source name declDef startRow startCol =
988 DeclDefSpace space row col ->
989 toSpaceReport source space row col
991 DeclDefEquals row col ->
992 case Code.whatIsNext source row col of
993 Code.Keyword keyword ->
995 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
996 region = toWiderRegion row col (fromIntegral (length keyword))
998 Report.Report "RESERVED WORD" region [] $
999 Code.toSnippet source surroundings (Just region)
1002 "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
1005 "This is a reserved word! Try using some other name?"
1010 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1011 region = toWiderRegion row col (fromIntegral (length op))
1013 Report.Report "UNEXPECTED SYMBOL" region [] $
1014 Code.toSnippet source surroundings (Just region)
1017 "I was not expecting to see this symbol here:"
1021 "I am not sure what is going wrong exactly, so here is a valid\
1022 \ definition (with an optional type annotation) for reference:"
1024 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1025 , D.fillSep [D.green "add","x","y","="]
1026 , D.fillSep [" ","x","+","y"]
1029 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
1035 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1036 region = toRegion row col
1038 Report.Report "PROBLEM IN DEFINITION" region [] $
1039 Code.toSnippet source surroundings (Just region)
1042 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
1046 "I am not sure what is going wrong exactly, so here is a valid\
1047 \ definition (with an optional type annotation) for reference:"
1049 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1050 , D.fillSep [D.green "add","x","y","="]
1051 , D.fillSep [" ","x","+","y"]
1054 "Try to use that format!"
1058 DeclDefType tipe row col ->
1059 error "TODO DeclDefType" toTypeReport tipe row col
1061 DeclDefArg pattern row col ->
1062 toPatternReport source PArg pattern row col
1064 DeclDefBody expr row col ->
1065 toExprReport source (InDef name startRow startCol) expr row col
1067 DeclDefNameRepeat row col ->
1069 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1070 region = toRegion row col
1072 Report.Report "EXPECTING DEFINITION" region [] $
1073 Code.toSnippet source surroundings (Just region)
1076 "I just saw the type annotation for `" ++ Name.toChars name
1077 ++ "` so I was expecting to see its definition here:"
1080 "Type annotations always appear directly above the relevant\
1081 \ definition, without anything else (even doc comments) in between."
1084 DeclDefNameMatch defName row col ->
1086 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1087 region = toRegion row col
1089 Report.Report "NAME MISMATCH" region [] $
1090 Code.toSnippet source surroundings (Just region)
1093 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
1097 "These names do not match! Is there a typo?"
1098 , D.indent 4 $ D.fillSep $
1099 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
1103 DeclDefIndentType row col ->
1104 error "TODO DeclDefIndentType" row col
1106 DeclDefIndentEquals row col ->
1107 error "TODO DeclDefIndentEquals" row col
1109 DeclDefIndentBody row col ->
1110 error "TODO DeclDefIndentBody" row col
1112 DeclDefFreshLineAfterType row col ->
1113 error "TODO DeclDefFreshLineAfterType" row col
1121 = InNode Node Row Col Context
1122 | InDef Name.Name Row Col
1138getDefName :: Context -> Name.Name
1141 InDef name _ _ -> name
1142 InNode _ _ _ c -> getDefName c
1145isWithin :: Node -> Context -> Bool
1146isWithin desiredNode context =
1148 InDef _ _ _ -> False
1149 InNode actualNode _ _ _ -> desiredNode == actualNode
1156toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
1157toExprReport source context expr startRow startCol =
1160 toLetReport source context let_ row col
1162 Case case_ row col ->
1163 toCaseReport source context case_ row col
1166 toIfReport source context if_ row col
1168 List list row col ->
1169 toListReport source context list row col
1171 Record record row col ->
1172 toRecordReport source context record row col
1174 Tuple tuple row col ->
1175 toTupleReport source context tuple row col
1177 Func func row col ->
1178 toFuncReport source context func row col
1181 let region = toRegion row col in
1182 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
1183 Code.toSnippet source region Nothing
1186 "I was expecting to see a record accessor here:"
1189 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
1190 ,"that","accesses","a","value","from","a","record."
1195 let region = toRegion row col in
1196 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
1197 Code.toSnippet source region Nothing
1200 "I am trying to parse a record accessor here:"
1205 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
1206 ,"that","accesses","a","value","from","a","record."
1210 "Record field names must start with a lower case letter!"
1214 OperatorRight op row col ->
1215 let region = toRegion row col in
1216 Report.Report "MISSING EXPRESSION" region [] $
1217 Code.toSnippet source region Nothing
1220 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1224 ["You","can","just","put","anything","for","now,","like"
1225 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1226 ,"Once","there","is","something","there,","I","can","probably"
1227 ,"give","a","more","specific","hint!"
1230 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
1231 \ Or if I run into operators in unexpected spots. Point is, there are a\
1232 \ couple ways I can get confused and give sort of weird advice!"
1236 OperatorReserved operator row col ->
1237 toOperatorReport source context operator row col
1241 (contextRow, contextCol, aThing) =
1243 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
1244 InNode NRecord r c _ -> (r, c, "a record")
1245 InNode NParens r c _ -> (r, c, "some parentheses")
1246 InNode NList r c _ -> (r, c, "a list")
1247 InNode NFunc r c _ -> (r, c, "an anonymous function")
1248 InNode NCond r c _ -> (r, c, "an `if` expression")
1249 InNode NThen r c _ -> (r, c, "an `if` expression")
1250 InNode NElse r c _ -> (r, c, "an `if` expression")
1251 InNode NCase r c _ -> (r, c, "a `case` expression")
1252 InNode NBranch r c _ -> (r, c, "a `case` expression")
1253 -- TODO check if this is actually the best way to get error messages here
1255 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
1256 region = toRegion row col
1258 Report.Report "MISSING EXPRESSION" region [] $
1259 Code.toSnippet source surroundings (Just region)
1262 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
1266 ["I","was","expecting","to","see","an","expression","like"
1267 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1268 ,"Once","there","is","something","there,","I","can","probably"
1269 ,"give","a","more","specific","hint!"
1272 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
1273 \ Or if I run into operators in unexpected spots. Point is, there are a\
1274 \ couple ways I can get confused and give sort of weird advice!"
1278 Char char row col ->
1279 toCharReport source char row col
1281 String string row col ->
1282 toStringReport source string row col
1284 Number number row col ->
1285 toNumberReport source number row col
1287 Space space row col ->
1288 toSpaceReport source space row col
1290 EndlessShader row col ->
1292 region = toWiderRegion row col 6
1294 Report.Report "ENDLESS SHADER" region [] $
1295 Code.toSnippet source region Nothing
1297 D.reflow "I cannot find the end of this shader:"
1299 D.reflow "Add a |] somewhere after this to end the shader."
1302 ShaderProblem problem row col ->
1304 region = toRegion row col
1306 Report.Report "SHADER PROBLEM" region [] $
1307 Code.toSnippet source region Nothing
1310 "I ran into a problem while parsing this GLSL block."
1314 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
1315 , D.indent 4 $ D.vcat $
1316 map D.fromChars (filter (/="") (lines problem))
1320 IndentOperatorRight op row col ->
1322 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1323 region = toRegion row col
1325 Report.Report "MISSING EXPRESSION" region [] $
1326 Code.toSnippet source surroundings (Just region)
1329 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1334 ["You","can","just","put","anything","for","now,","like"
1335 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1336 ,"Once","there","is","something","there,","I","can","probably"
1337 ,"give","a","more","specific","hint!"
1341 "I may be getting confused by your indentation? The easiest way to make sure\
1342 \ this is not an indentation problem is to put the expression on the right of\
1343 \ the " ++ Name.toChars op ++ " operator on the same line."
1347 IndentMoreExpr _ _ ->
1348 error "TODO IndentMoreExpr"
1355toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
1356toCharReport source char row col =
1360 region = toRegion row col
1362 Report.Report "MISSING SINGLE QUOTE" region [] $
1363 Code.toSnippet source region Nothing
1366 "I thought I was parsing a character, but I got to the end of\
1367 \ the line without seeing the closing single quote:"
1370 "Add a closing single quote here!"
1373 CharEscape escape ->
1374 toEscapeReport source escape row col
1376 CharNotString width ->
1378 region = toWiderRegion row col width
1380 Report.Report "NEEDS DOUBLE QUOTES" region [] $
1381 Code.toSnippet source region Nothing
1383 "The following string uses single quotes:"
1386 [ "Please switch to double quotes instead:"
1388 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
1390 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
1391 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
1392 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
1393 \ individual characters."
1402toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
1403toStringReport source string row col =
1405 StringEndless_Single ->
1407 region = toRegion row col
1409 Report.Report "ENDLESS STRING" region [] $
1410 Code.toSnippet source region Nothing
1413 "I got to the end of the line without seeing the closing double quote:"
1417 ["Strings","look","like",D.green "\"this\"","with","double"
1418 ,"quotes","on","each","end.","Is","the","closing","double"
1419 ,"quote","missing","in","your","code?"
1421 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
1425 StringEndless_Multi ->
1427 region = toWiderRegion row col 3
1429 Report.Report "ENDLESS STRING" region [] $
1430 Code.toSnippet source region Nothing
1433 "I cannot find the end of this multi-line string:"
1436 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
1437 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
1441 StringEscape escape ->
1442 toEscapeReport source escape row col
1449toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1450toEscapeReport source escape row col =
1454 region = toWiderRegion row col 2
1456 Report.Report "UNKNOWN ESCAPE" region [] $
1457 Code.toSnippet source region Nothing
1460 "Backslashes always start escaped characters, but I do not recognize this one:"
1464 "Valid escape characters include:"
1465 , D.dullyellow $ D.indent 4 $ D.vcat $
1475 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1477 "The last style lets encode ANY character by its Unicode code\
1478 \ point. That means \\u{0009} and \\t are the same. You can use\
1479 \ that style for anything not covered by the other six escapes!"
1483 BadUnicodeFormat width ->
1485 region = toWiderRegion row col width
1487 Report.Report "BAD UNICODE ESCAPE" region [] $
1488 Code.toSnippet source region Nothing
1491 "I ran into an invalid Unicode escape:"
1495 "Here are some examples of valid Unicode escapes:"
1496 , D.dullyellow $ D.indent 4 $ D.vcat $
1503 "Notice that the code point is always surrounded by curly braces.\
1504 \ Maybe you are missing the opening or closing curly brace?"
1507 BadUnicodeCode width ->
1509 region = toWiderRegion row col width
1511 Report.Report "BAD UNICODE ESCAPE" region [] $
1512 Code.toSnippet source region Nothing
1515 "This is not a valid code point:"
1518 "The valid code points are between 0 and 10FFFF inclusive."
1521 BadUnicodeLength width numDigits badCode ->
1523 region = toWiderRegion row col width
1525 Report.Report "BAD UNICODE ESCAPE" region [] $
1526 Code.toSnippet source region Nothing $
1527 if numDigits < 4 then
1530 "Every code point needs at least four digits:"
1533 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1534 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1536 D.fillSep ["Try",D.green suggestion,"instead?"]
1542 "This code point has too many digits:"
1545 ["Valid","code","points","are","between"
1546 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1547 ,"so","try","trimming","any","leading","zeros","until"
1548 ,"you","have","between","four","and","six","digits."
1557toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1558toNumberReport source number row col =
1560 region = toRegion row col
1564 Report.Report "WEIRD NUMBER" region [] $
1565 Code.toSnippet source region Nothing
1568 "I thought I was reading a number, but I ran into some weird stuff here:"
1572 "I recognize numbers in the following formats:"
1573 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1575 "So is there a way to write it like one of those?"
1580 Report.Report "WEIRD NUMBER" region [] $
1581 Code.toSnippet source region Nothing
1584 "Numbers cannot end with a dot like this:"
1587 ["Switching","to",D.green (D.fromChars (show int))
1588 ,"or",D.green (D.fromChars (show int ++ ".0"))
1589 ,"will","work","though!"
1594 Report.Report "WEIRD HEXIDECIMAL" region [] $
1595 Code.toSnippet source region Nothing
1598 "I thought I was reading a hexidecimal number until I got here:"
1602 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1603 \ only recognize things like this:"
1604 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1608 NumberNoLeadingZero ->
1609 Report.Report "LEADING ZEROS" region [] $
1610 Code.toSnippet source region Nothing
1613 "I do not accept numbers with leading zeros:"
1617 "Just delete the leading zeros and it should work!"
1619 "Some languages let you to specify octal numbers by adding a leading zero.\
1620 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1621 \ that, but others probably want it to equal 111. Either path is going to\
1622 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1632toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
1633toOperatorReport source context operator row col =
1637 region = toRegion row col
1639 Report.Report "UNEXPECTED SYMBOL" region [] $
1640 Code.toSnippet source region Nothing
1642 "I was not expecting this dot:"
1645 "Dots are for record access and decimal points, so\
1646 \ they cannot float around on their own. Maybe\
1647 \ there is some extra whitespace?"
1652 region = toRegion row col
1654 Report.Report "UNEXPECTED SYMBOL" region [] $
1655 Code.toSnippet source region Nothing
1658 "I was not expecting this vertical bar:"
1661 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
1666 region = toWiderRegion row col 2
1668 Report.Report "UNEXPECTED ARROW" region [] $
1669 Code.toSnippet source region Nothing $
1670 if isWithin NBranch context then
1673 "I was not expecting to see an arrow here:"
1678 "I think I am parsing a `case` expression right now, so it makes sense to\
1679 \ see arrows around here. This one is confusing me though!"
1682 "I may be getting confused by the indentation. Every pattern in a `case` must be\
1683 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
1684 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
1685 \ indented too far?"
1692 "I was not expecting an arrow here:"
1695 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
1696 \ you want > or >= instead?"
1701 region = toRegion row col
1702 name = getDefName context
1704 Report.Report "UNEXPECTED EQUALS" region [] $
1705 Code.toSnippet source region Nothing
1708 "I was not expecting to see this equals sign:"
1712 D.reflow "Maybe you want == instead? To check if two values are equal?"
1715 if isWithin NRecord context then
1716 "Records look like { x = 3, y = 4 } with the equals sign right\
1717 \ after the field name. So maybe you forgot a comma?"
1719 "I may be getting confused by your indentation. Is this supposed to be part of\
1720 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1721 \ the problem may be a bit before the equals sign. I need all definitions to\
1722 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1723 \ this new definition is indented a bit too much."
1729 region = toRegion row col
1730 name = getDefName context
1732 Report.Report "UNEXPECTED SYMBOL" region [] $
1733 Code.toSnippet source region Nothing $
1736 "I was not expecting to run into the \"has type\" symbol here:"
1741 ["Maybe","you","want",D.green "::","instead?"
1742 ,"To","put","something","on","the","front","of","a","list?"
1745 "The single colon is reserved for type annotations and record types, but I think\
1746 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
1749 "I may be getting confused by your indentation. Is this supposed to be part of\
1750 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1751 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
1752 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1753 \ this new definition is indented a bit too much."
1762toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
1763toLetReport source context let_ startRow startCol =
1765 LetSpace space row col ->
1766 toSpaceReport source space row col
1770 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1771 region = toRegion row col
1773 Report.Report "LET PROBLEM" region [] $
1774 Code.toSnippet source surroundings (Just region)
1777 "I was partway through parsing a `let` expression, but I got stuck here:"
1781 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
1782 ,"keyword","next.","Is","there","a","typo?"
1785 "This can also happen if you are trying to define another value within the `let` but\
1786 \ it is not indented enough. Make sure each definition has exactly the same amount of\
1787 \ spaces before it. They should line up exactly!"
1791 LetDefAlignment _ row col ->
1793 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1794 region = toRegion row col
1796 Report.Report "LET PROBLEM" region [] $
1797 Code.toSnippet source surroundings (Just region)
1800 "I was partway through parsing a `let` expression, but I got stuck here:"
1804 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
1805 ,"keyword","next.","Is","there","a","typo?"
1808 "This can also happen if you are trying to define another value within the `let` but\
1809 \ it is not indented enough. Make sure each definition has exactly the same amount of\
1810 \ spaces before it. The should line up exactly!"
1814 LetDefName row col ->
1815 case Code.whatIsNext source row col of
1816 Code.Keyword keyword ->
1818 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1819 region = toWiderRegion row col (fromIntegral (length keyword))
1821 Report.Report "RESERVED WORD" region [] $
1822 Code.toSnippet source surroundings (Just region)
1825 "I was partway through parsing a `let` expression, but I got stuck here:"
1828 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
1829 \ it is a reserved word! Try using a different name instead."
1833 toUnfinishLetReport source row col startRow startCol $
1835 "I was expecting the name of a definition next."
1837 LetDef name def row col ->
1838 error "TODO LetDef" name def row col
1840 LetDestruct destruct row col ->
1841 error "TODO LetDestruct" destruct row col
1843 LetBody expr row col ->
1844 toExprReport source context expr row col
1846 LetIndentDef row col ->
1847 toUnfinishLetReport source row col startRow startCol $
1849 "I was expecting a value to be defined here."
1851 LetIndentIn row col ->
1852 toUnfinishLetReport source row col startRow startCol $
1854 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
1855 ,"Or","maybe","more","of","that","expression?"
1858 LetIndentBody row col ->
1859 toUnfinishLetReport source row col startRow startCol $
1861 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
1864toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
1865toUnfinishLetReport source row col startRow startCol message =
1867 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1868 region = toRegion row col
1870 Report.Report "UNFINISHED LET" region [] $
1871 Code.toSnippet source surroundings (Just region)
1874 "I was partway through parsing a `let` expression, but I got stuck here:"
1879 "Here is an example with a valid `let` expression for reference:"
1881 [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
1882 , D.indent 2 $ D.fillSep [D.cyan "let"]
1883 , D.indent 4 $ D.fillSep ["fullName","="]
1884 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
1885 , D.indent 2 $ D.fillSep [D.cyan "in"]
1886 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
1889 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
1890 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
1891 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
1892 \ indented a bit more than that. That is important!"
1901toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
1902toCaseReport source context case_ startRow startCol =
1904 CaseSpace space row col ->
1905 toSpaceReport source space row col
1908 toUnfinishCaseReport source row col startRow startCol $
1909 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
1911 CasePattern pattern row col ->
1912 toPatternReport source PCase pattern row col
1914 CaseArrow row col ->
1916 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1917 region = toRegion row col
1919 case Code.whatIsNext source row col of
1920 Code.Keyword keyword ->
1921 Report.Report "RESERVED WORD" region [] $
1922 Code.toSnippet source surroundings (Just region)
1925 "I am partway through parsing a `case` expression, but I got stuck here:"
1928 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
1929 \ patterns, but it is a reserved word. Try using a different name?"
1932 Code.Operator ":" ->
1933 Report.Report "UNEXPECTED OPERATOR" region [] $
1934 Code.toSnippet source surroundings (Just region)
1937 "I am partway through parsing a `case` expression, but I got stuck here:"
1940 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
1941 ,"For","pattern","matching","on","lists?"
1945 Code.Operator "=" ->
1946 Report.Report "UNEXPECTED OPERATOR" region [] $
1947 Code.toSnippet source surroundings (Just region)
1950 "I am partway through parsing a `case` expression, but I got stuck here:"
1953 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
1958 Report.Report "MISSING ARROW" region [] $
1959 Code.toSnippet source surroundings (Just region)
1962 "I am partway through parsing a `case` expression, but I got stuck here:"
1964 addNoteForCaseIndentError $
1966 "I was expecting to see an arrow next."
1969 CaseExpr expr row col ->
1970 toExprReport source (InNode NCase startRow startCol context) expr row col
1972 CaseBranch expr row col ->
1973 toExprReport source (InNode NBranch startRow startCol context) expr row col
1975 CaseIndentOf row col ->
1976 toUnfinishCaseReport source row col startRow startCol $
1977 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
1979 CaseIndentExpr row col ->
1980 toUnfinishCaseReport source row col startRow startCol $
1981 D.reflow "I was expecting to see a expression next."
1983 CaseIndentPattern row col ->
1984 toUnfinishCaseReport source row col startRow startCol $
1985 D.reflow "I was expecting to see a pattern next."
1987 CaseIndentArrow row col ->
1988 toUnfinishCaseReport source row col startRow startCol $
1990 ["I","just","saw","a","pattern,","so","I","was","expecting"
1991 ,"to","see","a",D.dullyellow "->","next."
1994 CaseIndentBranch row col ->
1995 toUnfinishCaseReport source row col startRow startCol $
1997 "I was expecting to see an expression next. What should I do when\
1998 \ I run into this particular pattern?"
2000 CasePatternAlignment indent row col ->
2001 toUnfinishCaseReport source row col startRow startCol $
2003 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
2006toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
2007toUnfinishCaseReport source row col startRow startCol message =
2009 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2010 region = toRegion row col
2012 Report.Report "UNFINISHED CASE" region [] $
2013 Code.toSnippet source surroundings (Just region)
2016 "I was partway through parsing a `case` expression, but I got stuck here:"
2021 "Here is an example of a valid `case` expression for reference."
2023 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2024 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2025 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
2027 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2028 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
2031 "Notice the indentation. Each pattern is aligned, and each branch is indented\
2032 \ a bit more than the corresponding pattern. That is important!"
2037addNoteForCaseIndentError :: D.Doc -> D.Doc
2038addNoteForCaseIndentError message =
2043 "Sometimes I get confused by indentation, so try to make your `case` look\
2044 \ something like this:"
2046 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2047 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2048 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
2050 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2051 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
2054 "Notice the indentation! Each pattern is aligned, and each branch is indented\
2055 \ a bit more than the corresponding pattern. That is important!"
2063toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
2064toIfReport source context if_ startRow startCol =
2066 IfSpace space row col ->
2067 toSpaceReport source space row col
2071 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2072 region = toRegion row col
2074 Report.Report "UNFINISHED IF" region [] $
2075 Code.toSnippet source surroundings (Just region)
2078 "I was expecting to see more of this `if` expression, but I got stuck here:"
2081 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
2087 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2088 region = toRegion row col
2090 Report.Report "UNFINISHED IF" region [] $
2091 Code.toSnippet source surroundings (Just region)
2094 "I was expecting to see more of this `if` expression, but I got stuck here:"
2097 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
2101 IfElseBranchStart row col ->
2103 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2104 region = toRegion row col
2106 Report.Report "UNFINISHED IF" region [] $
2107 Code.toSnippet source surroundings (Just region)
2110 "I just saw the start of an `else` branch, but then I got stuck here:"
2113 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2116 IfCondition expr row col ->
2117 toExprReport source (InNode NCond startRow startCol context) expr row col
2119 IfThenBranch expr row col ->
2120 toExprReport source (InNode NThen startRow startCol context) expr row col
2122 IfElseBranch expr row col ->
2123 toExprReport source (InNode NElse startRow startCol context) expr row col
2125 IfIndentCondition row col ->
2127 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2128 region = toRegion row col
2130 Report.Report "UNFINISHED IF" region [] $
2131 Code.toSnippet source surroundings (Just region)
2134 "I was expecting to see more of this `if` expression, but I got stuck here:"
2138 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
2139 ,"that","evaluates","to","True","or","False."
2142 "I can be confused by indentation. Maybe something is not indented enough?"
2146 IfIndentThen row col ->
2148 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2149 region = toRegion row col
2151 Report.Report "UNFINISHED IF" region [] $
2152 Code.toSnippet source surroundings (Just region)
2155 "I was expecting to see more of this `if` expression, but I got stuck here:"
2159 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
2162 "I can be confused by indentation. Maybe something is not indented enough?"
2166 IfIndentThenBranch row col ->
2168 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2169 region = toRegion row col
2171 Report.Report "UNFINISHED IF" region [] $
2172 Code.toSnippet source surroundings (Just region)
2175 "I got stuck after the start of this `then` branch:"
2179 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2181 "I can be confused by indentation, so if the `then` branch is already\
2182 \ present, it may not be indented enough for me to recognize it."
2186 IfIndentElseBranch row col ->
2188 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2189 region = toRegion row col
2191 Report.Report "UNFINISHED IF" region [] $
2192 Code.toSnippet source surroundings (Just region)
2195 "I got stuck after the start of this `else` branch:"
2199 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2201 "I can be confused by indentation, so if the `else` branch is already\
2202 \ present, it may not be indented enough for me to recognize it."
2206 IfIndentElse row col ->
2208 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2209 region = toRegion row col
2211 Report.Report "UNFINISHED IF" region [] $
2212 Code.toSnippet source surroundings (Just region)
2215 "I was expecting to see an `else` branch after this:"
2219 "I know what to do when the condition is `True`, but not when it is `False`."
2221 ["Add","an",D.cyan "else","branch","to","handle","that","scenario!"]
2230toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
2231toRecordReport source context record startRow startCol =
2233 RecordOpen row col ->
2235 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2236 region = toRegion row col
2238 case Code.whatIsNext source row col of
2239 Code.Keyword keyword ->
2240 Report.Report "RESERVED WORD" region [] $
2241 Code.toSnippet source surroundings (Just region)
2244 "I just started parsing a record, but I got stuck on this field name:"
2247 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
2248 \ that is a reserved word. Try using a different name!"
2252 Report.Report "UNFINISHED RECORD" region [] $
2253 Code.toSnippet source surroundings (Just region)
2256 "I just started parsing a record, but I got stuck here:"
2259 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
2260 ,"so","I","was","expecting","to","see","a","field","name","next."
2264 RecordEnd row col ->
2266 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2267 region = toRegion row col
2269 Report.Report "UNFINISHED RECORD" region [] $
2270 Code.toSnippet source surroundings (Just region)
2273 "I am partway through parsing a record, but I got stuck here:"
2277 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
2278 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
2281 "When I get stuck like this, it usually means that there is a missing parenthesis\
2282 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2286 RecordField row col ->
2288 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2289 region = toRegion row col
2291 case Code.whatIsNext source row col of
2292 Code.Keyword keyword ->
2293 Report.Report "RESERVED WORD" region [] $
2294 Code.toSnippet source surroundings (Just region)
2297 "I am partway through parsing a record, but I got stuck on this field name:"
2300 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
2301 \ that is a reserved word. Try using a different name!"
2305 Report.Report "UNFINISHED RECORD" region [] $
2306 Code.toSnippet source surroundings (Just region)
2309 "I am partway through parsing a record, but I got stuck after that last comma:"
2311 addNoteForRecordError $
2313 "Trailing commas are not allowed in records, so I was expecting to see another\
2314 \ record field defined next. If you are done defining the record, the fix may\
2315 \ be to delete that last comma?"
2318 RecordEquals row col ->
2320 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2321 region = toRegion row col
2323 Report.Report "UNFINISHED RECORD" region [] $
2324 Code.toSnippet source surroundings (Just region)
2327 "I am partway through parsing a record, but I got stuck here:"
2329 addNoteForRecordError $
2331 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
2332 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
2336 RecordExpr expr row col ->
2337 toExprReport source (InNode NRecord startRow startCol context) expr row col
2339 RecordSpace space row col ->
2340 toSpaceReport source space row col
2342 RecordIndentOpen row col ->
2344 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2345 region = toRegion row col
2347 Report.Report "UNFINISHED RECORD" region [] $
2348 Code.toSnippet source surroundings (Just region)
2351 "I just saw the opening curly brace of a record, but then I got stuck here:"
2353 addNoteForRecordIndentError $
2355 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
2356 ,"Try","defining","some","fields","of","your","own?"
2360 RecordIndentEnd row col ->
2362 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2363 region = toRegion row col
2365 Report.Report "UNFINISHED RECORD" region [] $
2366 Code.toSnippet source surroundings (Just region)
2369 "I was expecting to see a closing curly brace next:"
2371 addNoteForRecordIndentError $
2373 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
2377 RecordIndentField row col ->
2379 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2380 region = toRegion row col
2382 Report.Report "UNFINISHED RECORD" region [] $
2383 Code.toSnippet source surroundings (Just region)
2386 "I am partway through parsing a record, but I got stuck after that last comma:"
2388 addNoteForRecordError $
2390 "Trailing commas are not allowed in records, so the fix may be to\
2391 \ delete that last comma? Or maybe you were in the middle of defining\
2392 \ an additional field?"
2395 RecordIndentEquals row col ->
2397 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2398 region = toRegion row col
2400 Report.Report "UNFINISHED RECORD" region [] $
2401 Code.toSnippet source surroundings (Just region)
2404 "I am partway through parsing a record. I just saw a record\
2405 \ field, so I was expecting to see an equals sign next:"
2407 addNoteForRecordIndentError $
2409 ["Try","putting","an",D.green "=","followed","by","an","expression?"
2413 RecordIndentExpr row col ->
2415 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2416 region = toRegion row col
2418 Report.Report "UNFINISHED RECORD" region [] $
2419 Code.toSnippet source surroundings (Just region)
2422 "I am partway through parsing a record, and I was expecting to run into an expression next:"
2424 addNoteForRecordIndentError $
2426 ["Try","putting","something,","like"
2427 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
2432addNoteForRecordError :: D.Doc -> D.Doc
2433addNoteForRecordError normalRecommendation =
2435 normalRecommendation
2438 "If you are trying to define a record across multiple lines, I recommend using this format:"
2439 , D.indent 4 $ D.vcat $
2440 [ "{ name = \"Alice\""
2446 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
2447 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
2448 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2452addNoteForRecordIndentError :: D.Doc -> D.Doc
2453addNoteForRecordIndentError normalRecommendation =
2455 normalRecommendation
2458 "I may be confused by indentation. For example, if you are trying to define\
2459 \ a record across multiple lines, I recommend using this format:"
2460 , D.indent 4 $ D.vcat $
2467 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
2468 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
2469 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2477toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
2478toTupleReport source context tuple startRow startCol =
2480 TupleExpr expr row col ->
2481 toExprReport source (InNode NParens startRow startCol context) expr row col
2483 TupleSpace space row col ->
2484 toSpaceReport source space row col
2488 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2489 region = toRegion row col
2491 Report.Report "UNFINISHED PARENTHESES" region [] $
2492 Code.toSnippet source surroundings (Just region)
2495 "I was expecting to see a closing parentheses next, but I got stuck here:"
2498 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
2500 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
2501 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
2502 \ or missing brackets) that is confusing me."
2506 TupleOperatorClose row col ->
2508 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2509 region = toRegion row col
2511 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
2512 Code.toSnippet source surroundings (Just region)
2514 D.reflow "I was expecting a closing parenthesis here:"
2517 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
2519 "I think I am parsing an operator function right now, so I am expecting to see\
2520 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
2525 TupleOperatorReserved operator row col ->
2527 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2528 region = toRegion row col
2530 Report.Report "UNEXPECTED SYMBOL" region [] $
2531 Code.toSnippet source surroundings (Just region)
2534 "I ran into an unexpected symbol here:"
2538 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
2539 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
2540 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
2541 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
2542 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
2545 TupleIndentExpr1 row col ->
2547 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2548 region = toRegion row col
2550 Report.Report "UNFINISHED PARENTHESES" region [] $
2551 Code.toSnippet source surroundings (Just region)
2554 "I just saw an open parenthesis, so I was expecting to see an expression next."
2558 ["Something","like",D.dullyellow "(4 + 5)","or"
2559 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
2560 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
2563 "I can get confused by indentation in cases like this, so\
2564 \ maybe you have an expression but it is not indented enough?"
2568 TupleIndentExprN row col ->
2570 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2571 region = toRegion row col
2573 Report.Report "UNFINISHED TUPLE" region [] $
2574 Code.toSnippet source surroundings (Just region)
2577 "I think I am in the middle of parsing a tuple. I just saw a comma, so I was expecting to see expression next."
2581 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
2582 ,D.dullyellow "(\"Tom\",42)" <> ","
2583 ,"so","I","think","there","is","an","expression","missing","here?"
2586 "I can get confused by indentation in cases like this, so\
2587 \ maybe you have an expression but it is not indented enough?"
2591 TupleIndentEnd row col ->
2593 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2594 region = toRegion row col
2596 Report.Report "UNFINISHED PARENTHESES" region [] $
2597 Code.toSnippet source surroundings (Just region)
2600 "I was expecting to see a closing parenthesis next:"
2603 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
2605 "I can get confused by indentation in cases like this, so\
2606 \ maybe you have a closing parenthesis but it is not indented enough?"
2611toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
2612toListReport source context list startRow startCol =
2614 ListSpace space row col ->
2615 toSpaceReport source space row col
2619 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2620 region = toRegion row col
2622 Report.Report "UNFINISHED LIST" region [] $
2623 Code.toSnippet source surroundings (Just region)
2626 "I am partway through parsing a list, but I got stuck here:"
2630 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2631 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2634 "When I get stuck like this, it usually means that there is a missing parenthesis\
2635 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2639 ListExpr expr row col ->
2643 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
2644 region = toRegion r c
2646 Report.Report "UNFINISHED LIST" region [] $
2647 Code.toSnippet source surroundings (Just region)
2650 "I was expecting to see another list entry after that last comma:"
2654 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2656 "I recommend using the following format for lists that span multiple lines:"
2657 , D.indent 4 $ D.vcat $
2664 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2665 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2666 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2671 toExprReport source (InNode NList startRow startCol context) expr row col
2675 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2676 region = toRegion row col
2678 Report.Report "UNFINISHED LIST" region [] $
2679 Code.toSnippet source surroundings (Just region)
2682 "I am partway through parsing a list, but I got stuck here:"
2686 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2687 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2690 "When I get stuck like this, it usually means that there is a missing parenthesis\
2691 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2695 ListIndentOpen row col ->
2697 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2698 region = toRegion row col
2700 Report.Report "UNFINISHED LIST" region [] $
2701 Code.toSnippet source surroundings (Just region)
2704 "I cannot find the end of this list:"
2708 ["You","could","change","it","to","something","like"
2709 ,D.dullyellow "[3,4,5]"
2711 ,D.dullyellow "[]" <> "."
2712 ,"Anything","where","there","is","an","open","and","close","square","brace,"
2713 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
2716 "I may be confused by indentation. For example, if you are trying to define\
2717 \ a list across multiple lines, I recommend using this format:"
2718 , D.indent 4 $ D.vcat $
2725 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2726 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2727 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2731 ListIndentEnd row col ->
2733 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2734 region = toRegion row col
2736 Report.Report "UNFINISHED LIST" region [] $
2737 Code.toSnippet source surroundings (Just region)
2740 "I cannot find the end of this list:"
2744 ["You","can","just","add","a","closing",D.dullyellow "]"
2745 ,"right","here,","and","I","will","be","all","set!"
2748 "I may be confused by indentation. For example, if you are trying to define\
2749 \ a list across multiple lines, I recommend using this format:"
2750 , D.indent 4 $ D.vcat $
2757 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2758 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2759 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2763 ListIndentExpr row col ->
2765 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2766 region = toRegion row col
2768 Report.Report "UNFINISHED LIST" region [] $
2769 Code.toSnippet source surroundings (Just region)
2772 "I was expecting to see another list entry after this comma:"
2776 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2778 "I recommend using the following format for lists that span multiple lines:"
2779 , D.indent 4 $ D.vcat $
2786 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2787 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2788 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2793toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
2794toFuncReport source context func startRow startCol =
2796 FuncSpace space row col ->
2797 toSpaceReport source space row col
2799 FuncArg pattern row col ->
2800 toPatternReport source PArg pattern row col
2802 FuncBody expr row col ->
2803 toExprReport source (InNode NFunc startRow startCol context) expr row col
2805 FuncArrow row col ->
2807 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2808 region = toRegion row col
2810 case Code.whatIsNext source row col of
2811 Code.Keyword keyword ->
2812 Report.Report "RESERVED WORD" region [] $
2813 Code.toSnippet source surroundings (Just region)
2816 "I was parsing an anonymous function, but I got stuck here:"
2819 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
2820 \ it is a reserved word in this language. Try using a different argument name!"
2824 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2825 Code.toSnippet source surroundings (Just region)
2828 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2831 ["The","syntax","for","anonymous","functions","is"
2832 ,D.dullyellow "(\\x -> x + 1)"
2833 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2837 FuncIndentArg row col ->
2839 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2840 region = toRegion row col
2842 Report.Report "MISSING ARGUMENT" region [] $
2843 Code.toSnippet source surroundings (Just region)
2846 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
2850 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
2851 ,"Anything","that","starts","with","a","lower","case","letter!"
2854 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
2855 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
2856 \ like a better idea at the time!"
2860 FuncIndentArrow row col ->
2862 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2863 region = toRegion row col
2865 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2866 Code.toSnippet source surroundings (Just region)
2869 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2873 ["The","syntax","for","anonymous","functions","is"
2874 ,D.dullyellow "(\\x -> x + 1)"
2875 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2878 "It is possible that I am confused about indetation! I generally recommend\
2879 \ switching to named functions if the definition cannot fit inline nicely, so\
2880 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2881 \ the whole thing out into a named function. Things tend to be clearer that way!"
2885 FuncIndentBody row col ->
2887 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2888 region = toRegion row col
2890 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2891 Code.toSnippet source surroundings (Just region)
2894 "I was expecting to see the body of your anonymous function next:"
2898 ["The","syntax","for","anonymous","functions","is"
2899 ,D.dullyellow "(\\x -> x + 1)"
2900 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
2903 "It is possible that I am confused about indetation! I generally recommend\
2904 \ switching to named functions if the definition cannot fit inline nicely, so\
2905 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2906 \ the whole thing out into a named function. Things tend to be clearer that way!"
2920toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
2921toPatternReport source context pattern startRow startCol =
2923 PRecord record row col ->
2924 toPRecordReport source record row col
2926 PTuple tuple row col ->
2927 toPTupleReport source context tuple row col
2929 PList list row col ->
2930 toPListReport source context list row col
2933 case Code.whatIsNext source row col of
2934 Code.Keyword keyword ->
2936 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2937 region = toWiderRegion row col (fromIntegral (length keyword))
2940 PArg -> "an argument"
2941 PCase -> "a pattern"
2943 Report.Report "RESERVED WORD" region [] $
2944 Code.toSnippet source surroundings (Just region)
2947 "It looks like you are trying to use `" ++ keyword ++ "` as " ++ aThing ++ ":"
2950 "This is a reserved word! Try using some other name?"
2956 PChar char row col ->
2957 toCharReport source char row col
2959 PString string row col ->
2960 toStringReport source string row col
2962 PNumber number row col ->
2963 toNumberReport source number row col
2965 PFloat width row col ->
2967 region = toWiderRegion row col width
2969 Report.Report "UNEXPECTED PATTERN" region [] $
2970 Code.toSnippet source region Nothing
2973 "I cannot pattern match with floating point numbers:"
2976 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
2977 ,"to","check","that","they","are","nearby","with","some","sort","of"
2978 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
2984 region = toRegion row col
2986 Report.Report "UNFINISHED PATTERN" region [] $
2987 Code.toSnippet source region Nothing $
2990 "I was expecting to see a variable name after the `as` keyword:"
2994 ["The","`as`","keyword","lets","you","write","patterns","like"
2995 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
2996 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
2997 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
2998 ,"thing","with",D.dullyellow "point."
3001 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
3002 \ people just want to use `as` as a variable name though. Try using a different name\
3007 PWildcardNotVar name width row col ->
3009 region = toWiderRegion row col (fromIntegral width)
3011 case dropWhile (=='_') (Name.toChars name) of
3012 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
3013 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
3015 Report.Report "UNEXPECTED NAME" region [] $
3016 Code.toSnippet source region Nothing $
3019 "Variable names cannot start with underscores like this:"
3022 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
3023 ,"ignore","the","value,","or","you","can","have","a","name","like"
3024 ] ++ examples ++ ["to","use","the","matched","value." ]
3027 PSpace space row col ->
3028 toSpaceReport source space row col
3030 PIndentStart row col ->
3031 error "TODO PIndentStart" row col
3033 PIndentAlias row col ->
3035 region = toRegion row col
3037 Report.Report "UNFINISHED PATTERN" region [] $
3038 Code.toSnippet source region Nothing $
3041 "I was expecting to see a variable name after the `as` keyword:"
3045 ["The","`as`","keyword","lets","you","write","patterns","like"
3046 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
3047 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
3048 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
3049 ,"thing","with",D.dullyellow "point."
3052 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
3053 \ people just want to use `as` as a variable name though. Try using a different name\
3059toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
3060toPRecordReport source record startRow startCol =
3062 PRecordOpen row col ->
3063 toUnfinishRecordPatternReport source row col startRow startCol $
3064 D.reflow "I was expecting to see a field name next."
3066 PRecordEnd row col ->
3067 toUnfinishRecordPatternReport source row col startRow startCol $
3069 ["I","was","expecting","to","see","a","closing","curly","brace","next."
3070 ,"Try","adding","a",D.dullyellow "}","here?"
3073 PRecordField row col ->
3074 case Code.whatIsNext source row col of
3075 Code.Keyword keyword ->
3077 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3078 region = toWiderRegion row col (fromIntegral (length keyword))
3080 Report.Report "RESERVED WORD" region [] $
3081 Code.toSnippet source surroundings (Just region)
3084 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
3087 "This is a reserved word, not available for variable names. Try another name!"
3091 toUnfinishRecordPatternReport source row col startRow startCol $
3092 D.reflow "I was expecting to see a field name next."
3094 PRecordSpace space row col ->
3095 toSpaceReport source space row col
3097 PRecordIndentOpen row col ->
3098 toUnfinishRecordPatternReport source row col startRow startCol $
3099 D.reflow "I was expecting to see a field name next."
3101 PRecordIndentEnd row col ->
3102 toUnfinishRecordPatternReport source row col startRow startCol $
3104 ["I","was","expecting","to","see","a","closing","curly","brace","next."
3105 ,"Try","adding","a",D.dullyellow "}","here?"
3108 PRecordIndentField row col ->
3109 toUnfinishRecordPatternReport source row col startRow startCol $
3110 D.reflow "I was expecting to see a field name next."
3113toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3114toUnfinishRecordPatternReport source row col startRow startCol message =
3116 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3117 region = toRegion row col
3119 Report.Report "UNFINISHED RECORD PATTERN" region [] $
3120 Code.toSnippet source surroundings (Just region)
3123 "I was partway through parsing a record pattern, but I got stuck here:"
3128 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
3129 ,"where","you","list","the","field","names","you","want","to","access."
3136toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
3137toPTupleReport source context tuple startRow startCol =
3139 PTupleOpen row col ->
3140 case Code.whatIsNext source row col of
3141 Code.Keyword keyword ->
3143 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3144 region = toWiderRegion row col (fromIntegral (length keyword))
3146 Report.Report "RESERVED WORD" region [] $
3147 Code.toSnippet source surroundings (Just region)
3150 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
3153 "This is a reserved word! Try using some other name?"
3158 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3159 region = toRegion row col
3161 Report.Report "UNFINISHED PARENTHESES" region [] $
3162 Code.toSnippet source surroundings (Just region)
3165 "I just saw an open parenthesis, but I got stuck here:"
3168 ["I","was","expecting","so","see","a","pattern","next."
3169 ,"Maybe","it","will","end","up","being","something"
3170 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3174 PTupleEnd row col ->
3176 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3177 region = toRegion row col
3179 Report.Report "UNFINISHED PARENTHESES" region [] $
3180 Code.toSnippet source surroundings (Just region) $
3183 "I was expecting a closing parenthesis next:"
3185 D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3188 PTupleExpr pattern row col ->
3189 toPatternReport source context pattern row col
3191 PTupleSpace space row col ->
3192 toSpaceReport source space row col
3194 PTupleIndentEnd row col ->
3196 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3197 region = toRegion row col
3199 Report.Report "UNFINISHED PARENTHESES" region [] $
3200 Code.toSnippet source surroundings (Just region) $
3203 "I was expecting a closing parenthesis next:"
3206 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3208 "I can get confused by indentation in cases like this, so\
3209 \ maybe you have a closing parenthesis but it is not indented enough?"
3213 PTupleIndentExpr1 row col ->
3215 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3216 region = toRegion row col
3218 Report.Report "UNFINISHED PARENTHESES" region [] $
3219 Code.toSnippet source surroundings (Just region) $
3222 "I just saw an open parenthesis, but then I got stuck here:"
3225 ["I","was","expecting","so","see","a","pattern","next."
3226 ,"Maybe","it","will","end","up","being","something"
3227 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3231 PTupleIndentExprN row col ->
3233 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3234 region = toRegion row col
3236 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
3237 Code.toSnippet source surroundings (Just region) $
3240 "I am partway through parsing a tuple pattern, but I got stuck here:"
3244 ["I","was","expecting","so","see","a","pattern","next."
3245 ,"I","am","expecting","the","final","result","to","be","something"
3246 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
3249 "I can get confused by indentation in cases like this, so the problem\
3250 \ may be that the next part is not indented enough?"
3255toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
3256toPListReport source context list startRow startCol =
3258 PListOpen row col ->
3259 case Code.whatIsNext source row col of
3260 Code.Keyword keyword ->
3262 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3263 region = toWiderRegion row col (fromIntegral (length keyword))
3265 Report.Report "RESERVED WORD" region [] $
3266 Code.toSnippet source surroundings (Just region)
3269 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
3272 "This is a reserved word though! Try using some other name?"
3277 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3278 region = toRegion row col
3280 Report.Report "UNFINISHED LIST PATTERN" region [] $
3281 Code.toSnippet source surroundings (Just region) $
3284 "I just saw an open square bracket, but then I got stuck here:"
3286 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3291 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3292 region = toRegion row col
3294 Report.Report "UNFINISHED LIST PATTERN" region [] $
3295 Code.toSnippet source surroundings (Just region) $
3298 "I was expecting a closing square bracket to end this list pattern:"
3300 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3303 PListExpr pattern row col ->
3304 toPatternReport source context pattern row col
3306 PListSpace space row col ->
3307 toSpaceReport source space row col
3309 PListIndentOpen row col ->
3311 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3312 region = toRegion row col
3314 Report.Report "UNFINISHED LIST PATTERN" region [] $
3315 Code.toSnippet source surroundings (Just region) $
3318 "I just saw an open square bracket, but then I got stuck here:"
3321 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3323 "I can get confused by indentation in cases like this, so\
3324 \ maybe there is something next, but it is not indented enough?"
3328 PListIndentEnd row col ->
3330 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3331 region = toRegion row col
3333 Report.Report "UNFINISHED LIST PATTERN" region [] $
3334 Code.toSnippet source surroundings (Just region) $
3337 "I was expecting a closing square bracket to end this list pattern:"
3340 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3342 "I can get confused by indentation in cases like this, so\
3343 \ maybe you have a closing square bracket but it is not indented enough?"
3347 PListIndentExpr row col ->
3349 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3350 region = toRegion row col
3352 Report.Report "UNFINISHED LIST PATTERN" region [] $
3353 Code.toSnippet source surroundings (Just region) $
3356 "I am partway through parsing a list pattern, but I got stuck here:"
3360 "I was expecting to see another pattern next. Maybe a variable name."
3362 "I can get confused by indentation in cases like this, so\
3363 \ maybe there is more to this pattern but it is not indented enough?"
3372toTypeReport :: Code.Source -> Type -> Row -> Col -> Report.Report
3373toTypeReport source tipe startRow startCol =
3375 TRecord record row col ->
3376 toTRecordReport source record row col
3378 TTuple tuple row col ->
3379 toTTupleReport source tuple row col
3382 error "TODO TVariant" row col startRow startCol
3385 error "TODO TArrow" row col
3388 error "TODO TStart" row col
3390 TSpace space row col ->
3391 toSpaceReport source space row col
3393 TIndentStart row col ->
3394 error "TODO TIndentStart" row col
3398toTRecordReport :: Code.Source -> TRecord -> Row -> Col -> Report.Report
3399toTRecordReport source record startRow startCol =
3401 TRecordOpen row col ->
3402 error "TODO TRecordOpen" row col startRow startCol
3404 TRecordEnd row col ->
3405 error "TODO TRecordEnd" row col
3407 TRecordField row col ->
3408 error "TODO TRecordField" row col
3410 TRecordColon row col ->
3411 error "TODO TRecordColon" row col
3413 TRecordType tipe row col ->
3414 error "TODO TRecordType" tipe row col
3416 TRecordSpace space row col ->
3417 toSpaceReport source space row col
3419 TRecordIndentOpen row col ->
3420 error "TODO TRecordIndentOpen" row col
3422 TRecordIndentField row col ->
3423 error "TODO TRecordIndentField" row col
3425 TRecordIndentColon row col ->
3426 error "TODO TRecordIndentColon" row col
3428 TRecordIndentType row col ->
3429 error "TODO TRecordIndentType" row col
3431 TRecordIndentEnd row col ->
3432 error "TODO TRecordIndentEnd" row col
3436toTTupleReport :: Code.Source -> TTuple -> Row -> Col -> Report.Report
3437toTTupleReport source tuple startRow startCol =
3439 TTupleOpen row col ->
3440 error "TODO TTupleOpen" row col startRow startCol
3442 TTupleEnd row col ->
3443 error "TODO TTupleEnd" row col
3445 TTupleType tipe row col ->
3446 error "TODO TTupleType" tipe row col
3448 TTupleSpace space row col ->
3449 toSpaceReport source space row col
3451 TTupleIndentOpen row col ->
3452 error "TODO TTupleIndentOpen" row col
3454 TTupleIndentType row col ->
3455 error "TODO TTupleIndentType" row col
3457 TTupleIndentEnd row col ->
3458 error "TODO TTupleIndentEnd" row col
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