1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Syntax
48import Prelude hiding (Char, String)
49import qualified Data.Char as Char
50import qualified Data.Name as Name
51import Data.Word (Word16)
52import Numeric (showHex)
54import qualified Elm.ModuleName as ModuleName
55import Parse.Primitives (Row, Col)
56import Parse.Symbol (BadOperator(..))
57import qualified Reporting.Annotation as A
58import qualified Reporting.Doc as D
59import qualified Reporting.Report as Report
60import qualified Reporting.Render.Code as Code
68 = ModuleNameUnspecified ModuleName.Raw
69 | ModuleNameMismatch ModuleName.Raw (A.Located ModuleName.Raw)
70 | UnexpectedPort A.Region
80 = ModuleSpace Space Row Col
81 | ModuleBadEnd Row Col
83 | ModuleProblem Row Col
85 | ModuleExposing Exposing Row Col
87 | PortModuleProblem Row Col
88 | PortModuleName Row Col
89 | PortModuleExposing Exposing Row Col
99 | ImportExposing Row Col
100 | ImportExposingList Exposing Row Col
101 | ImportEnd Row Col -- different based on col=1 or if greater
103 | ImportIndentName Row Col
104 | ImportIndentAlias Row Col
105 | ImportIndentExposingList Row Col
109 | Declarations Decl Row Col
113 = ExposingSpace Space Row Col
114 | ExposingStart Row Col
115 | ExposingValue Row Col
116 | ExposingOperator Row Col
117 | ExposingOperatorReserved BadOperator Row Col
118 | ExposingOperatorRightParen Row Col
119 | ExposingTypePrivacy Row Col
120 | ExposingEnd Row Col
122 | ExposingIndentEnd Row Col
123 | ExposingIndentValue Row Col
132 | DeclSpace Space Row Col
135 | DeclType DeclType Row Col
136 | DeclDef Name.Name DeclDef Row Col
138 | DeclFreshLineAfterDocComment Row Col
142 = DeclDefSpace Space Row Col
143 | DeclDefEquals Row Col
144 | DeclDefType Type Row Col
145 | DeclDefArg Pattern Row Col
146 | DeclDefBody Expr Row Col
147 | DeclDefNameRepeat Row Col
148 | DeclDefNameMatch Name.Name Row Col
150 | DeclDefIndentType Row Col
151 | DeclDefIndentEquals Row Col
152 | DeclDefIndentBody Row Col
156 = PortSpace Space Row Col
159 | PortType Type Row Col
160 | PortIndentName Row Col
161 | PortIndentColon Row Col
162 | PortIndentType Row Col
170 = DT_Space Space Row Col
172 | DT_Alias TypeAlias Row Col
173 | DT_Union CustomType Row Col
175 | DT_IndentName Row Col
179 = AliasSpace Space Row Col
181 | AliasEquals Row Col
182 | AliasBody Type Row Col
184 | AliasIndentEquals Row Col
185 | AliasIndentBody Row Col
189 = CT_Space Space Row Col
194 | CT_VariantArg Type Row Col
196 | CT_IndentEquals Row Col
197 | CT_IndentBar Row Col
198 | CT_IndentAfterBar Row Col
199 | CT_IndentAfterEquals Row Col
211 | Record Record Row Col
212 | Tuple Tuple Row Col
217 | OperatorRight Name.Name Row Col
218 | OperatorReserved BadOperator Row Col
222 | String String Row Col
223 | Number Number Row Col
224 | Space Space Row Col
225 | EndlessShader Row Col
226 | ShaderProblem [Char.Char] Row Col
227 | IndentOperatorRight Name.Name Row Col
233 | RecordField Row Col
234 | RecordEquals Row Col
235 | RecordExpr Expr Row Col
236 | RecordSpace Space Row Col
238 | RecordIndentOpen Row Col
239 | RecordIndentEnd Row Col
240 | RecordIndentField Row Col
241 | RecordIndentEquals Row Col
242 | RecordIndentExpr Row Col
246 = TupleExpr Expr Row Col
247 | TupleSpace Space Row Col
249 | TupleOperatorClose Row Col
250 | TupleOperatorReserved BadOperator Row Col
252 | TupleIndentExpr1 Row Col
253 | TupleIndentExprN Row Col
254 | TupleIndentEnd Row Col
258 = ListSpace Space Row Col
260 | ListExpr Expr Row Col
263 | ListIndentOpen Row Col
264 | ListIndentEnd Row Col
265 | ListIndentExpr Row Col
269 = FuncSpace Space Row Col
270 | FuncArg Pattern Row Col
271 | FuncBody Expr Row Col
274 | FuncIndentArg Row Col
275 | FuncIndentArrow Row Col
276 | FuncIndentBody Row Col
280 = CaseSpace Space Row Col
282 | CasePattern Pattern Row Col
284 | CaseExpr Expr Row Col
285 | CaseBranch Expr Row Col
287 | CaseIndentOf Row Col
288 | CaseIndentExpr Row Col
289 | CaseIndentPattern Row Col
290 | CaseIndentArrow Row Col
291 | CaseIndentBranch Row Col
292 | CasePatternAlignment Word16 Row Col
296 = IfSpace Space Row Col
299 | IfElseBranchStart Row Col
301 | IfCondition Expr Row Col
302 | IfThenBranch Expr Row Col
303 | IfElseBranch Expr Row Col
305 | IfIndentCondition Row Col
306 | IfIndentThen Row Col
307 | IfIndentThenBranch Row Col
308 | IfIndentElseBranch Row Col
309 | IfIndentElse Row Col
313 = LetSpace Space Row Col
315 | LetDefAlignment Word16 Row Col
317 | LetDef Name.Name Def Row Col
318 | LetDestruct Destruct Row Col
319 | LetBody Expr Row Col
320 | LetIndentDef Row Col
321 | LetIndentIn Row Col
322 | LetIndentBody Row Col
326 = DefSpace Space Row Col
327 | DefType Type Row Col
328 | DefNameRepeat Row Col
329 | DefNameMatch Name.Name Row Col
330 | DefArg Pattern Row Col
332 | DefBody Expr Row Col
333 | DefIndentEquals Row Col
334 | DefIndentType Row Col
335 | DefIndentBody Row Col
336 | DefAlignment Word16 Row Col
340 = DestructSpace Space Row Col
341 | DestructPattern Pattern Row Col
342 | DestructEquals Row Col
343 | DestructBody Expr Row Col
344 | DestructIndentEquals Row Col
345 | DestructIndentBody Row Col
353 = PRecord PRecord Row Col
354 | PTuple PTuple Row Col
355 | PList PList Row Col
359 | PString String Row Col
360 | PNumber Number Row Col
361 | PFloat Word16 Row Col
363 | PWildcardNotVar Name.Name Int Row Col
364 | PSpace Space Row Col
366 | PIndentStart Row Col
367 | PIndentAlias Row Col
371 = PRecordOpen Row Col
373 | PRecordField Row Col
374 | PRecordSpace Space Row Col
376 | PRecordIndentOpen Row Col
377 | PRecordIndentEnd Row Col
378 | PRecordIndentField Row Col
384 | PTupleExpr Pattern Row Col
385 | PTupleSpace Space Row Col
387 | PTupleIndentEnd Row Col
388 | PTupleIndentExpr1 Row Col
389 | PTupleIndentExprN Row Col
395 | PListExpr Pattern Row Col
396 | PListSpace Space Row Col
398 | PListIndentOpen Row Col
399 | PListIndentEnd Row Col
400 | PListIndentExpr Row Col
408 = TRecord TRecord Row Col
409 | TTuple TTuple Row Col
412 | TSpace Space Row Col
414 | TIndentStart Row Col
418 = TRecordOpen Row Col
421 | TRecordField Row Col
422 | TRecordColon Row Col
423 | TRecordType Type Row Col
425 | TRecordSpace Space Row Col
427 | TRecordIndentOpen Row Col
428 | TRecordIndentField Row Col
429 | TRecordIndentColon Row Col
430 | TRecordIndentType Row Col
431 | TRecordIndentEnd Row Col
437 | TTupleType Type Row Col
438 | TTupleSpace Space Row Col
440 | TTupleIndentType1 Row Col
441 | TTupleIndentTypeN Row Col
442 | TTupleIndentEnd Row Col
452 | CharNotString Word16
456 = StringEndless_Single
457 | StringEndless_Multi
458 | StringEscape Escape
463 | BadUnicodeFormat Word16
464 | BadUnicodeCode Word16
465 | BadUnicodeLength Word16 Int Int
472 | NumberNoLeadingZero
481 | EndlessMultiComment
488toReport :: Code.Source -> Error -> Report.Report
491 ModuleNameUnspecified name ->
493 region = toRegion 1 1
495 Report.Report "MODULE NAME MISSING" region [] $
498 "I need the module name to be declared at the top of this file, like this:"
499 , D.indent 4 $ D.fillSep $
500 [ D.cyan "module", D.fromName name, D.cyan "exposing", "(..)" ]
502 "Try adding that as the first line of your file!"
504 "It is best to replace (..) with an explicit list of types and\
505 \ functions you want to expose. When you know a value is only used\
506 \ within this module, you can refactor without worrying about uses\
507 \ elsewhere. Limiting exposed values can also speed up compilation\
508 \ because I can skip a bunch of work if I see that the exposed API\
512 ModuleNameMismatch expectedName (A.At region actualName) ->
513 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
514 Code.toSnippet source region Nothing
516 "It looks like this module name is out of sync:"
520 "I need it to match the file path, so I was expecting to see `"
521 ++ ModuleName.toChars expectedName
522 ++ "` here. Make the following change, and you should be all set!"
524 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
526 "I require that module names correspond to file paths. This makes it much\
527 \ easier to explore unfamiliar codebases! So if you want to keep the current\
528 \ module name, try renaming the file instead."
532 UnexpectedPort region ->
533 Report.Report "UNEXPECTED PORTS" region [] $
534 Code.toSnippet source region Nothing
537 "You are declaring ports in a normal module."
541 ["Switch","this","to","say",D.cyan "port module","instead,"
542 ,"marking","that","this","module","contains","port","declarations."
545 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
547 "to learn the syntax and how to use it effectively."
552 Report.Report "NO PORTS" region [] $
553 Code.toSnippet source region Nothing
556 "This module does not declare any ports, but it says it will:"
559 ["Switch","this","to",D.cyan "module"
560 ,"and","you","should","be","all","set!"
565 toParseErrorReport source modul
568toParseErrorReport :: Code.Source -> Module -> Report.Report
569toParseErrorReport source modul =
571 ModuleSpace space row col ->
572 toSpaceReport source space row col
574 ModuleBadEnd row col ->
575 case Code.whatIsNext source row col of
576 Code.Keyword keyword ->
578 region = toKeywordRegion row col keyword
580 Report.Report "RESERVED WORD" region [] $
581 Code.toSnippet source region Nothing
584 "I got stuck on this reserved word:"
587 "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
592 region = toKeywordRegion row col op
594 Report.Report "UNEXPECTED SYMBOL" region [] $
595 Code.toSnippet source region Nothing
598 "I ran into an unexpected symbol:"
601 "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
602 \ I can give a better hint from there?"
605 Code.Close term bracket ->
607 region = toRegion row col
609 Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
610 Code.toSnippet source region Nothing
613 "I ran into an unexpected " ++ term ++ ":"
616 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
619 Code.Other maybeChar ->
621 region = toRegion row col
625 Report.Report "UNEXPECTED SEMICOLON" region [] $
626 Code.toSnippet source region Nothing
629 "I got stuck on this semicolon:"
632 [ D.reflow $ "Try removing it?"
634 "Some languages require semicolons at the end of each statement. These are\
635 \ often called C-like languages, and they usually share a lot of language design\
636 \ choices. (E.g. side-effects, for loops, etc.) Elm manages effects with commands\
637 \ and subscriptions instead, so there is no special syntax for \"statements\" and\
638 \ therefore no need to use semicolons to separate them. I think this will make\
639 \ more sense as you work through <https://guide.elm-lang.org> though!"
644 Report.Report "UNEXPECTED COMMA" region [] $
645 Code.toSnippet source region Nothing
648 "I got stuck on this comma:"
652 "I do not think I am parsing a list or tuple right now. Try deleting the comma?"
654 "If this is supposed to be part of a list, the problem may be a bit earlier.\
655 \ Perhaps the opening [ is missing? Or perhaps some value in the list has an extra\
656 \ closing ] that is making me think the list ended earlier? The same kinds of\
657 \ things could be going wrong if this is supposed to be a tuple."
662 Report.Report "UNEXPECTED CHARACTER" region [] $
663 Code.toSnippet source region Nothing
666 "I got stuck on this character:"
670 "It is not used for anything in Elm syntax. It is used for multi-line strings in\
671 \ some languages though, so if you want a string that spans multiple lines, you\
672 \ can use Elm's multi-line string syntax like this:"
674 [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
676 , D.dullyellow "# Multi-line Strings"
678 , D.dullyellow "- start with triple double quotes"
679 , D.dullyellow "- write whatever you want"
680 , D.dullyellow "- no need to escape newlines or double quotes"
681 , D.dullyellow "- end with triple double quotes"
683 , D.dullyellow "\"\"\""
686 "Otherwise I do not know what is going on! Try removing the character?"
691 Report.Report "UNEXPECTED SYMBOL" region [] $
692 Code.toSnippet source region Nothing
695 "I got stuck on this dollar sign:"
698 "It is not used for anything in Elm syntax. Are you coming from a language where\
699 \ dollar signs can be used in variable names? If so, try a name that (1) starts\
700 \ with a letter and (2) only contains letters, numbers, and underscores."
703 Just c | elem c ['#','@','!','%','~'] ->
704 Report.Report "UNEXPECTED SYMBOL" region [] $
705 Code.toSnippet source region Nothing
708 "I got stuck on this symbol:"
711 "It is not used for anything in Elm syntax. Try removing it?"
715 Report.Report "SYNTAX PROBLEM" region [] $
716 Code.toSnippet source region Nothing
722 "Whatever I am running into is confusing me a lot! Normally I can give fairly\
723 \ specific hints, but something is really tripping me up this time."
726 ModuleProblem row col ->
728 region = toRegion row col
730 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
731 Code.toSnippet source region Nothing
734 "I am parsing an `module` declaration, but I got stuck here:"
738 "Here are some examples of valid `module` declarations:"
739 , D.indent 4 $ D.vcat $
740 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
741 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
744 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
745 \ of files when the public interface of a module stays the same, so exposing fewer\
746 \ values can help improve compile times!"
750 ModuleName row col ->
752 region = toRegion row col
754 Report.Report "EXPECTING MODULE NAME" region [] $
755 Code.toSnippet source region Nothing
758 "I was parsing an `module` declaration until I got stuck here:"
762 "I was expecting to see the module name next, like in these examples:"
763 , D.indent 4 $ D.vcat $
764 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
765 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
766 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
767 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
770 "Notice that the module names all start with capital letters. That is required!"
774 ModuleExposing exposing row col ->
775 toExposingReport source exposing row col
777 PortModuleProblem row col ->
779 region = toRegion row col
781 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
782 Code.toSnippet source region Nothing
785 "I am parsing an `port module` declaration, but I got stuck here:"
789 "Here are some examples of valid `port module` declarations:"
790 , D.indent 4 $ D.vcat $
791 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
792 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
794 , D.link "Note" "Read" "ports" "for more help."
798 PortModuleName row col ->
800 region = toRegion row col
802 Report.Report "EXPECTING MODULE NAME" region [] $
803 Code.toSnippet source region Nothing
806 "I was parsing an `module` declaration until I got stuck here:"
810 "I was expecting to see the module name next, like in these examples:"
811 , D.indent 4 $ D.vcat $
812 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
813 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
816 "Notice that the module names start with capital letters. That is required!"
820 PortModuleExposing exposing row col ->
821 toExposingReport source exposing row col
825 region = toRegion row col
827 Report.Report "BAD MODULE DECLARATION" region [] $
828 Code.toSnippet source region Nothing
831 "I cannot parse this module declaration:"
834 "This type of module is reserved for the @elm organization. It is used to\
835 \ define certain effects, avoiding building them into the compiler."
840 region = toRegion row col
842 toBadFirstLineReport keyword =
843 Report.Report "TOO MUCH INDENTATION" region [] $
844 Code.toSnippet source region Nothing
847 "This `" ++ keyword ++ "` should not have any spaces before it:"
850 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
854 case Code.whatIsNext source row col of
855 Code.Keyword "module" -> toBadFirstLineReport "module"
856 Code.Keyword "import" -> toBadFirstLineReport "import"
857 Code.Keyword "type" -> toBadFirstLineReport "type"
858 Code.Keyword "port" -> toBadFirstLineReport "port"
860 Report.Report "SYNTAX PROBLEM" region [] $
861 Code.toSnippet source region Nothing
868 "I am not sure what is going on, but I recommend starting an Elm\
869 \ file with the following lines:"
871 [ D.fillSep [D.cyan "import","Html"]
873 , D.fillSep [D.green "main","="]
874 , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
877 "You should be able to copy those lines directly into your file. Check out the\
878 \ examples at <https://elm-lang.org/examples> for more help getting started!"
880 "This can also happen when something is indented too much!"
884 ImportStart row col ->
885 toImportReport source row col
887 ImportName row col ->
889 region = toRegion row col
891 Report.Report "EXPECTING IMPORT NAME" region [] $
892 Code.toSnippet source region Nothing
895 "I was parsing an `import` until I got stuck here:"
899 "I was expecting to see a module name next, like in these examples:"
900 , D.indent 4 $ D.vcat $
901 [ D.fillSep [D.cyan "import","Dict"]
902 , D.fillSep [D.cyan "import","Maybe"]
903 , D.fillSep [D.cyan "import","Html.Attributes"]
904 , D.fillSep [D.cyan "import","Json.Decode"]
907 "Notice that the module names all start with capital letters. That is required!"
912 toImportReport source row col
914 ImportAlias row col ->
916 region = toRegion row col
918 Report.Report "EXPECTING IMPORT ALIAS" region [] $
919 Code.toSnippet source region Nothing
922 "I was parsing an `import` until I got stuck here:"
926 "I was expecting to see an alias next, like in these examples:"
927 , D.indent 4 $ D.vcat $
928 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
929 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
930 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
933 "Notice that the alias always starts with a capital letter. That is required!"
937 ImportExposing row col ->
938 toImportReport source row col
940 ImportExposingList exposing row col ->
941 toExposingReport source exposing row col
944 toImportReport source row col
946 ImportIndentName row col ->
947 toImportReport source row col
949 ImportIndentAlias row col ->
950 toImportReport source row col
952 ImportIndentExposingList row col ->
954 region = toRegion row col
956 Report.Report "UNFINISHED IMPORT" region [] $
957 Code.toSnippet source region Nothing
960 "I was parsing an `import` until I got stuck here:"
964 "I was expecting to see the list of exposed values next. For example, here\
965 \ are two ways to expose values from the `Html` module:"
966 , D.indent 4 $ D.vcat $
967 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
968 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
971 "I generally recommend the second style. It is more explicit, making it\
972 \ much easier to figure out where values are coming from in large projects!"
978 region = toRegion row col
980 Report.Report "BAD INFIX" region [] $
981 Code.toSnippet source region Nothing
984 "Something went wrong in this infix operator declaration:"
987 "This feature is used by the @elm organization to define the\
988 \ languages built-in operators."
991 Declarations decl _ _ ->
992 toDeclarationsReport source decl
999toImportReport :: Code.Source -> Row -> Col -> Report.Report
1000toImportReport source row col =
1002 region = toRegion row col
1004 Report.Report "UNFINISHED IMPORT" region [] $
1005 Code.toSnippet source region Nothing
1008 "I am partway through parsing an import, but I got stuck here:"
1012 "Here are some examples of valid `import` declarations:"
1013 , D.indent 4 $ D.vcat $
1014 [ D.fillSep [D.cyan "import","Html"]
1015 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
1016 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
1017 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
1020 "You are probably trying to import a different module, but try to make it look like one of these examples!"
1029toExposingReport :: Code.Source -> Exposing -> Row -> Col -> Report.Report
1030toExposingReport source exposing startRow startCol =
1032 ExposingSpace space row col ->
1033 toSpaceReport source space row col
1035 ExposingStart row col ->
1037 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1038 region = toRegion row col
1040 Report.Report "PROBLEM IN EXPOSING" region [] $
1041 Code.toSnippet source surroundings (Just region)
1044 "I want to parse exposed values, but I am getting stuck here:"
1048 ["Exposed","values","are","always","surrounded","by","parentheses."
1049 ,"So","try","adding","a",D.green "(","here?"
1051 , D.toSimpleNote "Here are some valid examples of `exposing` for reference:"
1052 , D.indent 4 $ D.vcat $
1053 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1054 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
1057 "If you are getting tripped up, you can just expose everything for now. It should\
1058 \ get easier to make an explicit exposing list as you see more examples in the wild."
1062 ExposingValue row col ->
1063 case Code.whatIsNext source row col of
1064 Code.Keyword keyword ->
1066 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1067 region = toKeywordRegion row col keyword
1069 Report.Report "RESERVED WORD" region [] $
1070 Code.toSnippet source surroundings (Just region)
1073 "I got stuck on this reserved word:"
1076 "It looks like you are trying to expose `" ++ keyword ++ "` but that is a reserved word. Is there a typo?"
1081 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1082 region = toKeywordRegion row col op
1084 Report.Report "UNEXPECTED SYMBOL" region [] $
1085 Code.toSnippet source surroundings (Just region)
1088 "I got stuck on this symbol:"
1092 "If you are trying to expose an operator, add parentheses around it like this:"
1093 , D.indent 4 $ D.dullyellow (D.fromChars op) <> " -> " <> D.green ("(" <> D.fromChars op <> ")")
1099 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1100 region = toRegion row col
1102 Report.Report "PROBLEM IN EXPOSING" region [] $
1103 Code.toSnippet source surroundings (Just region)
1106 "I got stuck while parsing these exposed values:"
1110 "I do not have an exact recommendation, so here are some valid examples\
1111 \ of `exposing` for reference:"
1112 , D.indent 4 $ D.vcat $
1113 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1114 , D.fillSep [D.cyan "import","Basics",D.cyan "exposing","(Int, Float, Bool(..), (+), not, sqrt)"]
1117 "These examples show how to expose types, variants, operators, and functions. Everything\
1118 \ should be some permutation of these examples, just with different names."
1122 ExposingOperator row col ->
1124 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1125 region = toRegion row col
1127 Report.Report "PROBLEM IN EXPOSING" region [] $
1128 Code.toSnippet source surroundings (Just region)
1131 "I just saw an open parenthesis, so I was expecting an operator next:"
1134 ["It","is","possible","to","expose","operators,","so","I","was","expecting"
1135 ,"to","see","something","like",D.dullyellow "(+)","or",D.dullyellow "(|=)"
1136 ,"or",D.dullyellow "(||)","after","I","saw","that","open","parenthesis."
1140 ExposingOperatorReserved op row col ->
1142 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1143 region = toRegion row col
1145 Report.Report "RESERVED SYMBOL" region [] $
1146 Code.toSnippet source surroundings (Just region)
1149 "I cannot expose this as an operator:"
1152 BadDot -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1153 BadPipe -> D.fillSep ["Maybe","you","want",D.dullyellow "(||)","instead?"]
1154 BadArrow -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1155 BadEquals -> D.fillSep ["Maybe","you","want",D.dullyellow "(==)","instead?"]
1156 BadHasType -> D.fillSep ["Maybe","you","want",D.dullyellow "(::)","instead?"]
1159 ExposingOperatorRightParen row col ->
1161 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1162 region = toRegion row col
1164 Report.Report "PROBLEM IN EXPOSING" region [] $
1165 Code.toSnippet source surroundings (Just region)
1168 "It looks like you are exposing an operator, but I got stuck here:"
1171 ["I","was","expecting","to","see","the","closing","parenthesis","immediately"
1172 ,"after","the","operator.","Try","adding","a",D.green ")","right","here?"
1176 ExposingEnd row col ->
1178 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1179 region = toRegion row col
1181 Report.Report "UNFINISHED EXPOSING" region [] $
1182 Code.toSnippet source surroundings (Just region)
1185 "I was partway through parsing exposed values, but I got stuck here:"
1188 "Maybe there is a comma missing before this?"
1191 ExposingTypePrivacy row col ->
1193 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1194 region = toRegion row col
1196 Report.Report "PROBLEM EXPOSING CUSTOM TYPE VARIANTS" region [] $
1197 Code.toSnippet source surroundings (Just region)
1200 "It looks like you are trying to expose the variants of a custom type:"
1204 ["You","need","to","write","something","like"
1205 ,D.dullyellow "Status(..)","or",D.dullyellow "Entity(..)"
1206 ,"though.","It","is","all","or","nothing,","otherwise","`case`"
1207 ,"expressions","could","miss","a","variant","and","crash!"
1210 "It is often best to keep the variants hidden! If someone pattern matches on\
1211 \ the variants, it is a MAJOR change if any new variants are added. Suddenly\
1212 \ their `case` expressions do not cover all variants! So if you do not need\
1213 \ people to pattern match, keep the variants hidden and expose functions to\
1214 \ construct values of this type. This way you can add new variants as a MINOR change!"
1218 ExposingIndentEnd row col ->
1220 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1221 region = toRegion row col
1223 Report.Report "UNFINISHED EXPOSING" region [] $
1224 Code.toSnippet source surroundings (Just region)
1227 "I was partway through parsing exposed values, but I got stuck here:"
1231 ["I","was","expecting","a","closing","parenthesis."
1232 ,"Try","adding","a",D.green ")","right","here?"
1235 "I can get confused when there is not enough indentation, so if you already\
1236 \ have a closing parenthesis, it probably just needs some spaces in front of it."
1240 ExposingIndentValue row col ->
1242 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1243 region = toRegion row col
1245 Report.Report "UNFINISHED EXPOSING" region [] $
1246 Code.toSnippet source surroundings (Just region)
1249 "I was partway through parsing exposed values, but I got stuck here:"
1252 "I was expecting another value to expose."
1260toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
1261toSpaceReport source space row col =
1265 region = toRegion row col
1267 Report.Report "NO TABS" region [] $
1268 Code.toSnippet source region Nothing
1271 "I ran into a tab, but tabs are not allowed in Elm files."
1274 "Replace the tab with spaces."
1277 EndlessMultiComment ->
1279 region = toWiderRegion row col 2
1281 Report.Report "ENDLESS COMMENT" region [] $
1282 Code.toSnippet source region Nothing
1285 "I cannot find the end of this multi-line comment:"
1288 [ D.reflow "Add a -} somewhere after this to end the comment."
1290 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
1291 \ that happens to contain another comment. Like parentheses and curly braces,\
1292 \ the start and end markers must always be balanced. Maybe that is the problem?"
1301toRegion :: Row -> Col -> A.Region
1304 pos = A.Position row col
1309toWiderRegion :: Row -> Col -> Word16 -> A.Region
1310toWiderRegion row col extra =
1312 (A.Position row col)
1313 (A.Position row (col + extra))
1316toKeywordRegion :: Row -> Col -> [Char.Char] -> A.Region
1317toKeywordRegion row col keyword =
1319 (A.Position row col)
1320 (A.Position row (col + fromIntegral (length keyword)))
1323toDeclarationsReport :: Code.Source -> Decl -> Report.Report
1324toDeclarationsReport source decl =
1326 DeclStart row col ->
1327 case Code.whatIsNext source row col of
1328 Code.Close term bracket ->
1330 region = toRegion row col
1332 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1333 Code.toSnippet source region Nothing
1336 "I was not expecting to see a " ++ term ++ " here:"
1338 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1341 Code.Keyword keyword ->
1343 region = toKeywordRegion row col keyword
1345 Report.Report "RESERVED WORD" region [] $
1346 Code.toSnippet source region Nothing
1349 "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1354 "It is reserved for declaring imports at the top of your module. If you want\
1355 \ another import, try moving it up top with the other imports. If you want to\
1356 \ define a value or function, try changing the name to something else!"
1361 "It is reserved for writing `case` expressions. Try using a different name?"
1363 "If you are trying to write a `case` expression, it needs to be part of a\
1364 \ definition. So you could write something like this instead:"
1366 [ D.indent 0 $ D.fillSep [D.green "getWidth","maybeWidth","="]
1367 , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1368 , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1369 , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1371 , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1372 , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1375 "This defines a `getWidth` function that we can use elsewhere in our program."
1381 "It is reserved for writing `if` expressions. Try using a different name?"
1383 "If you are trying to write an `if` expression, it needs to be part of a\
1384 \ definition. So you could write something like this instead:"
1386 [ D.indent 0 $ D.fillSep [D.green "reviewPowerLevel","powerLevel","="]
1387 , D.indent 2 $ D.fillSep $
1388 [D.cyan "if","powerLevel",">",D.dullyellow "9000"
1389 ,D.cyan "then",D.dullyellow "\"OVER 9000!!!\""
1390 ,D.cyan "else",D.dullyellow "\"not bad\""
1394 "This defines a `reviewPowerLevel` function that we can use elsewhere in our program."
1399 "It is a reserved word. Try changing the name to something else?"
1404 region = toRegion row col
1406 Report.Report "SYNTAX PROBLEM" region [] $
1407 Code.toSnippet source region Nothing
1410 "I was expecting to see a declaration, but I am getting stuck here:"
1413 [ case Code.whatIsNext source row col of
1414 Code.Other (Just char) | Char.isUpper char ->
1416 "All declarations start with lower-case letters in Elm, so maybe this letter can\
1417 \ be changed to lower-case?"
1421 "Declarations normally start with a lower-case name or the `type` keyword."
1423 "Here are a couple valid declarations for reference:"
1425 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1426 , D.fillSep [D.green "add","x","y","="]
1427 , D.fillSep [" ","x","+","y"]
1429 , D.fillSep [D.cyan "type",D.green "User","=","Anonymous","|","LoggedIn String"]
1431 "Notice that these declarations start with lower-case letters. Capitalization\
1432 \ makes a difference in Elm!"
1436 DeclSpace space row col ->
1437 toSpaceReport source space row col
1439 Port port_ row col ->
1440 toPortReport source port_ row col
1442 DeclType declType row col ->
1443 toDeclTypeReport source declType row col
1445 DeclDef name declDef row col ->
1446 toDeclDefReport source name declDef row col
1448 DeclFreshLineAfterDocComment row col ->
1450 region = toRegion row col
1452 Report.Report "EXPECTING DECLARATION" region [] $
1453 Code.toSnippet source region Nothing
1456 "I just saw a doc comment, but then I got stuck here:"
1459 "I was expecting to see the corresponding declaration next, starting on a fresh\
1460 \ line with no indentation."
1468toPortReport :: Code.Source -> Port -> Row -> Col -> Report.Report
1469toPortReport source port_ startRow startCol =
1471 PortSpace space row col ->
1472 toSpaceReport source space row col
1475 case Code.whatIsNext source row col of
1476 Code.Keyword keyword ->
1478 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1479 region = toKeywordRegion row col keyword
1481 Report.Report "RESERVED WORD" region [] $
1482 Code.toSnippet source surroundings (Just region)
1485 "I cannot handle ports with names like this:"
1488 "You are trying to make a port named `" ++ keyword
1489 ++ "` but that is a reserved word. Try using some other name?"
1494 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1495 region = toRegion row col
1497 Report.Report "PORT PROBLEM" region [] $
1498 Code.toSnippet source surroundings (Just region)
1501 "I just saw the start of a `port` declaration, but then I got stuck here:"
1505 ["I","was","expecting","to","see","a","name","like"
1506 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1507 ,"Something","that","starts","with","a","lower-case","letter."
1513 PortColon row col ->
1515 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1516 region = toRegion row col
1518 Report.Report "PORT PROBLEM" region [] $
1519 Code.toSnippet source surroundings (Just region)
1522 "I just saw the start of a `port` declaration, but then I got stuck here:"
1526 "I was expecting to see a colon next. And then a type that tells me\
1527 \ what type of values are going to flow through."
1532 PortType tipe row col ->
1533 toTypeReport source TC_Port tipe row col
1535 PortIndentName row col ->
1537 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1538 region = toRegion row col
1540 Report.Report "UNFINISHED PORT" region [] $
1541 Code.toSnippet source surroundings (Just region)
1544 "I just saw the start of a `port` declaration, but then I got stuck here:"
1548 ["I","was","expecting","to","see","a","name","like"
1549 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1550 ,"Something","that","starts","with","a","lower-case","letter."
1556 PortIndentColon row col ->
1558 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1559 region = toRegion row col
1561 Report.Report "UNFINISHED PORT" region [] $
1562 Code.toSnippet source surroundings (Just region)
1565 "I just saw the start of a `port` declaration, but then I got stuck here:"
1569 "I was expecting to see a colon next. And then a type that tells me\
1570 \ what type of values are going to flow through."
1575 PortIndentType row col ->
1577 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1578 region = toRegion row col
1580 Report.Report "UNFINISHED PORT" region [] $
1581 Code.toSnippet source surroundings (Just region)
1584 "I just saw the start of a `port` declaration, but then I got stuck here:"
1588 "I was expecting to see a type next. Here are examples of outgoing and\
1589 \ incoming ports for reference:"
1591 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1592 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1595 "The first line defines a `send` port so you can send strings out to JavaScript.\
1596 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1597 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1598 \ get receive messages when new WebSocket messages come in or when an entry in\
1599 \ IndexedDB changes for some external reason."
1608 "Here are some example `port` declarations for reference:"
1610 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1611 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1614 "The first line defines a `send` port so you can send strings out to JavaScript.\
1615 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1616 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1617 \ get receive messages when new WebSocket messages come in or when the IndexedDB\
1618 \ is changed for some external reason."
1626toDeclTypeReport :: Code.Source -> DeclType -> Row -> Col -> Report.Report
1627toDeclTypeReport source declType startRow startCol =
1629 DT_Space space row col ->
1630 toSpaceReport source space row col
1634 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1635 region = toRegion row col
1637 Report.Report "EXPECTING TYPE NAME" region [] $
1638 Code.toSnippet source surroundings (Just region)
1641 "I think I am parsing a type declaration, but I got stuck here:"
1645 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1646 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1652 DT_Alias typeAlias row col ->
1653 toTypeAliasReport source typeAlias row col
1655 DT_Union customType row col ->
1656 toCustomTypeReport source customType row col
1658 DT_IndentName row col ->
1660 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1661 region = toRegion row col
1663 Report.Report "EXPECTING TYPE NAME" region [] $
1664 Code.toSnippet source surroundings (Just region)
1667 "I think I am parsing a type declaration, but I got stuck here:"
1671 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1672 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1679toTypeAliasReport :: Code.Source -> TypeAlias -> Row -> Col -> Report.Report
1680toTypeAliasReport source typeAlias startRow startCol =
1682 AliasSpace space row col ->
1683 toSpaceReport source space row col
1685 AliasName row col ->
1687 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1688 region = toRegion row col
1690 Report.Report "EXPECTING TYPE ALIAS NAME" region [] $
1691 Code.toSnippet source surroundings (Just region)
1694 "I am partway through parsing a type alias, but I got stuck here:"
1698 ["I","was","expecting","a","name","like",D.dullyellow "Person","or",D.dullyellow "Point"
1699 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1705 AliasEquals row col ->
1706 case Code.whatIsNext source row col of
1707 Code.Keyword keyword ->
1709 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1710 region = toKeywordRegion row col keyword
1712 Report.Report "RESERVED WORD" region [] $
1713 Code.toSnippet source surroundings (Just region)
1716 "I ran into a reserved word unexpectedly while parsing this type alias:"
1720 "It looks like you are trying use `" ++ keyword
1721 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1728 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1729 region = toRegion row col
1731 Report.Report "PROBLEM IN TYPE ALIAS" region [] $
1732 Code.toSnippet source surroundings (Just region)
1735 "I am partway through parsing a type alias, but I got stuck here:"
1739 "I was expecting to see a type variable or an equals sign next."
1744 AliasBody tipe row col ->
1745 toTypeReport source TC_TypeAlias tipe row col
1747 AliasIndentEquals row col ->
1749 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1750 region = toRegion row col
1752 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1753 Code.toSnippet source surroundings (Just region)
1756 "I am partway through parsing a type alias, but I got stuck here:"
1760 "I was expecting to see a type variable or an equals sign next."
1765 AliasIndentBody row col ->
1767 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1768 region = toRegion row col
1770 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1771 Code.toSnippet source surroundings (Just region)
1774 "I am partway through parsing a type alias, but I got stuck here:"
1778 ["I","was","expecting","to","see","a","type","next.","Something","as","simple"
1779 ,"as",D.dullyellow "Int","or",D.dullyellow "Float","would","work!"
1786typeAliasNote :: D.Doc
1790 "Here is an example of a valid `type alias` for reference:"
1792 [ D.indent 0 $ D.fillSep [D.cyan "type",D.cyan "alias",D.green "Person","="]
1793 , D.indent 2 $ D.vcat $
1801 "This would let us use `Person` as a shorthand for that record type. Using this\
1802 \ shorthand makes type annotations much easier to read, and makes changing code\
1803 \ easier if you decide later that there is more to a person than age and height!"
1807toCustomTypeReport :: Code.Source -> CustomType -> Row -> Col -> Report.Report
1808toCustomTypeReport source customType startRow startCol =
1810 CT_Space space row col ->
1811 toSpaceReport source space row col
1815 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1816 region = toRegion row col
1818 Report.Report "EXPECTING TYPE NAME" region [] $
1819 Code.toSnippet source surroundings (Just region)
1822 "I think I am parsing a type declaration, but I got stuck here:"
1826 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1827 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1833 CT_Equals row col ->
1834 case Code.whatIsNext source row col of
1835 Code.Keyword keyword ->
1837 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1838 region = toKeywordRegion row col keyword
1840 Report.Report "RESERVED WORD" region [] $
1841 Code.toSnippet source surroundings (Just region)
1844 "I ran into a reserved word unexpectedly while parsing this custom type:"
1848 "It looks like you are trying use `" ++ keyword
1849 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1856 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1857 region = toRegion row col
1859 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1860 Code.toSnippet source surroundings (Just region)
1863 "I am partway through parsing a custom type, but I got stuck here:"
1867 "I was expecting to see a type variable or an equals sign next."
1874 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1875 region = toRegion row col
1877 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1878 Code.toSnippet source surroundings (Just region)
1881 "I am partway through parsing a custom type, but I got stuck here:"
1885 "I was expecting to see a vertical bar like | next."
1890 CT_Variant row col ->
1892 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1893 region = toRegion row col
1895 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1896 Code.toSnippet source surroundings (Just region)
1899 "I am partway through parsing a custom type, but I got stuck here:"
1903 ["I","was","expecting","to","see","a","variant","name","next."
1904 ,"Something","like",D.dullyellow "Success","or",D.dullyellow "Sandwich" <> "."
1905 ,"Any","name","that","starts","with","a","capital","letter","really!"
1911 CT_VariantArg tipe row col ->
1912 toTypeReport source TC_CustomType tipe row col
1914 CT_IndentEquals row col ->
1916 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1917 region = toRegion row col
1919 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1920 Code.toSnippet source surroundings (Just region)
1923 "I am partway through parsing a custom type, but I got stuck here:"
1927 "I was expecting to see a type variable or an equals sign next."
1932 CT_IndentBar row col ->
1934 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1935 region = toRegion row col
1937 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1938 Code.toSnippet source surroundings (Just region)
1941 "I am partway through parsing a custom type, but I got stuck here:"
1945 "I was expecting to see a vertical bar like | next."
1950 CT_IndentAfterBar row col ->
1952 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1953 region = toRegion row col
1955 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1956 Code.toSnippet source surroundings (Just region)
1959 "I am partway through parsing a custom type, but I got stuck here:"
1963 "I just saw a vertical bar, so I was expecting to see another variant defined next."
1968 CT_IndentAfterEquals row col ->
1970 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1971 region = toRegion row col
1973 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1974 Code.toSnippet source surroundings (Just region)
1977 "I am partway through parsing a custom type, but I got stuck here:"
1981 "I just saw an equals sign, so I was expecting to see the first variant defined next."
1987customTypeNote :: D.Doc
1991 "Here is an example of a valid `type` declaration for reference:"
1993 [ D.indent 0 $ D.fillSep [D.cyan "type",D.green "Status"]
1994 , D.indent 2 $ D.fillSep ["=","Failure"]
1995 , D.indent 2 $ D.fillSep ["|","Waiting"]
1996 , D.indent 2 $ D.fillSep ["|","Success","String"]
1999 "This defines a new `Status` type with three variants. This could be useful if\
2000 \ we are waiting for an HTTP request. Maybe we start with `Waiting` and then\
2001 \ switch to `Failure` or `Success \"message from server\"` depending on how\
2002 \ things go. Notice that the Success variant has some associated data, allowing\
2003 \ us to store a String if the request goes well!"
2011toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
2012toDeclDefReport source name declDef startRow startCol =
2014 DeclDefSpace space row col ->
2015 toSpaceReport source space row col
2017 DeclDefEquals row col ->
2018 case Code.whatIsNext source row col of
2019 Code.Keyword keyword ->
2021 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2022 region = toKeywordRegion row col keyword
2024 Report.Report "RESERVED WORD" region [] $
2025 Code.toSnippet source surroundings (Just region)
2029 ,"`" <> D.cyan (D.fromChars keyword) <> "`"
2030 ,"is","reserved","in","Elm,","so","it","cannot"
2031 ,"be","used","as","an","argument","here:"
2036 "Try renaming it to something else."
2040 ["This","keyword","is","reserved","for","pattern","matches","like"
2041 ,"((x,y)",D.cyan "as","point)","where","you","want","to","name","a","tuple","and"
2042 ,"the","values","it","contains."
2047 "The `" ++ keyword ++ "` keyword has a special meaning in Elm, so it can only be used in certain situations."
2051 Code.Operator "->" ->
2053 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2054 region = toWiderRegion row col 2
2056 Report.Report "MISSING COLON?" region [] $
2057 Code.toSnippet source surroundings (Just region)
2060 "I was not expecting to see an arrow here:"
2064 ["This","usually","means","a",D.green ":","is","missing","a","bit","earlier","in"
2065 ,"a","type","annotation.","It","could","be","something","else","though,","so"
2066 ,"here","is","a","valid","definition","for","reference:"
2069 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2070 , D.fillSep [D.green "add","x","y","="]
2071 , D.fillSep [" ","x","+","y"]
2074 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
2080 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2081 region = toKeywordRegion row col op
2083 Report.Report "UNEXPECTED SYMBOL" region [] $
2084 Code.toSnippet source surroundings (Just region)
2087 "I was not expecting to see this symbol here:"
2091 "I am not sure what is going wrong exactly, so here is a valid\
2092 \ definition (with an optional type annotation) for reference:"
2094 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2095 , D.fillSep [D.green "add","x","y","="]
2096 , D.fillSep [" ","x","+","y"]
2099 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
2105 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2106 region = toRegion row col
2108 Report.Report "PROBLEM IN DEFINITION" region [] $
2109 Code.toSnippet source surroundings (Just region)
2112 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2116 "I am not sure what is going wrong exactly, so here is a valid\
2117 \ definition (with an optional type annotation) for reference:"
2119 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2120 , D.fillSep [D.green "add","x","y","="]
2121 , D.fillSep [" ","x","+","y"]
2124 "Try to use that format!"
2128 DeclDefType tipe row col ->
2129 toTypeReport source (TC_Annotation name) tipe row col
2131 DeclDefArg pattern row col ->
2132 toPatternReport source PArg pattern row col
2134 DeclDefBody expr row col ->
2135 toExprReport source (InDef name startRow startCol) expr row col
2137 DeclDefNameRepeat row col ->
2139 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2140 region = toRegion row col
2142 Report.Report "EXPECTING DEFINITION" region [] $
2143 Code.toSnippet source surroundings (Just region)
2146 "I just saw the type annotation for `" ++ Name.toChars name
2147 ++ "` so I was expecting to see its definition here:"
2151 "Type annotations always appear directly above the relevant\
2152 \ definition, without anything else in between. (Not even doc comments!)"
2157 DeclDefNameMatch defName row col ->
2159 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2160 region = toRegion row col
2162 Report.Report "NAME MISMATCH" region [] $
2163 Code.toSnippet source surroundings (Just region)
2166 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
2170 "These names do not match! Is there a typo?"
2171 , D.indent 4 $ D.fillSep $
2172 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
2176 DeclDefIndentType row col ->
2178 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2179 region = toRegion row col
2181 Report.Report "UNFINISHED DEFINITION" region [] $
2182 Code.toSnippet source surroundings (Just region)
2185 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
2189 "I just saw a colon, so I am expecting to see a type next."
2194 DeclDefIndentEquals row col ->
2196 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2197 region = toRegion row col
2199 Report.Report "UNFINISHED DEFINITION" region [] $
2200 Code.toSnippet source surroundings (Just region)
2203 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2207 "I was expecting to see an argument or an equals sign next."
2212 DeclDefIndentBody row col ->
2214 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2215 region = toRegion row col
2217 Report.Report "UNFINISHED DEFINITION" region [] $
2218 Code.toSnippet source surroundings (Just region)
2221 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2225 "I was expecting to see an expression next. What is it equal to?"
2235 "Here is a valid definition (with a type annotation) for reference:"
2237 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2238 , D.fillSep [D.green "add","x","y","="]
2239 , D.fillSep [" ","x","+","y"]
2242 "The top line (called a \"type annotation\") is optional. You can leave it off\
2243 \ if you want. As you get more comfortable with Elm and as your project grows,\
2244 \ it becomes more and more valuable to add them though! They work great as\
2245 \ compiler-verified documentation, and they often improve error messages!"
2254 = InNode Node Row Col Context
2255 | InDef Name.Name Row Col
2256 | InDestruct Row Col
2272getDefName :: Context -> Maybe Name.Name
2275 InDestruct _ _ -> Nothing
2276 InDef name _ _ -> Just name
2277 InNode _ _ _ c -> getDefName c
2280isWithin :: Node -> Context -> Bool
2281isWithin desiredNode context =
2283 InDestruct _ _ -> False
2284 InDef _ _ _ -> False
2285 InNode actualNode _ _ _ -> desiredNode == actualNode
2292toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
2293toExprReport source context expr startRow startCol =
2296 toLetReport source context let_ row col
2298 Case case_ row col ->
2299 toCaseReport source context case_ row col
2302 toIfReport source context if_ row col
2304 List list row col ->
2305 toListReport source context list row col
2307 Record record row col ->
2308 toRecordReport source context record row col
2310 Tuple tuple row col ->
2311 toTupleReport source context tuple row col
2313 Func func row col ->
2314 toFuncReport source context func row col
2317 let region = toRegion row col in
2318 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2319 Code.toSnippet source region Nothing
2322 "I was expecting to see a record accessor here:"
2325 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2326 ,"that","accesses","a","value","from","a","record."
2331 let region = toRegion row col in
2332 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2333 Code.toSnippet source region Nothing
2336 "I am trying to parse a record accessor here:"
2341 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2342 ,"that","accesses","a","value","from","a","record."
2346 "Record field names must start with a lower case letter!"
2350 OperatorRight op row col ->
2352 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2353 region = toRegion row col
2354 isMath = elem op ["-","+","*","/","^"]
2356 Report.Report "MISSING EXPRESSION" region [] $
2357 Code.toSnippet source surroundings (Just region)
2360 "I just saw a " ++ Name.toChars op ++ " "
2361 ++ (if isMath then "sign" else "operator")
2362 ++ ", so I am getting stuck here:"
2366 ["I","was","expecting","to","see","an","expression","next."
2367 ,"Something","like",D.dullyellow "42","or",D.dullyellow "1000"
2368 ,"that","makes","sense","with","a",D.fromName op,"sign."
2370 else if op == "&&" || op == "||" then
2372 ["I","was","expecting","to","see","an","expression","next."
2373 ,"Something","like",D.dullyellow "True","or",D.dullyellow "False"
2374 ,"that","makes","sense","with","boolean","logic."
2376 else if op == "|>" then
2378 "I was expecting to see a function next."
2379 else if op == "<|" then
2381 "I was expecting to see an argument next."
2384 "I was expecting to see an expression next."
2387 OperatorReserved operator row col ->
2388 toOperatorReport source context operator row col
2392 (contextRow, contextCol, aThing) =
2394 InDestruct r c -> (r, c, "a definition")
2395 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
2396 InNode NRecord r c _ -> (r, c, "a record")
2397 InNode NParens r c _ -> (r, c, "some parentheses")
2398 InNode NList r c _ -> (r, c, "a list")
2399 InNode NFunc r c _ -> (r, c, "an anonymous function")
2400 InNode NCond r c _ -> (r, c, "an `if` expression")
2401 InNode NThen r c _ -> (r, c, "an `if` expression")
2402 InNode NElse r c _ -> (r, c, "an `if` expression")
2403 InNode NCase r c _ -> (r, c, "a `case` expression")
2404 InNode NBranch r c _ -> (r, c, "a `case` expression")
2406 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
2407 region = toRegion row col
2409 Report.Report "MISSING EXPRESSION" region [] $
2410 Code.toSnippet source surroundings (Just region)
2413 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
2417 ["I","was","expecting","to","see","an","expression","like"
2418 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2419 ,"Once","there","is","something","there,","I","can","probably"
2420 ,"give","a","more","specific","hint!"
2423 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
2424 \ Or if I run into operators in unexpected spots. Point is, there are a\
2425 \ couple ways I can get confused and give sort of weird advice!"
2429 Char char row col ->
2430 toCharReport source char row col
2432 String string row col ->
2433 toStringReport source string row col
2435 Number number row col ->
2436 toNumberReport source number row col
2438 Space space row col ->
2439 toSpaceReport source space row col
2441 EndlessShader row col ->
2443 region = toWiderRegion row col 6
2445 Report.Report "ENDLESS SHADER" region [] $
2446 Code.toSnippet source region Nothing
2448 D.reflow "I cannot find the end of this shader:"
2450 D.reflow "Add a |] somewhere after this to end the shader."
2453 ShaderProblem problem row col ->
2455 region = toRegion row col
2457 Report.Report "SHADER PROBLEM" region [] $
2458 Code.toSnippet source region Nothing
2461 "I ran into a problem while parsing this GLSL block."
2465 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
2466 , D.indent 4 $ D.vcat $
2467 map D.fromChars (filter (/="") (lines problem))
2471 IndentOperatorRight op row col ->
2473 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2474 region = toRegion row col
2476 Report.Report "MISSING EXPRESSION" region [] $
2477 Code.toSnippet source surroundings (Just region)
2480 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
2485 ["You","can","just","put","anything","for","now,","like"
2486 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2487 ,"Once","there","is","something","there,","I","can","probably"
2488 ,"give","a","more","specific","hint!"
2492 "I may be getting confused by your indentation? The easiest way to make sure\
2493 \ this is not an indentation problem is to put the expression on the right of\
2494 \ the " ++ Name.toChars op ++ " operator on the same line."
2503toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
2504toCharReport source char row col =
2508 region = toRegion row col
2510 Report.Report "MISSING SINGLE QUOTE" region [] $
2511 Code.toSnippet source region Nothing
2514 "I thought I was parsing a character, but I got to the end of\
2515 \ the line without seeing the closing single quote:"
2518 "Add a closing single quote here!"
2521 CharEscape escape ->
2522 toEscapeReport source escape row col
2524 CharNotString width ->
2526 region = toWiderRegion row col width
2528 Report.Report "NEEDS DOUBLE QUOTES" region [] $
2529 Code.toSnippet source region Nothing
2531 "The following string uses single quotes:"
2534 [ "Please switch to double quotes instead:"
2536 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
2538 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
2539 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
2540 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
2541 \ individual characters."
2550toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
2551toStringReport source string row col =
2553 StringEndless_Single ->
2555 region = toRegion row col
2557 Report.Report "ENDLESS STRING" region [] $
2558 Code.toSnippet source region Nothing
2561 "I got to the end of the line without seeing the closing double quote:"
2565 ["Strings","look","like",D.green "\"this\"","with","double"
2566 ,"quotes","on","each","end.","Is","the","closing","double"
2567 ,"quote","missing","in","your","code?"
2570 "For a string that spans multiple lines, you can use the multi-line string\
2571 \ syntax like this:"
2573 [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2575 , D.dullyellow "# Multi-line Strings"
2577 , D.dullyellow "- start with triple double quotes"
2578 , D.dullyellow "- write whatever you want"
2579 , D.dullyellow "- no need to escape newlines or double quotes"
2580 , D.dullyellow "- end with triple double quotes"
2582 , D.dullyellow "\"\"\""
2587 StringEndless_Multi ->
2589 region = toWiderRegion row col 3
2591 Report.Report "ENDLESS STRING" region [] $
2592 Code.toSnippet source region Nothing
2595 "I cannot find the end of this multi-line string:"
2598 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
2600 "Here is a valid multi-line string for reference:"
2602 [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2604 , D.dullyellow "# Multi-line Strings"
2606 , D.dullyellow "- start with triple double quotes"
2607 , D.dullyellow "- write whatever you want"
2608 , D.dullyellow "- no need to escape newlines or double quotes"
2609 , D.dullyellow "- end with triple double quotes"
2611 , D.dullyellow "\"\"\""
2616 StringEscape escape ->
2617 toEscapeReport source escape row col
2624toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
2625toEscapeReport source escape row col =
2629 region = toWiderRegion row col 2
2631 Report.Report "UNKNOWN ESCAPE" region [] $
2632 Code.toSnippet source region Nothing
2635 "Backslashes always start escaped characters, but I do not recognize this one:"
2639 "Valid escape characters include:"
2640 , D.dullyellow $ D.indent 4 $ D.vcat $
2650 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
2652 "The last style lets encode ANY character by its Unicode code\
2653 \ point. That means \\u{0009} and \\t are the same. You can use\
2654 \ that style for anything not covered by the other six escapes!"
2658 BadUnicodeFormat width ->
2660 region = toWiderRegion row col width
2662 Report.Report "BAD UNICODE ESCAPE" region [] $
2663 Code.toSnippet source region Nothing
2666 "I ran into an invalid Unicode escape:"
2670 "Here are some examples of valid Unicode escapes:"
2671 , D.dullyellow $ D.indent 4 $ D.vcat $
2678 "Notice that the code point is always surrounded by curly braces.\
2679 \ Maybe you are missing the opening or closing curly brace?"
2682 BadUnicodeCode width ->
2684 region = toWiderRegion row col width
2686 Report.Report "BAD UNICODE ESCAPE" region [] $
2687 Code.toSnippet source region Nothing
2690 "This is not a valid code point:"
2693 "The valid code points are between 0 and 10FFFF inclusive."
2696 BadUnicodeLength width numDigits badCode ->
2698 region = toWiderRegion row col width
2700 Report.Report "BAD UNICODE ESCAPE" region [] $
2701 Code.toSnippet source region Nothing $
2702 if numDigits < 4 then
2705 "Every code point needs at least four digits:"
2708 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
2709 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
2711 D.fillSep ["Try",D.green suggestion,"instead?"]
2717 "This code point has too many digits:"
2720 ["Valid","code","points","are","between"
2721 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
2722 ,"so","try","trimming","any","leading","zeros","until"
2723 ,"you","have","between","four","and","six","digits."
2732toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
2733toNumberReport source number row col =
2735 region = toRegion row col
2739 Report.Report "WEIRD NUMBER" region [] $
2740 Code.toSnippet source region Nothing
2743 "I thought I was reading a number, but I ran into some weird stuff here:"
2747 "I recognize numbers in the following formats:"
2748 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
2750 "So is there a way to write it like one of those?"
2755 Report.Report "WEIRD NUMBER" region [] $
2756 Code.toSnippet source region Nothing
2759 "Numbers cannot end with a dot like this:"
2762 ["Switching","to",D.green (D.fromChars (show int))
2763 ,"or",D.green (D.fromChars (show int ++ ".0"))
2764 ,"will","work","though!"
2769 Report.Report "WEIRD HEXIDECIMAL" region [] $
2770 Code.toSnippet source region Nothing
2773 "I thought I was reading a hexidecimal number until I got here:"
2777 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
2778 \ only recognize things like this:"
2779 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
2783 NumberNoLeadingZero ->
2784 Report.Report "LEADING ZEROS" region [] $
2785 Code.toSnippet source region Nothing
2788 "I do not accept numbers with leading zeros:"
2792 "Just delete the leading zeros and it should work!"
2794 "Some languages let you to specify octal numbers by adding a leading zero.\
2795 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
2796 \ that, but others probably want it to equal 111. Either path is going to\
2797 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
2807toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
2808toOperatorReport source context operator row col =
2812 region = toRegion row col
2814 Report.Report "UNEXPECTED SYMBOL" region [] $
2815 Code.toSnippet source region Nothing
2817 "I was not expecting this dot:"
2820 "Dots are for record access and decimal points, so\
2821 \ they cannot float around on their own. Maybe\
2822 \ there is some extra whitespace?"
2827 region = toRegion row col
2829 Report.Report "UNEXPECTED SYMBOL" region [] $
2830 Code.toSnippet source region Nothing
2833 "I was not expecting this vertical bar:"
2836 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
2841 region = toWiderRegion row col 2
2843 Report.Report "UNEXPECTED ARROW" region [] $
2844 Code.toSnippet source region Nothing $
2845 if isWithin NCase context then
2848 "I am parsing a `case` expression right now, but this arrow is confusing me:"
2851 [ D.reflow "Maybe the `of` keyword is missing on a previous line?"
2856 else if isWithin NBranch context then
2859 "I am parsing a `case` expression right now, but this arrow is confusing me:"
2863 "It makes sense to see arrows around here, so I suspect it is something earlier. Maybe this pattern is indented a bit farther than the previous patterns?"
2864 , noteForCaseIndentError
2871 "I was not expecting an arrow here:"
2874 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
2875 \ you want > or >= instead?"
2880 region = toRegion row col
2882 Report.Report "UNEXPECTED EQUALS" region [] $
2883 Code.toSnippet source region Nothing
2886 "I was not expecting to see this equals sign:"
2890 D.reflow "Maybe you want == instead? To check if two values are equal?"
2893 if isWithin NRecord context then
2894 "Records look like { x = 3, y = 4 } with the equals sign right\
2895 \ after the field name. So maybe you forgot a comma?"
2897 case getDefName context of
2899 "I may be getting confused by your indentation. I need all definitions to be indented\
2900 \ exactly the same amount, so if this is meant to be a new definition, it may have too\
2901 \ many spaces in front of it."
2904 "I may be getting confused by your indentation. I think I am still parsing the `"
2905 ++ Name.toChars name ++ "` definition. Is this supposed to be part of a definition\
2906 \ after that? If so, the problem may be a bit before the equals sign. I need all\
2907 \ definitions to be indented exactly the same amount, so the problem may be that\
2908 \ this new definition has too many spaces in front of it."
2914 region = toRegion row col
2916 Report.Report "UNEXPECTED SYMBOL" region [] $
2917 Code.toSnippet source region Nothing $
2920 "I was not expecting to run into the \"has type\" symbol here:"
2922 case getDefName context of
2925 ["Maybe","you","want",D.green "::","instead?"
2926 ,"To","put","something","on","the","front","of","a","list?"
2933 ["Maybe","you","want",D.green "::","instead?"
2934 ,"To","put","something","on","the","front","of","a","list?"
2937 "The single colon is reserved for type annotations and record types, but I think\
2938 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
2941 "I may be getting confused by your indentation. Is this supposed to be part of\
2942 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
2943 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
2944 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
2945 \ this new definition is indented a bit too much."
2954toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
2955toLetReport source context let_ startRow startCol =
2957 LetSpace space row col ->
2958 toSpaceReport source space row col
2962 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2963 region = toRegion row col
2965 Report.Report "LET PROBLEM" region [] $
2966 Code.toSnippet source surroundings (Just region)
2969 "I was partway through parsing a `let` expression, but I got stuck here:"
2973 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2974 ,"keyword","next.","Is","there","a","typo?"
2977 "This can also happen if you are trying to define another value within the `let` but\
2978 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2979 \ spaces before it. They should line up exactly!"
2983 LetDefAlignment _ row col ->
2985 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2986 region = toRegion row col
2988 Report.Report "LET PROBLEM" region [] $
2989 Code.toSnippet source surroundings (Just region)
2992 "I was partway through parsing a `let` expression, but I got stuck here:"
2996 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2997 ,"keyword","next.","Is","there","a","typo?"
3000 "This can also happen if you are trying to define another value within the `let` but\
3001 \ it is not indented enough. Make sure each definition has exactly the same amount of\
3002 \ spaces before it. They should line up exactly!"
3006 LetDefName row col ->
3007 case Code.whatIsNext source row col of
3008 Code.Keyword keyword ->
3010 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3011 region = toKeywordRegion row col keyword
3013 Report.Report "RESERVED WORD" region [] $
3014 Code.toSnippet source surroundings (Just region)
3017 "I was partway through parsing a `let` expression, but I got stuck here:"
3020 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
3021 \ it is a reserved word! Try using a different name instead."
3025 toUnfinishLetReport source row col startRow startCol $
3027 "I was expecting the name of a definition next."
3029 LetDef name def row col ->
3030 toLetDefReport source name def row col
3032 LetDestruct destruct row col ->
3033 toLetDestructReport source destruct row col
3035 LetBody expr row col ->
3036 toExprReport source context expr row col
3038 LetIndentDef row col ->
3039 toUnfinishLetReport source row col startRow startCol $
3041 "I was expecting a value to be defined here."
3043 LetIndentIn row col ->
3044 toUnfinishLetReport source row col startRow startCol $
3046 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
3047 ,"Or","maybe","more","of","that","expression?"
3050 LetIndentBody row col ->
3051 toUnfinishLetReport source row col startRow startCol $
3053 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
3056toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3057toUnfinishLetReport source row col startRow startCol message =
3059 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3060 region = toRegion row col
3062 Report.Report "UNFINISHED LET" region [] $
3063 Code.toSnippet source surroundings (Just region)
3066 "I was partway through parsing a `let` expression, but I got stuck here:"
3071 "Here is an example with a valid `let` expression for reference:"
3073 [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
3074 , D.indent 2 $ D.fillSep [D.cyan "let"]
3075 , D.indent 4 $ D.fillSep ["fullName","="]
3076 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
3077 , D.indent 2 $ D.fillSep [D.cyan "in"]
3078 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
3081 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
3082 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
3083 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
3084 \ indented a bit more than that. That is important!"
3089toLetDefReport :: Code.Source -> Name.Name -> Def -> Row -> Col -> Report.Report
3090toLetDefReport source name def startRow startCol =
3092 DefSpace space row col ->
3093 toSpaceReport source space row col
3095 DefType tipe row col ->
3096 toTypeReport source (TC_Annotation name) tipe row col
3098 DefNameRepeat row col ->
3100 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3101 region = toRegion row col
3103 Report.Report "EXPECTING DEFINITION" region [] $
3104 Code.toSnippet source surroundings (Just region)
3107 "I just saw the type annotation for `" ++ Name.toChars name
3108 ++ "` so I was expecting to see its definition here:"
3112 "Type annotations always appear directly above the relevant\
3113 \ definition, without anything else in between."
3118 DefNameMatch defName row col ->
3120 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3121 region = toRegion row col
3123 Report.Report "NAME MISMATCH" region [] $
3124 Code.toSnippet source surroundings (Just region)
3127 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
3131 "These names do not match! Is there a typo?"
3132 , D.indent 4 $ D.fillSep $
3133 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
3137 DefArg pattern row col ->
3138 toPatternReport source PArg pattern row col
3140 DefEquals row col ->
3141 case Code.whatIsNext source row col of
3142 Code.Keyword keyword ->
3144 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3145 region = toKeywordRegion row col keyword
3147 Report.Report "RESERVED WORD" region [] $
3148 Code.toSnippet source surroundings (Just region)
3152 ,"`" <> D.cyan (D.fromChars keyword) <> "`"
3153 ,"is","reserved","in","Elm,","so","it","cannot"
3154 ,"be","used","as","an","argument","here:"
3159 "Try renaming it to something else."
3163 ["This","keyword","is","reserved","for","pattern","matches","like"
3164 ,"((x,y)",D.cyan "as","point)","where","you","want","to","name","a","tuple","and"
3165 ,"the","values","it","contains."
3170 "The `" ++ keyword ++ "` keyword has a special meaning in Elm, so it can only be used in certain situations."
3174 Code.Operator "->" ->
3176 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3177 region = toWiderRegion row col 2
3179 Report.Report "MISSING COLON?" region [] $
3180 Code.toSnippet source surroundings (Just region)
3183 "I was not expecting to see an arrow here:"
3187 ["This","usually","means","a",D.green ":","is","missing","a","bit","earlier","in"
3188 ,"a","type","annotation.","It","could","be","something","else","though,","so"
3189 ,"here","is","a","valid","definition","for","reference:"
3192 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3193 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3194 , D.indent 6 $ D.fillSep ["x","+","y"]
3197 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
3203 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3204 region = toKeywordRegion row col op
3206 Report.Report "UNEXPECTED SYMBOL" region [] $
3207 Code.toSnippet source surroundings (Just region)
3210 "I was not expecting to see this symbol here:"
3214 "I am not sure what is going wrong exactly, so here is a valid\
3215 \ definition (with an optional type annotation) for reference:"
3217 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3218 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3219 , D.indent 6 $ D.fillSep ["x","+","y"]
3222 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
3228 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3229 region = toRegion row col
3231 Report.Report "PROBLEM IN DEFINITION" region [] $
3232 Code.toSnippet source surroundings (Just region)
3235 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3239 "I am not sure what is going wrong exactly, so here is a valid\
3240 \ definition (with an optional type annotation) for reference:"
3242 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3243 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3244 , D.indent 4 $ D.fillSep ["x","+","y"]
3247 "Try to use that format!"
3251 DefBody expr row col ->
3252 toExprReport source (InDef name startRow startCol) expr row col
3254 DefIndentEquals row col ->
3256 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3257 region = toRegion row col
3259 Report.Report "UNFINISHED DEFINITION" region [] $
3260 Code.toSnippet source surroundings (Just region)
3263 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3267 "I was expecting to see an argument or an equals sign next."
3272 DefIndentType row col ->
3274 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3275 region = toRegion row col
3277 Report.Report "UNFINISHED DEFINITION" region [] $
3278 Code.toSnippet source surroundings (Just region)
3281 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
3285 "I just saw a colon, so I am expecting to see a type next."
3290 DefIndentBody row col ->
3292 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3293 region = toRegion row col
3295 Report.Report "UNFINISHED DEFINITION" region [] $
3296 Code.toSnippet source surroundings (Just region)
3299 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3303 "I was expecting to see an expression next. What is it equal to?"
3308 DefAlignment indent row col ->
3310 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3311 region = toRegion row col
3312 offset = indent - col
3314 Report.Report "PROBLEM IN DEFINITION" region [] $
3315 Code.toSnippet source surroundings (Just region)
3318 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3321 "I just saw a type annotation indented " ++ show indent ++ " spaces, so I was\
3322 \ expecting to see the corresponding definition next with the exact same amount\
3323 \ of indentation. It looks like this line needs "
3324 ++ show offset ++ " more " ++ (if offset == 1 then "space" else "spaces") ++ "?"
3333 "Here is a valid definition (with a type annotation) for reference:"
3335 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3336 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3337 , D.indent 6 $ D.fillSep ["x","+","y"]
3340 "The top line (called a \"type annotation\") is optional. You can leave it off\
3341 \ if you want. As you get more comfortable with Elm and as your project grows,\
3342 \ it becomes more and more valuable to add them though! They work great as\
3343 \ compiler-verified documentation, and they often improve error messages!"
3347toLetDestructReport :: Code.Source -> Destruct -> Row -> Col -> Report.Report
3348toLetDestructReport source destruct startRow startCol =
3350 DestructSpace space row col ->
3351 toSpaceReport source space row col
3353 DestructPattern pattern row col ->
3354 toPatternReport source PLet pattern row col
3356 DestructEquals row col ->
3358 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3359 region = toRegion row col
3361 Report.Report "PROBLEM IN DEFINITION" region [] $
3362 Code.toSnippet source surroundings (Just region)
3365 "I got stuck trying to parse this definition:"
3367 case Code.whatIsNext source row col of
3368 Code.Operator ":" ->
3371 "I was expecting to see an equals sign next, followed by an expression\
3372 \ telling me what to compute."
3374 "It looks like you may be trying to write a type annotation? It is not\
3375 \ possible to add type annotations on destructuring definitions like this.\
3376 \ You can assign a name to the overall structure, put a type annotation on\
3377 \ that, and then destructure separately though."
3382 "I was expecting to see an equals sign next, followed by an expression\
3383 \ telling me what to compute."
3386 DestructBody expr row col ->
3387 toExprReport source (InDestruct startRow startCol) expr row col
3389 DestructIndentEquals row col ->
3391 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3392 region = toRegion row col
3394 Report.Report "UNFINISHED DEFINITION" region [] $
3395 Code.toSnippet source surroundings (Just region)
3398 "I got stuck trying to parse this definition:"
3401 "I was expecting to see an equals sign next, followed by an expression\
3402 \ telling me what to compute."
3405 DestructIndentBody row col ->
3407 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3408 region = toRegion row col
3410 Report.Report "UNFINISHED DEFINITION" region [] $
3411 Code.toSnippet source surroundings (Just region)
3414 "I got stuck while parsing this definition:"
3417 "I was expecting to see an expression next. What is it equal to?"
3425toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
3426toCaseReport source context case_ startRow startCol =
3428 CaseSpace space row col ->
3429 toSpaceReport source space row col
3432 toUnfinishCaseReport source row col startRow startCol $
3433 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3435 CasePattern pattern row col ->
3436 toPatternReport source PCase pattern row col
3438 CaseArrow row col ->
3439 case Code.whatIsNext source row col of
3440 Code.Keyword keyword ->
3442 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3443 region = toKeywordRegion row col keyword
3445 Report.Report "RESERVED WORD" region [] $
3446 Code.toSnippet source surroundings (Just region)
3449 "I am partway through parsing a `case` expression, but I got stuck here:"
3452 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
3453 \ patterns, but it is a reserved word. Try using a different name?"
3456 Code.Operator ":" ->
3458 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3459 region = toRegion row col
3461 Report.Report "UNEXPECTED OPERATOR" region [] $
3462 Code.toSnippet source surroundings (Just region)
3465 "I am partway through parsing a `case` expression, but I got stuck here:"
3468 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
3469 ,"For","pattern","matching","on","lists?"
3473 Code.Operator "=" ->
3475 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3476 region = toRegion row col
3478 Report.Report "UNEXPECTED OPERATOR" region [] $
3479 Code.toSnippet source surroundings (Just region)
3482 "I am partway through parsing a `case` expression, but I got stuck here:"
3485 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
3491 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3492 region = toRegion row col
3494 Report.Report "MISSING ARROW" region [] $
3495 Code.toSnippet source surroundings (Just region)
3498 "I am partway through parsing a `case` expression, but I got stuck here:"
3501 [ D.reflow "I was expecting to see an arrow next."
3502 , noteForCaseIndentError
3506 CaseExpr expr row col ->
3507 toExprReport source (InNode NCase startRow startCol context) expr row col
3509 CaseBranch expr row col ->
3510 toExprReport source (InNode NBranch startRow startCol context) expr row col
3512 CaseIndentOf row col ->
3513 toUnfinishCaseReport source row col startRow startCol $
3514 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3516 CaseIndentExpr row col ->
3517 toUnfinishCaseReport source row col startRow startCol $
3518 D.reflow "I was expecting to see a expression next."
3520 CaseIndentPattern row col ->
3521 toUnfinishCaseReport source row col startRow startCol $
3522 D.reflow "I was expecting to see a pattern next."
3524 CaseIndentArrow row col ->
3525 toUnfinishCaseReport source row col startRow startCol $
3527 ["I","just","saw","a","pattern,","so","I","was","expecting"
3528 ,"to","see","a",D.dullyellow "->","next."
3531 CaseIndentBranch row col ->
3532 toUnfinishCaseReport source row col startRow startCol $
3534 "I was expecting to see an expression next. What should I do when\
3535 \ I run into this particular pattern?"
3537 CasePatternAlignment indent row col ->
3538 toUnfinishCaseReport source row col startRow startCol $
3540 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
3543toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3544toUnfinishCaseReport source row col startRow startCol message =
3546 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3547 region = toRegion row col
3549 Report.Report "UNFINISHED CASE" region [] $
3550 Code.toSnippet source surroundings (Just region)
3553 "I was partway through parsing a `case` expression, but I got stuck here:"
3562noteForCaseError :: D.Doc
3566 "Here is an example of a valid `case` expression for reference."
3568 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3569 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3570 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3572 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3573 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3576 "Notice the indentation. Each pattern is aligned, and each branch is indented\
3577 \ a bit more than the corresponding pattern. That is important!"
3581noteForCaseIndentError :: D.Doc
3582noteForCaseIndentError =
3585 "Sometimes I get confused by indentation, so try to make your `case` look\
3586 \ something like this:"
3588 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3589 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3590 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3592 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3593 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3596 "Notice the indentation! Patterns are aligned with each other. Same indentation.\
3597 \ The expressions after each arrow are all indented a bit more than the patterns.\
3598 \ That is important!"
3606toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
3607toIfReport source context if_ startRow startCol =
3609 IfSpace space row col ->
3610 toSpaceReport source space row col
3614 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3615 region = toRegion row col
3617 Report.Report "UNFINISHED IF" region [] $
3618 Code.toSnippet source surroundings (Just region)
3621 "I was expecting to see more of this `if` expression, but I got stuck here:"
3624 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3630 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3631 region = toRegion row col
3633 Report.Report "UNFINISHED IF" region [] $
3634 Code.toSnippet source surroundings (Just region)
3637 "I was expecting to see more of this `if` expression, but I got stuck here:"
3640 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
3644 IfElseBranchStart row col ->
3646 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3647 region = toRegion row col
3649 Report.Report "UNFINISHED IF" region [] $
3650 Code.toSnippet source surroundings (Just region)
3653 "I just saw the start of an `else` branch, but then I got stuck here:"
3656 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3659 IfCondition expr row col ->
3660 toExprReport source (InNode NCond startRow startCol context) expr row col
3662 IfThenBranch expr row col ->
3663 toExprReport source (InNode NThen startRow startCol context) expr row col
3665 IfElseBranch expr row col ->
3666 toExprReport source (InNode NElse startRow startCol context) expr row col
3668 IfIndentCondition row col ->
3670 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3671 region = toRegion row col
3673 Report.Report "UNFINISHED IF" region [] $
3674 Code.toSnippet source surroundings (Just region)
3677 "I was expecting to see more of this `if` expression, but I got stuck here:"
3681 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
3682 ,"that","evaluates","to","True","or","False."
3685 "I can be confused by indentation. Maybe something is not indented enough?"
3689 IfIndentThen row col ->
3691 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3692 region = toRegion row col
3694 Report.Report "UNFINISHED IF" region [] $
3695 Code.toSnippet source surroundings (Just region)
3698 "I was expecting to see more of this `if` expression, but I got stuck here:"
3702 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3705 "I can be confused by indentation. Maybe something is not indented enough?"
3709 IfIndentThenBranch row col ->
3711 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3712 region = toRegion row col
3714 Report.Report "UNFINISHED IF" region [] $
3715 Code.toSnippet source surroundings (Just region)
3718 "I got stuck after the start of this `then` branch:"
3722 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3724 "I can be confused by indentation, so if the `then` branch is already\
3725 \ present, it may not be indented enough for me to recognize it."
3729 IfIndentElseBranch row col ->
3731 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3732 region = toRegion row col
3734 Report.Report "UNFINISHED IF" region [] $
3735 Code.toSnippet source surroundings (Just region)
3738 "I got stuck after the start of this `else` branch:"
3742 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3744 "I can be confused by indentation, so if the `else` branch is already\
3745 \ present, it may not be indented enough for me to recognize it."
3749 IfIndentElse row col ->
3751 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3752 region = toRegion row col
3754 Report.Report "UNFINISHED IF" region [] $
3755 Code.toSnippet source surroundings (Just region)
3758 "I was expecting to see an `else` branch after this:"
3762 ["I","know","what","to","do","when","the","condition","is","True,"
3763 ,"but","what","happens","when","it","is","False?"
3764 ,"Add","an",D.cyan "else","branch","to","handle","that","scenario!"
3774toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
3775toRecordReport source context record startRow startCol =
3777 RecordOpen row col ->
3778 case Code.whatIsNext source row col of
3779 Code.Keyword keyword ->
3781 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3782 region = toKeywordRegion row col keyword
3784 Report.Report "RESERVED WORD" region [] $
3785 Code.toSnippet source surroundings (Just region)
3788 "I just started parsing a record, but I got stuck on this field name:"
3791 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3792 \ that is a reserved word. Try using a different name!"
3797 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3798 region = toRegion row col
3800 Report.Report "UNFINISHED RECORD" region [] $
3801 Code.toSnippet source surroundings (Just region)
3804 "I just started parsing a record, but I got stuck here:"
3807 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
3808 ,"so","I","was","expecting","to","see","a","field","name","next."
3812 RecordEnd row col ->
3814 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3815 region = toRegion row col
3817 Report.Report "UNFINISHED RECORD" region [] $
3818 Code.toSnippet source surroundings (Just region)
3821 "I am partway through parsing a record, but I got stuck here:"
3825 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
3826 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
3829 "When I get stuck like this, it usually means that there is a missing parenthesis\
3830 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3834 RecordField row col ->
3835 case Code.whatIsNext source row col of
3836 Code.Keyword keyword ->
3838 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3839 region = toKeywordRegion row col keyword
3841 Report.Report "RESERVED WORD" region [] $
3842 Code.toSnippet source surroundings (Just region)
3845 "I am partway through parsing a record, but I got stuck on this field name:"
3848 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3849 \ that is a reserved word. Try using a different name!"
3854 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3855 region = toRegion row col
3857 Report.Report "UNFINISHED RECORD" region [] $
3858 Code.toSnippet source surroundings (Just region)
3861 "I am partway through parsing a record, but I got stuck after that last comma:"
3863 addNoteForRecordError $
3865 "Trailing commas are not allowed in records, so I was expecting to see another\
3866 \ record field defined next. If you are done defining the record, the fix may\
3867 \ be to delete that last comma?"
3870 RecordEquals row col ->
3872 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3873 region = toRegion row col
3875 Report.Report "UNFINISHED RECORD" region [] $
3876 Code.toSnippet source surroundings (Just region)
3879 "I am partway through parsing a record, but I got stuck here:"
3881 addNoteForRecordError $
3883 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
3884 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
3888 RecordExpr expr row col ->
3889 toExprReport source (InNode NRecord startRow startCol context) expr row col
3891 RecordSpace space row col ->
3892 toSpaceReport source space row col
3894 RecordIndentOpen row col ->
3896 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3897 region = toRegion row col
3899 Report.Report "UNFINISHED RECORD" region [] $
3900 Code.toSnippet source surroundings (Just region)
3903 "I just saw the opening curly brace of a record, but then I got stuck here:"
3905 addNoteForRecordIndentError $
3907 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
3908 ,"Try","defining","some","fields","of","your","own?"
3912 RecordIndentEnd row col ->
3914 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3915 region = toRegion row col
3917 Report.Report "UNFINISHED RECORD" region [] $
3918 Code.toSnippet source surroundings (Just region)
3921 "I was expecting to see a closing curly brace next:"
3923 addNoteForRecordIndentError $
3925 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
3929 RecordIndentField row col ->
3931 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3932 region = toRegion row col
3934 Report.Report "UNFINISHED RECORD" region [] $
3935 Code.toSnippet source surroundings (Just region)
3938 "I am partway through parsing a record, but I got stuck after that last comma:"
3940 addNoteForRecordError $
3942 "Trailing commas are not allowed in records, so the fix may be to\
3943 \ delete that last comma? Or maybe you were in the middle of defining\
3944 \ an additional field?"
3947 RecordIndentEquals row col ->
3949 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3950 region = toRegion row col
3952 Report.Report "UNFINISHED RECORD" region [] $
3953 Code.toSnippet source surroundings (Just region)
3956 "I am partway through parsing a record. I just saw a record\
3957 \ field, so I was expecting to see an equals sign next:"
3959 addNoteForRecordIndentError $
3961 ["Try","putting","an",D.green "=","followed","by","an","expression?"
3965 RecordIndentExpr row col ->
3967 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3968 region = toRegion row col
3970 Report.Report "UNFINISHED RECORD" region [] $
3971 Code.toSnippet source surroundings (Just region)
3974 "I am partway through parsing a record, and I was expecting to run into an expression next:"
3976 addNoteForRecordIndentError $
3978 ["Try","putting","something","like"
3979 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
3984addNoteForRecordError :: D.Doc -> D.Doc
3985addNoteForRecordError normalRecommendation =
3987 normalRecommendation
3990 "If you are trying to define a record across multiple lines, I recommend using this format:"
3991 , D.indent 4 $ D.vcat $
3992 [ "{ name = \"Alice\""
3998 "Notice that each line starts with some indentation. Usually two or four spaces. I\
3999 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
4000 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4004addNoteForRecordIndentError :: D.Doc -> D.Doc
4005addNoteForRecordIndentError normalRecommendation =
4007 normalRecommendation
4010 "I may be confused by indentation. For example, if you are trying to define\
4011 \ a record across multiple lines, I recommend using this format:"
4012 , D.indent 4 $ D.vcat $
4013 [ "{ name = \"Alice\""
4019 "Notice that each line starts with some indentation. Usually two or four spaces. I\
4020 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
4021 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4029toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
4030toTupleReport source context tuple startRow startCol =
4032 TupleExpr expr row col ->
4033 toExprReport source (InNode NParens startRow startCol context) expr row col
4035 TupleSpace space row col ->
4036 toSpaceReport source space row col
4040 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4041 region = toRegion row col
4043 Report.Report "UNFINISHED PARENTHESES" region [] $
4044 Code.toSnippet source surroundings (Just region)
4047 "I was expecting to see a closing parentheses next, but I got stuck here:"
4050 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
4052 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
4053 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
4054 \ or missing brackets) that is confusing me."
4058 TupleOperatorClose row col ->
4060 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4061 region = toRegion row col
4063 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
4064 Code.toSnippet source surroundings (Just region)
4066 D.reflow "I was expecting a closing parenthesis here:"
4069 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4071 "I think I am parsing an operator function right now, so I am expecting to see\
4072 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
4077 TupleOperatorReserved operator row col ->
4079 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4080 region = toRegion row col
4082 Report.Report "UNEXPECTED SYMBOL" region [] $
4083 Code.toSnippet source surroundings (Just region)
4086 "I ran into an unexpected symbol here:"
4090 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
4091 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
4092 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
4093 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
4094 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
4097 TupleIndentExpr1 row col ->
4099 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4100 region = toRegion row col
4102 Report.Report "UNFINISHED PARENTHESES" region [] $
4103 Code.toSnippet source surroundings (Just region)
4106 "I just saw an open parenthesis, so I was expecting to see an expression next."
4110 ["Something","like",D.dullyellow "(4 + 5)","or"
4111 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
4112 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
4115 "I can get confused by indentation in cases like this, so\
4116 \ maybe you have an expression but it is not indented enough?"
4120 TupleIndentExprN row col ->
4122 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4123 region = toRegion row col
4125 Report.Report "UNFINISHED TUPLE" region [] $
4126 Code.toSnippet source surroundings (Just region)
4129 "I think I am in the middle of parsing a tuple. I just saw a comma, so I was expecting to see an expression next."
4133 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
4134 ,D.dullyellow "(\"Tom\",42)" <> ","
4135 ,"so","I","think","there","is","an","expression","missing","here?"
4138 "I can get confused by indentation in cases like this, so\
4139 \ maybe you have an expression but it is not indented enough?"
4143 TupleIndentEnd row col ->
4145 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4146 region = toRegion row col
4148 Report.Report "UNFINISHED PARENTHESES" region [] $
4149 Code.toSnippet source surroundings (Just region)
4152 "I was expecting to see a closing parenthesis next:"
4155 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4157 "I can get confused by indentation in cases like this, so\
4158 \ maybe you have a closing parenthesis but it is not indented enough?"
4163toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
4164toListReport source context list startRow startCol =
4166 ListSpace space row col ->
4167 toSpaceReport source space row col
4171 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4172 region = toRegion row col
4174 Report.Report "UNFINISHED LIST" region [] $
4175 Code.toSnippet source surroundings (Just region)
4178 "I am partway through parsing a list, but I got stuck here:"
4182 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
4183 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4186 "When I get stuck like this, it usually means that there is a missing parenthesis\
4187 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4191 ListExpr expr row col ->
4195 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
4196 region = toRegion r c
4198 Report.Report "UNFINISHED LIST" region [] $
4199 Code.toSnippet source surroundings (Just region)
4202 "I was expecting to see another list entry after that last comma:"
4206 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4208 "I recommend using the following format for lists that span multiple lines:"
4209 , D.indent 4 $ D.vcat $
4216 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4217 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4218 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4223 toExprReport source (InNode NList startRow startCol context) expr row col
4227 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4228 region = toRegion row col
4230 Report.Report "UNFINISHED LIST" region [] $
4231 Code.toSnippet source surroundings (Just region)
4234 "I am partway through parsing a list, but I got stuck here:"
4238 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
4239 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4242 "When I get stuck like this, it usually means that there is a missing parenthesis\
4243 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4247 ListIndentOpen row col ->
4249 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4250 region = toRegion row col
4252 Report.Report "UNFINISHED LIST" region [] $
4253 Code.toSnippet source surroundings (Just region)
4256 "I cannot find the end of this list:"
4260 ["You","could","change","it","to","something","like"
4261 ,D.dullyellow "[3,4,5]"
4263 ,D.dullyellow "[]" <> "."
4264 ,"Anything","where","there","is","an","open","and","close","square","brace,"
4265 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
4268 "I may be confused by indentation. For example, if you are trying to define\
4269 \ a list across multiple lines, I recommend using this format:"
4270 , D.indent 4 $ D.vcat $
4277 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4278 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4279 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4283 ListIndentEnd row col ->
4285 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4286 region = toRegion row col
4288 Report.Report "UNFINISHED LIST" region [] $
4289 Code.toSnippet source surroundings (Just region)
4292 "I cannot find the end of this list:"
4296 ["You","can","just","add","a","closing",D.dullyellow "]"
4297 ,"right","here,","and","I","will","be","all","set!"
4300 "I may be confused by indentation. For example, if you are trying to define\
4301 \ a list across multiple lines, I recommend using this format:"
4302 , D.indent 4 $ D.vcat $
4309 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4310 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4311 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4315 ListIndentExpr row col ->
4317 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4318 region = toRegion row col
4320 Report.Report "UNFINISHED LIST" region [] $
4321 Code.toSnippet source surroundings (Just region)
4324 "I was expecting to see another list entry after this comma:"
4328 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4330 "I recommend using the following format for lists that span multiple lines:"
4331 , D.indent 4 $ D.vcat $
4338 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4339 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4340 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4345toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
4346toFuncReport source context func startRow startCol =
4348 FuncSpace space row col ->
4349 toSpaceReport source space row col
4351 FuncArg pattern row col ->
4352 toPatternReport source PArg pattern row col
4354 FuncBody expr row col ->
4355 toExprReport source (InNode NFunc startRow startCol context) expr row col
4357 FuncArrow row col ->
4358 case Code.whatIsNext source row col of
4359 Code.Keyword keyword ->
4361 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4362 region = toKeywordRegion row col keyword
4364 Report.Report "RESERVED WORD" region [] $
4365 Code.toSnippet source surroundings (Just region)
4368 "I was parsing an anonymous function, but I got stuck here:"
4371 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
4372 \ it is a reserved word in this language. Try using a different argument name!"
4377 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4378 region = toRegion row col
4380 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4381 Code.toSnippet source surroundings (Just region)
4384 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4387 ["The","syntax","for","anonymous","functions","is"
4388 ,D.dullyellow "(\\x -> x + 1)"
4389 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4393 FuncIndentArg row col ->
4395 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4396 region = toRegion row col
4398 Report.Report "MISSING ARGUMENT" region [] $
4399 Code.toSnippet source surroundings (Just region)
4402 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
4406 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
4407 ,"Anything","that","starts","with","a","lower","case","letter!"
4410 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
4411 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
4412 \ like a better idea at the time!"
4416 FuncIndentArrow row col ->
4418 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4419 region = toRegion row col
4421 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4422 Code.toSnippet source surroundings (Just region)
4425 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4429 ["The","syntax","for","anonymous","functions","is"
4430 ,D.dullyellow "(\\x -> x + 1)"
4431 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4434 "It is possible that I am confused about indetation! I generally recommend\
4435 \ switching to named functions if the definition cannot fit inline nicely, so\
4436 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4437 \ the whole thing out into a named function. Things tend to be clearer that way!"
4441 FuncIndentBody row col ->
4443 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4444 region = toRegion row col
4446 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4447 Code.toSnippet source surroundings (Just region)
4450 "I was expecting to see the body of your anonymous function next:"
4454 ["The","syntax","for","anonymous","functions","is"
4455 ,D.dullyellow "(\\x -> x + 1)"
4456 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
4459 "It is possible that I am confused about indetation! I generally recommend\
4460 \ switching to named functions if the definition cannot fit inline nicely, so\
4461 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4462 \ the whole thing out into a named function. Things tend to be clearer that way!"
4477toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
4478toPatternReport source context pattern startRow startCol =
4480 PRecord record row col ->
4481 toPRecordReport source record row col
4483 PTuple tuple row col ->
4484 toPTupleReport source context tuple row col
4486 PList list row col ->
4487 toPListReport source context list row col
4490 case Code.whatIsNext source row col of
4491 Code.Keyword keyword ->
4493 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4494 region = toKeywordRegion row col keyword
4497 PArg -> "as an argument"
4498 PCase -> "in this pattern"
4499 PLet -> "in this pattern"
4501 Report.Report "RESERVED WORD" region [] $
4502 Code.toSnippet source surroundings (Just region)
4505 "It looks like you are trying to use `" ++ keyword ++ "` " ++ inThisThing ++ ":"
4508 "This is a reserved word! Try using some other name?"
4511 Code.Operator "-" ->
4513 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4514 region = toRegion row col
4516 Report.Report "UNEXPECTED SYMBOL" region [] $
4517 Code.toSnippet source surroundings (Just region)
4520 "I ran into a minus sign unexpectedly in this pattern:"
4523 "It is not possible to pattern match on negative numbers at this\
4524 \ time. Try using an `if` expression for that sort of thing for now."
4529 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4530 region = toRegion row col
4532 Report.Report "PROBLEM IN PATTERN" region [] $
4533 Code.toSnippet source surroundings (Just region)
4536 "I wanted to parse a pattern next, but I got stuck here:"
4539 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4540 ,"I","just","know","that","I","want","a","pattern","next."
4541 ,"Something","as","simple","as"
4542 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4547 PChar char row col ->
4548 toCharReport source char row col
4550 PString string row col ->
4551 toStringReport source string row col
4553 PNumber number row col ->
4554 toNumberReport source number row col
4556 PFloat width row col ->
4558 region = toWiderRegion row col width
4560 Report.Report "UNEXPECTED PATTERN" region [] $
4561 Code.toSnippet source region Nothing
4564 "I cannot pattern match with floating point numbers:"
4567 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
4568 ,"to","check","that","they","are","nearby","with","some","sort","of"
4569 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
4575 region = toRegion row col
4577 Report.Report "UNFINISHED PATTERN" region [] $
4578 Code.toSnippet source region Nothing $
4581 "I was expecting to see a variable name after the `as` keyword:"
4585 ["The","`as`","keyword","lets","you","write","patterns","like"
4586 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4587 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4588 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4589 ,"thing","with",D.dullyellow "point" <> "."
4592 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4593 \ people just want to use `as` as a variable name though. Try using a different name\
4598 PWildcardNotVar name width row col ->
4600 region = toWiderRegion row col (fromIntegral width)
4602 case dropWhile (=='_') (Name.toChars name) of
4603 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
4604 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
4606 Report.Report "UNEXPECTED NAME" region [] $
4607 Code.toSnippet source region Nothing $
4610 "Variable names cannot start with underscores like this:"
4613 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
4614 ,"ignore","the","value,","or","you","can","have","a","name","like"
4615 ] ++ examples ++ ["to","use","the","matched","value." ]
4618 PSpace space row col ->
4619 toSpaceReport source space row col
4621 PIndentStart row col ->
4623 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4624 region = toRegion row col
4626 Report.Report "UNFINISHED PATTERN" region [] $
4627 Code.toSnippet source surroundings (Just region)
4630 "I wanted to parse a pattern next, but I got stuck here:"
4634 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4635 ,"I","just","know","that","I","want","a","pattern","next."
4636 ,"Something","as","simple","as"
4637 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4641 "I can get confused by indentation. If you think there is a pattern next, maybe\
4642 \ it needs to be indented a bit more?"
4646 PIndentAlias row col ->
4648 region = toRegion row col
4650 Report.Report "UNFINISHED PATTERN" region [] $
4651 Code.toSnippet source region Nothing $
4654 "I was expecting to see a variable name after the `as` keyword:"
4658 ["The","`as`","keyword","lets","you","write","patterns","like"
4659 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4660 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4661 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4662 ,"thing","with",D.dullyellow "point."
4665 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4666 \ people just want to use `as` as a variable name though. Try using a different name\
4672toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
4673toPRecordReport source record startRow startCol =
4675 PRecordOpen row col ->
4676 toUnfinishRecordPatternReport source row col startRow startCol $
4677 D.reflow "I was expecting to see a field name next."
4679 PRecordEnd row col ->
4680 toUnfinishRecordPatternReport source row col startRow startCol $
4682 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4683 ,"Try","adding","a",D.dullyellow "}","here?"
4686 PRecordField row col ->
4687 case Code.whatIsNext source row col of
4688 Code.Keyword keyword ->
4690 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4691 region = toKeywordRegion row col keyword
4693 Report.Report "RESERVED WORD" region [] $
4694 Code.toSnippet source surroundings (Just region)
4697 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
4700 "This is a reserved word, not available for variable names. Try another name!"
4704 toUnfinishRecordPatternReport source row col startRow startCol $
4705 D.reflow "I was expecting to see a field name next."
4707 PRecordSpace space row col ->
4708 toSpaceReport source space row col
4710 PRecordIndentOpen row col ->
4711 toUnfinishRecordPatternReport source row col startRow startCol $
4712 D.reflow "I was expecting to see a field name next."
4714 PRecordIndentEnd row col ->
4715 toUnfinishRecordPatternReport source row col startRow startCol $
4717 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4718 ,"Try","adding","a",D.dullyellow "}","here?"
4721 PRecordIndentField row col ->
4722 toUnfinishRecordPatternReport source row col startRow startCol $
4723 D.reflow "I was expecting to see a field name next."
4726toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
4727toUnfinishRecordPatternReport source row col startRow startCol message =
4729 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4730 region = toRegion row col
4732 Report.Report "UNFINISHED RECORD PATTERN" region [] $
4733 Code.toSnippet source surroundings (Just region)
4736 "I was partway through parsing a record pattern, but I got stuck here:"
4741 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
4742 ,"where","you","list","the","field","names","you","want","to","access."
4749toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
4750toPTupleReport source context tuple startRow startCol =
4752 PTupleOpen row col ->
4753 case Code.whatIsNext source row col of
4754 Code.Keyword keyword ->
4756 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4757 region = toKeywordRegion row col keyword
4759 Report.Report "RESERVED WORD" region [] $
4760 Code.toSnippet source surroundings (Just region)
4763 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
4766 "This is a reserved word! Try using some other name?"
4771 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4772 region = toRegion row col
4774 Report.Report "UNFINISHED PARENTHESES" region [] $
4775 Code.toSnippet source surroundings (Just region)
4778 "I just saw an open parenthesis, but I got stuck here:"
4781 ["I","was","expecting","to","see","a","pattern","next."
4782 ,"Maybe","it","will","end","up","being","something"
4783 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
4787 PTupleEnd row col ->
4788 case Code.whatIsNext source row col of
4789 Code.Keyword keyword ->
4791 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4792 region = toKeywordRegion row col keyword
4794 Report.Report "RESERVED WORD" region [] $
4795 Code.toSnippet source surroundings (Just region) $
4798 "I ran into a reserved word in this pattern:"
4801 "The `" ++ keyword ++ "` keyword is reserved. Try using a different name instead!"
4806 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4807 region = toKeywordRegion row col op
4809 Report.Report "UNEXPECTED SYMBOL" region [] $
4810 Code.toSnippet source surroundings (Just region) $
4813 "I ran into the " ++ op ++ " symbol unexpectedly in this pattern:"
4816 "Only the :: symbol that works in patterns. It is useful if you\
4817 \ are pattern matching on lists, trying to get the first element\
4818 \ off the front. Did you want that instead?"
4821 Code.Close term bracket ->
4823 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4824 region = toRegion row col
4826 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
4827 Code.toSnippet source surroundings (Just region) $
4830 "I ran into a an unexpected " ++ term ++ " in this pattern:"
4833 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
4838 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4839 region = toRegion row col
4841 Report.Report "UNFINISHED PARENTHESES" region [] $
4842 Code.toSnippet source surroundings (Just region) $
4845 "I was partway through parsing a pattern, but I got stuck here:"
4848 ["I","was","expecting","a","closing","parenthesis","next,","so"
4849 ,"try","adding","a",D.dullyellow ")","to","see","if","that","helps?"
4853 PTupleExpr pattern row col ->
4854 toPatternReport source context pattern row col
4856 PTupleSpace space row col ->
4857 toSpaceReport source space row col
4859 PTupleIndentEnd row col ->
4861 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4862 region = toRegion row col
4864 Report.Report "UNFINISHED PARENTHESES" region [] $
4865 Code.toSnippet source surroundings (Just region) $
4868 "I was expecting a closing parenthesis next:"
4871 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
4873 "I can get confused by indentation in cases like this, so\
4874 \ maybe you have a closing parenthesis but it is not indented enough?"
4878 PTupleIndentExpr1 row col ->
4880 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4881 region = toRegion row col
4883 Report.Report "UNFINISHED PARENTHESES" region [] $
4884 Code.toSnippet source surroundings (Just region) $
4887 "I just saw an open parenthesis, but then I got stuck here:"
4890 ["I","was","expecting","to","see","a","pattern","next."
4891 ,"Maybe","it","will","end","up","being","something"
4892 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
4896 PTupleIndentExprN row col ->
4898 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4899 region = toRegion row col
4901 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
4902 Code.toSnippet source surroundings (Just region) $
4905 "I am partway through parsing a tuple pattern, but I got stuck here:"
4909 ["I","was","expecting","to","see","a","pattern","next."
4910 ,"I","am","expecting","the","final","result","to","be","something"
4911 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
4914 "I can get confused by indentation in cases like this, so the problem\
4915 \ may be that the next part is not indented enough?"
4920toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
4921toPListReport source context list startRow startCol =
4923 PListOpen row col ->
4924 case Code.whatIsNext source row col of
4925 Code.Keyword keyword ->
4927 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4928 region = toKeywordRegion row col keyword
4930 Report.Report "RESERVED WORD" region [] $
4931 Code.toSnippet source surroundings (Just region)
4934 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
4937 "This is a reserved word though! Try using some other name?"
4942 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4943 region = toRegion row col
4945 Report.Report "UNFINISHED LIST PATTERN" region [] $
4946 Code.toSnippet source surroundings (Just region) $
4949 "I just saw an open square bracket, but then I got stuck here:"
4951 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4956 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4957 region = toRegion row col
4959 Report.Report "UNFINISHED LIST PATTERN" region [] $
4960 Code.toSnippet source surroundings (Just region) $
4963 "I was expecting a closing square bracket to end this list pattern:"
4965 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4968 PListExpr pattern row col ->
4969 toPatternReport source context pattern row col
4971 PListSpace space row col ->
4972 toSpaceReport source space row col
4974 PListIndentOpen row col ->
4976 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4977 region = toRegion row col
4979 Report.Report "UNFINISHED LIST PATTERN" region [] $
4980 Code.toSnippet source surroundings (Just region) $
4983 "I just saw an open square bracket, but then I got stuck here:"
4986 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4988 "I can get confused by indentation in cases like this, so\
4989 \ maybe there is something next, but it is not indented enough?"
4993 PListIndentEnd row col ->
4995 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4996 region = toRegion row col
4998 Report.Report "UNFINISHED LIST PATTERN" region [] $
4999 Code.toSnippet source surroundings (Just region) $
5002 "I was expecting a closing square bracket to end this list pattern:"
5005 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5007 "I can get confused by indentation in cases like this, so\
5008 \ maybe you have a closing square bracket but it is not indented enough?"
5012 PListIndentExpr row col ->
5014 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5015 region = toRegion row col
5017 Report.Report "UNFINISHED LIST PATTERN" region [] $
5018 Code.toSnippet source surroundings (Just region) $
5021 "I am partway through parsing a list pattern, but I got stuck here:"
5025 "I was expecting to see another pattern next. Maybe a variable name."
5027 "I can get confused by indentation in cases like this, so\
5028 \ maybe there is more to this pattern but it is not indented enough?"
5038 = TC_Annotation Name.Name
5044toTypeReport :: Code.Source -> TContext -> Type -> Row -> Col -> Report.Report
5045toTypeReport source context tipe startRow startCol =
5047 TRecord record row col ->
5048 toTRecordReport source context record row col
5050 TTuple tuple row col ->
5051 toTTupleReport source context tuple row col
5054 case Code.whatIsNext source row col of
5055 Code.Keyword keyword ->
5057 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5058 region = toKeywordRegion row col keyword
5060 Report.Report "RESERVED WORD" region [] $
5061 Code.toSnippet source surroundings (Just region)
5064 "I was expecting to see a type next, but I got stuck on this reserved word:"
5067 "It looks like you are trying to use `" ++ keyword ++ "` as a type variable, but \
5068 \ it is a reserved word. Try using a different name!"
5073 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5074 region = toRegion row col
5078 TC_Annotation _ -> "type annotation"
5079 TC_CustomType -> "custom type"
5080 TC_TypeAlias -> "type alias"
5085 TC_Annotation name -> "the `" ++ Name.toChars name ++ "` type annotation"
5086 TC_CustomType -> "a custom type"
5087 TC_TypeAlias -> "a type alias"
5090 Report.Report ("PROBLEM IN " ++ map Char.toUpper thing) region [] $
5091 Code.toSnippet source surroundings (Just region)
5094 "I was partway through parsing " ++ something ++ ", but I got stuck here:"
5097 ["I","was","expecting","to","see","a","type","next."
5098 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5102 TSpace space row col ->
5103 toSpaceReport source space row col
5105 TIndentStart row col ->
5107 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5108 region = toRegion row col
5112 TC_Annotation _ -> "type annotation"
5113 TC_CustomType -> "custom type"
5114 TC_TypeAlias -> "type alias"
5117 Report.Report ("UNFINISHED " ++ map Char.toUpper thing) region [] $
5118 Code.toSnippet source surroundings (Just region)
5121 "I was partway through parsing a " ++ thing ++ ", but I got stuck here:"
5125 ["I","was","expecting","to","see","a","type","next."
5126 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5129 "I can get confused by indentation. If you think there is already a type\
5130 \ next, maybe it is not indented enough?"
5135toTRecordReport :: Code.Source -> TContext -> TRecord -> Row -> Col -> Report.Report
5136toTRecordReport source context record startRow startCol =
5138 TRecordOpen row col ->
5139 case Code.whatIsNext source row col of
5140 Code.Keyword keyword ->
5142 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5143 region = toKeywordRegion row col keyword
5145 Report.Report "RESERVED WORD" region [] $
5146 Code.toSnippet source surroundings (Just region)
5149 "I just started parsing a record type, but I got stuck on this field name:"
5152 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
5153 \ that is a reserved word. Try using a different name!"
5158 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5159 region = toRegion row col
5161 Report.Report "UNFINISHED RECORD TYPE" region [] $
5162 Code.toSnippet source surroundings (Just region)
5165 "I just started parsing a record type, but I got stuck here:"
5168 ["Record","types","look","like",D.dullyellow "{ name : String, age : Int },"
5169 ,"so","I","was","expecting","to","see","a","field","name","next."
5173 TRecordEnd row col ->
5175 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5176 region = toRegion row col
5178 Report.Report "UNFINISHED RECORD TYPE" region [] $
5179 Code.toSnippet source surroundings (Just region)
5182 "I am partway through parsing a record type, but I got stuck here:"
5186 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
5187 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
5190 "When I get stuck like this, it usually means that there is a missing parenthesis\
5191 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
5195 TRecordField row col ->
5196 case Code.whatIsNext source row col of
5197 Code.Keyword keyword ->
5199 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5200 region = toKeywordRegion row col keyword
5202 Report.Report "RESERVED WORD" region [] $
5203 Code.toSnippet source surroundings (Just region)
5206 "I am partway through parsing a record type, but I got stuck on this field name:"
5209 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
5210 \ that is a reserved word. Try using a different name!"
5215 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5216 region = toRegion row col
5218 Report.Report "UNFINISHED RECORD TYPE" region [] $
5219 Code.toSnippet source surroundings (Just region)
5222 "I am partway through parsing a record type, but I got stuck after that last comma:"
5224 addNoteForRecordTypeError $
5226 "Trailing commas are not allowed in records, so I was expecting to see another\
5227 \ record field defined next. If you are done defining the record, the fix may\
5228 \ be to delete that last comma?"
5231 TRecordColon row col ->
5233 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5234 region = toRegion row col
5236 Report.Report "UNFINISHED RECORD TYPE" region [] $
5237 Code.toSnippet source surroundings (Just region)
5240 "I am partway through parsing a record type, but I got stuck here:"
5242 addNoteForRecordTypeError $
5244 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
5245 ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
5249 TRecordType tipe row col ->
5250 toTypeReport source context tipe row col
5252 TRecordSpace space row col ->
5253 toSpaceReport source space row col
5255 TRecordIndentOpen row col ->
5257 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5258 region = toRegion row col
5260 Report.Report "UNFINISHED RECORD TYPE" region [] $
5261 Code.toSnippet source surroundings (Just region)
5264 "I just saw the opening curly brace of a record type, but then I got stuck here:"
5266 addNoteForRecordTypeIndentError $
5268 ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
5269 ,"Try","defining","some","fields","of","your","own?"
5273 TRecordIndentEnd row col ->
5275 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5276 region = toRegion row col
5278 Report.Report "UNFINISHED RECORD TYPE" region [] $
5279 Code.toSnippet source surroundings (Just region)
5282 "I was expecting to see a closing curly brace next:"
5284 addNoteForRecordTypeIndentError $
5286 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
5290 TRecordIndentField row col ->
5292 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5293 region = toRegion row col
5295 Report.Report "UNFINISHED RECORD TYPE" region [] $
5296 Code.toSnippet source surroundings (Just region)
5299 "I am partway through parsing a record type, but I got stuck after that last comma:"
5301 addNoteForRecordTypeIndentError $
5303 "Trailing commas are not allowed in record types, so the fix may be to\
5304 \ delete that last comma? Or maybe you were in the middle of defining\
5305 \ an additional field?"
5308 TRecordIndentColon row col ->
5310 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5311 region = toRegion row col
5313 Report.Report "UNFINISHED RECORD TYPE" region [] $
5314 Code.toSnippet source surroundings (Just region)
5317 "I am partway through parsing a record type. I just saw a record\
5318 \ field, so I was expecting to see a colon next:"
5320 addNoteForRecordTypeIndentError $
5322 ["Try","putting","an",D.green ":","followed","by","a","type?"
5326 TRecordIndentType row col ->
5328 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5329 region = toRegion row col
5331 Report.Report "UNFINISHED RECORD TYPE" region [] $
5332 Code.toSnippet source surroundings (Just region)
5335 "I am partway through parsing a record type, and I was expecting to run into a type next:"
5337 addNoteForRecordTypeIndentError $
5339 ["Try","putting","something","like"
5340 ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5345addNoteForRecordTypeError :: D.Doc -> D.Doc
5346addNoteForRecordTypeError normalRecommendation =
5348 normalRecommendation
5351 "If you are trying to define a record type across multiple lines, I recommend using this format:"
5352 , D.indent 4 $ D.vcat $
5355 , ", height : Float"
5359 "Notice that each line starts with some indentation. Usually two or four spaces. I\
5360 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5361 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5365addNoteForRecordTypeIndentError :: D.Doc -> D.Doc
5366addNoteForRecordTypeIndentError normalRecommendation =
5368 normalRecommendation
5371 "I may be confused by indentation. For example, if you are trying to define\
5372 \ a record type across multiple lines, I recommend using this format:"
5373 , D.indent 4 $ D.vcat $
5376 , ", height : Float"
5380 "Notice that each line starts with some indentation. Usually two or four spaces. I\
5381 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5382 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5386toTTupleReport :: Code.Source -> TContext -> TTuple -> Row -> Col -> Report.Report
5387toTTupleReport source context tuple startRow startCol =
5389 TTupleOpen row col ->
5390 case Code.whatIsNext source row col of
5391 Code.Keyword keyword ->
5393 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5394 region = toKeywordRegion row col keyword
5396 Report.Report "RESERVED WORD" region [] $
5397 Code.toSnippet source surroundings (Just region)
5400 "I ran into a reserved word unexpectedly:"
5403 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but \
5404 \ it is a reserved word. Try using a different name!"
5409 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5410 region = toRegion row col
5412 Report.Report "UNFINISHED PARENTHESES" region [] $
5413 Code.toSnippet source surroundings (Just region)
5416 "I just saw an open parenthesis, so I was expecting to see a type next."
5419 ["Something","like",D.dullyellow "(Maybe Int)","or"
5420 ,D.dullyellow "(List Person)" <> "."
5421 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5425 TTupleEnd row col ->
5427 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5428 region = toRegion row col
5430 Report.Report "UNFINISHED PARENTHESES" region [] $
5431 Code.toSnippet source surroundings (Just region)
5434 "I was expecting to see a closing parenthesis next, but I got stuck here:"
5437 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
5439 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
5440 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
5441 \ or missing brackets) that is confusing me."
5445 TTupleType tipe row col ->
5446 toTypeReport source context tipe row col
5448 TTupleSpace space row col ->
5449 toSpaceReport source space row col
5451 TTupleIndentType1 row col ->
5453 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5454 region = toRegion row col
5456 Report.Report "UNFINISHED PARENTHESES" region [] $
5457 Code.toSnippet source surroundings (Just region)
5460 "I just saw an open parenthesis, so I was expecting to see a type next."
5464 ["Something","like",D.dullyellow "(Maybe Int)","or"
5465 ,D.dullyellow "(List Person)" <> "."
5466 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5469 "I can get confused by indentation in cases like this, so\
5470 \ maybe you have a type but it is not indented enough?"
5474 TTupleIndentTypeN row col ->
5476 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5477 region = toRegion row col
5479 Report.Report "UNFINISHED TUPLE TYPE" region [] $
5480 Code.toSnippet source surroundings (Just region)
5483 "I think I am in the middle of parsing a tuple type. I just saw a comma, so I was expecting to see a type next."
5487 ["A","tuple","type","looks","like",D.dullyellow "(Float,Float)","or"
5488 ,D.dullyellow "(String,Int)" <> ","
5489 ,"so","I","think","there","is","a","type","missing","here?"
5492 "I can get confused by indentation in cases like this, so\
5493 \ maybe you have an expression but it is not indented enough?"
5497 TTupleIndentEnd row col ->
5499 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5500 region = toRegion row col
5502 Report.Report "UNFINISHED PARENTHESES" region [] $
5503 Code.toSnippet source surroundings (Just region)
5506 "I was expecting to see a closing parenthesis next:"
5509 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
5511 "I can get confused by indentation in cases like this, so\
5512 \ maybe you have a closing parenthesis but it is not indented enough?"
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