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
72 | NoPortsInPackage (A.Located Name.Name)
73 | NoPortModulesInPackage A.Region
74 | NoEffectsOutsideKernel A.Region
83 = ModuleSpace Space Row Col
84 | ModuleBadEnd Row Col
86 | ModuleProblem Row Col
88 | ModuleExposing Exposing Row Col
90 | PortModuleProblem Row Col
91 | PortModuleName Row Col
92 | PortModuleExposing Exposing Row Col
101 | ImportAlias Row Col
102 | ImportExposing Row Col
103 | ImportExposingList Exposing Row Col
104 | ImportEnd Row Col -- different based on col=1 or if greater
106 | ImportIndentName Row Col
107 | ImportIndentAlias Row Col
108 | ImportIndentExposingList Row Col
112 | Declarations Decl Row Col
116 = ExposingSpace Space Row Col
117 | ExposingStart Row Col
118 | ExposingValue Row Col
119 | ExposingOperator Row Col
120 | ExposingOperatorReserved BadOperator Row Col
121 | ExposingOperatorRightParen Row Col
122 | ExposingTypePrivacy Row Col
123 | ExposingEnd Row Col
125 | ExposingIndentEnd Row Col
126 | ExposingIndentValue Row Col
135 | DeclSpace Space Row Col
138 | DeclType DeclType Row Col
139 | DeclDef Name.Name DeclDef Row Col
141 | DeclFreshLineAfterDocComment Row Col
145 = DeclDefSpace Space Row Col
146 | DeclDefEquals Row Col
147 | DeclDefType Type Row Col
148 | DeclDefArg Pattern Row Col
149 | DeclDefBody Expr Row Col
150 | DeclDefNameRepeat Row Col
151 | DeclDefNameMatch Name.Name Row Col
153 | DeclDefIndentType Row Col
154 | DeclDefIndentEquals Row Col
155 | DeclDefIndentBody Row Col
159 = PortSpace Space Row Col
162 | PortType Type Row Col
163 | PortIndentName Row Col
164 | PortIndentColon Row Col
165 | PortIndentType Row Col
173 = DT_Space Space Row Col
175 | DT_Alias TypeAlias Row Col
176 | DT_Union CustomType Row Col
178 | DT_IndentName Row Col
182 = AliasSpace Space Row Col
184 | AliasEquals Row Col
185 | AliasBody Type Row Col
187 | AliasIndentEquals Row Col
188 | AliasIndentBody Row Col
192 = CT_Space Space Row Col
197 | CT_VariantArg Type Row Col
199 | CT_IndentEquals Row Col
200 | CT_IndentBar Row Col
201 | CT_IndentAfterBar Row Col
202 | CT_IndentAfterEquals Row Col
214 | Record Record Row Col
215 | Tuple Tuple Row Col
220 | OperatorRight Name.Name Row Col
221 | OperatorReserved BadOperator Row Col
225 | String String Row Col
226 | Number Number Row Col
227 | Space Space Row Col
228 | EndlessShader Row Col
229 | ShaderProblem [Char.Char] Row Col
230 | IndentOperatorRight Name.Name Row Col
236 | RecordField Row Col
237 | RecordEquals Row Col
238 | RecordExpr Expr Row Col
239 | RecordSpace Space Row Col
241 | RecordIndentOpen Row Col
242 | RecordIndentEnd Row Col
243 | RecordIndentField Row Col
244 | RecordIndentEquals Row Col
245 | RecordIndentExpr Row Col
249 = TupleExpr Expr Row Col
250 | TupleSpace Space Row Col
252 | TupleOperatorClose Row Col
253 | TupleOperatorReserved BadOperator Row Col
255 | TupleIndentExpr1 Row Col
256 | TupleIndentExprN Row Col
257 | TupleIndentEnd Row Col
261 = ListSpace Space Row Col
263 | ListExpr Expr Row Col
266 | ListIndentOpen Row Col
267 | ListIndentEnd Row Col
268 | ListIndentExpr Row Col
272 = FuncSpace Space Row Col
273 | FuncArg Pattern Row Col
274 | FuncBody Expr Row Col
277 | FuncIndentArg Row Col
278 | FuncIndentArrow Row Col
279 | FuncIndentBody Row Col
283 = CaseSpace Space Row Col
285 | CasePattern Pattern Row Col
287 | CaseExpr Expr Row Col
288 | CaseBranch Expr Row Col
290 | CaseIndentOf Row Col
291 | CaseIndentExpr Row Col
292 | CaseIndentPattern Row Col
293 | CaseIndentArrow Row Col
294 | CaseIndentBranch Row Col
295 | CasePatternAlignment Word16 Row Col
299 = IfSpace Space Row Col
302 | IfElseBranchStart Row Col
304 | IfCondition Expr Row Col
305 | IfThenBranch Expr Row Col
306 | IfElseBranch Expr Row Col
308 | IfIndentCondition Row Col
309 | IfIndentThen Row Col
310 | IfIndentThenBranch Row Col
311 | IfIndentElseBranch Row Col
312 | IfIndentElse Row Col
316 = LetSpace Space Row Col
318 | LetDefAlignment Word16 Row Col
320 | LetDef Name.Name Def Row Col
321 | LetDestruct Destruct Row Col
322 | LetBody Expr Row Col
323 | LetIndentDef Row Col
324 | LetIndentIn Row Col
325 | LetIndentBody Row Col
329 = DefSpace Space Row Col
330 | DefType Type Row Col
331 | DefNameRepeat Row Col
332 | DefNameMatch Name.Name Row Col
333 | DefArg Pattern Row Col
335 | DefBody Expr Row Col
336 | DefIndentEquals Row Col
337 | DefIndentType Row Col
338 | DefIndentBody Row Col
339 | DefAlignment Word16 Row Col
343 = DestructSpace Space Row Col
344 | DestructPattern Pattern Row Col
345 | DestructEquals Row Col
346 | DestructBody Expr Row Col
347 | DestructIndentEquals Row Col
348 | DestructIndentBody Row Col
356 = PRecord PRecord Row Col
357 | PTuple PTuple Row Col
358 | PList PList Row Col
362 | PString String Row Col
363 | PNumber Number Row Col
364 | PFloat Word16 Row Col
366 | PWildcardNotVar Name.Name Int Row Col
367 | PSpace Space Row Col
369 | PIndentStart Row Col
370 | PIndentAlias Row Col
374 = PRecordOpen Row Col
376 | PRecordField Row Col
377 | PRecordSpace Space Row Col
379 | PRecordIndentOpen Row Col
380 | PRecordIndentEnd Row Col
381 | PRecordIndentField Row Col
387 | PTupleExpr Pattern Row Col
388 | PTupleSpace Space Row Col
390 | PTupleIndentEnd Row Col
391 | PTupleIndentExpr1 Row Col
392 | PTupleIndentExprN Row Col
398 | PListExpr Pattern Row Col
399 | PListSpace Space Row Col
401 | PListIndentOpen Row Col
402 | PListIndentEnd Row Col
403 | PListIndentExpr Row Col
411 = TRecord TRecord Row Col
412 | TTuple TTuple Row Col
415 | TSpace Space Row Col
417 | TIndentStart Row Col
421 = TRecordOpen Row Col
424 | TRecordField Row Col
425 | TRecordColon Row Col
426 | TRecordType Type Row Col
428 | TRecordSpace Space Row Col
430 | TRecordIndentOpen Row Col
431 | TRecordIndentField Row Col
432 | TRecordIndentColon Row Col
433 | TRecordIndentType Row Col
434 | TRecordIndentEnd Row Col
440 | TTupleType Type Row Col
441 | TTupleSpace Space Row Col
443 | TTupleIndentType1 Row Col
444 | TTupleIndentTypeN Row Col
445 | TTupleIndentEnd Row Col
455 | CharNotString Word16
459 = StringEndless_Single
460 | StringEndless_Multi
461 | StringEscape Escape
466 | BadUnicodeFormat Word16
467 | BadUnicodeCode Word16
468 | BadUnicodeLength Word16 Int Int
475 | NumberNoLeadingZero
484 | EndlessMultiComment
491toReport :: Code.Source -> Error -> Report.Report
494 ModuleNameUnspecified name ->
496 region = toRegion 1 1
498 Report.Report "MODULE NAME MISSING" region [] $
501 "I need the module name to be declared at the top of this file, like this:"
502 , D.indent 4 $ D.fillSep $
503 [ D.cyan "module", D.fromName name, D.cyan "exposing", "(..)" ]
505 "Try adding that as the first line of your file!"
507 "It is best to replace (..) with an explicit list of types and\
508 \ functions you want to expose. When you know a value is only used\
509 \ within this module, you can refactor without worrying about uses\
510 \ elsewhere. Limiting exposed values can also speed up compilation\
511 \ because I can skip a bunch of work if I see that the exposed API\
515 ModuleNameMismatch expectedName (A.At region actualName) ->
516 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
517 Code.toSnippet source region Nothing
519 "It looks like this module name is out of sync:"
523 "I need it to match the file path, so I was expecting to see `"
524 ++ ModuleName.toChars expectedName
525 ++ "` here. Make the following change, and you should be all set!"
527 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
529 "I require that module names correspond to file paths. This makes it much\
530 \ easier to explore unfamiliar codebases! So if you want to keep the current\
531 \ module name, try renaming the file instead."
535 UnexpectedPort region ->
536 Report.Report "UNEXPECTED PORTS" region [] $
537 Code.toSnippet source region Nothing
540 "You are declaring ports in a normal module."
544 ["Switch","this","to","say",D.cyan "port module","instead,"
545 ,"marking","that","this","module","contains","port","declarations."
548 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
550 "to learn the syntax and how to use it effectively."
555 Report.Report "NO PORTS" region [] $
556 Code.toSnippet source region Nothing
559 "This module does not declare any ports, but it says it will:"
562 ["Switch","this","to",D.cyan "module"
563 ,"and","you","should","be","all","set!"
567 NoPortsInPackage (A.At region _) ->
568 Report.Report "PACKAGES CANNOT HAVE PORTS" region [] $
569 Code.toSnippet source region Nothing
572 "Packages cannot declare any ports, so I am getting stuck here:"
576 "Remove this port declaration."
577 , noteForPortsInPackage
581 NoPortModulesInPackage region ->
582 Report.Report "PACKAGES CANNOT HAVE PORTS" region [] $
583 Code.toSnippet source region Nothing
586 "Packages cannot declare any ports, so I am getting stuck here:"
590 ["Remove","the",D.cyan "port","keyword","and","I"
591 ,"should","be","able","to","continue."
593 , noteForPortsInPackage
597 NoEffectsOutsideKernel region ->
598 Report.Report "INVALID EFFECT MODULE" region [] $
599 Code.toSnippet source region Nothing
602 "It is not possible to declare an `effect module` outside the @elm organization,\
603 \ so I am getting stuck here:"
607 "Switch to a normal module declaration."
609 "Effect modules are designed to allow certain core functionality to be\
610 \ defined separately from the compiler. So the @elm organization has access to\
611 \ this so that certain changes, extensions, and fixes can be introduced without\
612 \ needing to release new Elm binaries. For example, we want to make it possible\
613 \ to test effects, but this may require changes to the design of effect modules.\
614 \ By only having them defined in the @elm organization, that kind of design work\
615 \ can proceed much more smoothly."
620 toParseErrorReport source modul
623noteForPortsInPackage :: D.Doc
624noteForPortsInPackage =
627 "One of the major goals of the package ecosystem is to be completely written\
628 \ in Elm. This means when you install an Elm package, you can be sure you are safe\
629 \ from security issues on install and that you are not going to get any runtime\
630 \ exceptions coming from your new dependency. This design also sets the ecosystem\
631 \ up to target other platforms more easily (like mobile phones, WebAssembly, etc.)\
632 \ since no community code explicitly depends on JavaScript even existing."
634 "Given that overall goal, allowing ports in packages would lead to some pretty\
635 \ surprising behavior. If ports were allowed in packages, you could install a\
636 \ package but not realize that it brings in an indirect dependency that defines a\
637 \ port. Now you have a program that does not work and the fix is to realize that\
638 \ some JavaScript needs to be added for a dependency you did not even know about.\
639 \ That would be extremely frustrating! \"So why not allow the package author to\
640 \ include the necessary JS code as well?\" Now we are back in conflict with our\
641 \ overall goal to keep all community packages free from runtime exceptions."
645toParseErrorReport :: Code.Source -> Module -> Report.Report
646toParseErrorReport source modul =
648 ModuleSpace space row col ->
649 toSpaceReport source space row col
651 ModuleBadEnd row col ->
653 then toDeclStartReport source row col
654 else toWeirdEndReport source row col
656 ModuleProblem row col ->
658 region = toRegion row col
660 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
661 Code.toSnippet source region Nothing
664 "I am parsing an `module` declaration, but I got stuck here:"
668 "Here are some examples of valid `module` declarations:"
669 , D.indent 4 $ D.vcat $
670 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
671 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
674 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
675 \ of files when the public interface of a module stays the same, so exposing fewer\
676 \ values can help improve compile times!"
680 ModuleName row col ->
682 region = toRegion row col
684 Report.Report "EXPECTING MODULE NAME" region [] $
685 Code.toSnippet source region Nothing
688 "I was parsing an `module` declaration until I got stuck here:"
692 "I was expecting to see the module name next, like in these examples:"
693 , D.indent 4 $ D.vcat $
694 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
695 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
696 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
697 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
700 "Notice that the module names all start with capital letters. That is required!"
704 ModuleExposing exposing row col ->
705 toExposingReport source exposing row col
707 PortModuleProblem row col ->
709 region = toRegion row col
711 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
712 Code.toSnippet source region Nothing
715 "I am parsing an `port module` declaration, but I got stuck here:"
719 "Here are some examples of valid `port module` declarations:"
720 , D.indent 4 $ D.vcat $
721 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
722 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
724 , D.link "Note" "Read" "ports" "for more help."
728 PortModuleName row col ->
730 region = toRegion row col
732 Report.Report "EXPECTING MODULE NAME" region [] $
733 Code.toSnippet source region Nothing
736 "I was parsing an `module` declaration until I got stuck here:"
740 "I was expecting to see the module name next, like in these examples:"
741 , D.indent 4 $ D.vcat $
742 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
743 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
746 "Notice that the module names start with capital letters. That is required!"
750 PortModuleExposing exposing row col ->
751 toExposingReport source exposing row col
755 region = toRegion row col
757 Report.Report "BAD MODULE DECLARATION" region [] $
758 Code.toSnippet source region Nothing
761 "I cannot parse this module declaration:"
764 "This type of module is reserved for the @elm organization. It is used to\
765 \ define certain effects, avoiding building them into the compiler."
770 region = toRegion row col
772 toBadFirstLineReport keyword =
773 Report.Report "TOO MUCH INDENTATION" region [] $
774 Code.toSnippet source region Nothing
777 "This `" ++ keyword ++ "` should not have any spaces before it:"
780 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
784 case Code.whatIsNext source row col of
785 Code.Keyword "module" -> toBadFirstLineReport "module"
786 Code.Keyword "import" -> toBadFirstLineReport "import"
787 Code.Keyword "type" -> toBadFirstLineReport "type"
788 Code.Keyword "port" -> toBadFirstLineReport "port"
790 Report.Report "SYNTAX PROBLEM" region [] $
791 Code.toSnippet source region Nothing
798 "I am not sure what is going on, but I recommend starting an Elm\
799 \ file with the following lines:"
800 , D.indent 4 $ D.vcat $
801 [ D.fillSep [D.cyan "import","Html"]
804 , " Html.text " <> D.dullyellow "\"Hello!\""
807 "You should be able to copy those lines directly into your file. Check out the\
808 \ examples at <https://elm-lang.org/examples> for more help getting started!"
810 "This can also happen when something is indented too much!"
814 ImportStart row col ->
815 toImportReport source row col
817 ImportName row col ->
819 region = toRegion row col
821 Report.Report "EXPECTING IMPORT NAME" region [] $
822 Code.toSnippet source region Nothing
825 "I was parsing an `import` until I got stuck here:"
829 "I was expecting to see a module name next, like in these examples:"
830 , D.indent 4 $ D.vcat $
831 [ D.fillSep [D.cyan "import","Dict"]
832 , D.fillSep [D.cyan "import","Maybe"]
833 , D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","A"]
834 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "exposing","(..)"]
837 "Notice that the module names all start with capital letters. That is required!"
838 , D.reflowLink "Read" "imports" "to learn more."
843 toImportReport source row col
845 ImportAlias row col ->
847 region = toRegion row col
849 Report.Report "EXPECTING IMPORT ALIAS" region [] $
850 Code.toSnippet source region Nothing
853 "I was parsing an `import` until I got stuck here:"
857 "I was expecting to see an alias next, like in these examples:"
858 , D.indent 4 $ D.vcat $
859 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
860 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
861 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
864 "Notice that the alias always starts with a capital letter. That is required!"
865 , D.reflowLink "Read" "imports" "to learn more."
869 ImportExposing row col ->
870 toImportReport source row col
872 ImportExposingList exposing row col ->
873 toExposingReport source exposing row col
876 toImportReport source row col
878 ImportIndentName row col ->
879 toImportReport source row col
881 ImportIndentAlias row col ->
882 toImportReport source row col
884 ImportIndentExposingList row col ->
886 region = toRegion row col
888 Report.Report "UNFINISHED IMPORT" region [] $
889 Code.toSnippet source region Nothing
892 "I was parsing an `import` until I got stuck here:"
896 "I was expecting to see the list of exposed values next. For example, here\
897 \ are two ways to expose values from the `Html` module:"
898 , D.indent 4 $ D.vcat $
899 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
900 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
903 "I generally recommend the second style. It is more explicit, making it\
904 \ much easier to figure out where values are coming from in large projects!"
910 region = toRegion row col
912 Report.Report "BAD INFIX" region [] $
913 Code.toSnippet source region Nothing
916 "Something went wrong in this infix operator declaration:"
919 "This feature is used by the @elm organization to define the\
920 \ languages built-in operators."
923 Declarations decl _ _ ->
924 toDeclarationsReport source decl
931toWeirdEndReport :: Code.Source -> Row -> Col -> Report.Report
932toWeirdEndReport source row col =
933 case Code.whatIsNext source row col of
934 Code.Keyword keyword ->
936 region = toKeywordRegion row col keyword
938 Report.Report "RESERVED WORD" region [] $
939 Code.toSnippet source region Nothing
942 "I got stuck on this reserved word:"
945 "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
950 region = toKeywordRegion row col op
952 Report.Report "UNEXPECTED SYMBOL" region [] $
953 Code.toSnippet source region Nothing
956 "I ran into an unexpected symbol:"
959 "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
960 \ I can give a better hint from there?"
963 Code.Close term bracket ->
965 region = toRegion row col
967 Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
968 Code.toSnippet source region Nothing
971 "I ran into an unexpected " ++ term ++ ":"
974 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
979 region = toKeywordRegion row col (c:cs)
981 Report.Report "UNEXPECTED NAME" region [] $
982 Code.toSnippet source region Nothing
985 "I got stuck on this name:"
988 "It is confusing me a lot! Normally I can give fairly specific hints, but\
989 \ something is really tripping me up this time."
994 region = toKeywordRegion row col (c:cs)
996 Report.Report "UNEXPECTED NAME" region [] $
997 Code.toSnippet source region Nothing
1000 "I got stuck on this name:"
1003 "It is confusing me a lot! Normally I can give fairly specific hints, but\
1004 \ something is really tripping me up this time."
1007 Code.Other maybeChar ->
1009 region = toRegion row col
1013 Report.Report "UNEXPECTED SEMICOLON" region [] $
1014 Code.toSnippet source region Nothing
1017 "I got stuck on this semicolon:"
1020 [ D.reflow $ "Try removing it?"
1022 "Some languages require semicolons at the end of each statement. These are\
1023 \ often called C-like languages, and they usually share a lot of language design\
1024 \ choices. (E.g. side-effects, for loops, etc.) Elm manages effects with commands\
1025 \ and subscriptions instead, so there is no special syntax for \"statements\" and\
1026 \ therefore no need to use semicolons to separate them. I think this will make\
1027 \ more sense as you work through <https://guide.elm-lang.org> though!"
1032 Report.Report "UNEXPECTED COMMA" region [] $
1033 Code.toSnippet source region Nothing
1036 "I got stuck on this comma:"
1040 "I do not think I am parsing a list or tuple right now. Try deleting the comma?"
1042 "If this is supposed to be part of a list, the problem may be a bit earlier.\
1043 \ Perhaps the opening [ is missing? Or perhaps some value in the list has an extra\
1044 \ closing ] that is making me think the list ended earlier? The same kinds of\
1045 \ things could be going wrong if this is supposed to be a tuple."
1050 Report.Report "UNEXPECTED CHARACTER" region [] $
1051 Code.toSnippet source region Nothing
1054 "I got stuck on this character:"
1058 "It is not used for anything in Elm syntax. It is used for multi-line strings in\
1059 \ some languages though, so if you want a string that spans multiple lines, you\
1060 \ can use Elm's multi-line string syntax like this:"
1061 , D.dullyellow $ D.indent 4 $ D.vcat $
1063 , "# Multi-line Strings"
1065 , "- start with triple double quotes"
1066 , "- write whatever you want"
1067 , "- no need to escape newlines or double quotes"
1068 , "- end with triple double quotes"
1072 "Otherwise I do not know what is going on! Try removing the character?"
1077 Report.Report "UNEXPECTED SYMBOL" region [] $
1078 Code.toSnippet source region Nothing
1081 "I got stuck on this dollar sign:"
1084 "It is not used for anything in Elm syntax. Are you coming from a language where\
1085 \ dollar signs can be used in variable names? If so, try a name that (1) starts\
1086 \ with a letter and (2) only contains letters, numbers, and underscores."
1089 Just c | elem c ['#','@','!','%','~'] ->
1090 Report.Report "UNEXPECTED SYMBOL" region [] $
1091 Code.toSnippet source region Nothing
1094 "I got stuck on this symbol:"
1097 "It is not used for anything in Elm syntax. Try removing it?"
1101 Report.Report "SYNTAX PROBLEM" region [] $
1102 Code.toSnippet source region Nothing
1108 "Whatever I am running into is confusing me a lot! Normally I can give fairly\
1109 \ specific hints, but something is really tripping me up this time."
1117toImportReport :: Code.Source -> Row -> Col -> Report.Report
1118toImportReport source row col =
1120 region = toRegion row col
1122 Report.Report "UNFINISHED IMPORT" region [] $
1123 Code.toSnippet source region Nothing
1126 "I am partway through parsing an import, but I got stuck here:"
1130 "Here are some examples of valid `import` declarations:"
1131 , D.indent 4 $ D.vcat $
1132 [ D.fillSep [D.cyan "import","Html"]
1133 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
1134 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
1135 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
1138 "You are probably trying to import a different module, but try to make it look like one of these examples!"
1139 , D.reflowLink "Read" "imports" "to learn more."
1148toExposingReport :: Code.Source -> Exposing -> Row -> Col -> Report.Report
1149toExposingReport source exposing startRow startCol =
1151 ExposingSpace space row col ->
1152 toSpaceReport source space row col
1154 ExposingStart row col ->
1156 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1157 region = toRegion row col
1159 Report.Report "PROBLEM IN EXPOSING" region [] $
1160 Code.toSnippet source surroundings (Just region)
1163 "I want to parse exposed values, but I am getting stuck here:"
1167 ["Exposed","values","are","always","surrounded","by","parentheses."
1168 ,"So","try","adding","a",D.green "(","here?"
1170 , D.toSimpleNote "Here are some valid examples of `exposing` for reference:"
1171 , D.indent 4 $ D.vcat $
1172 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1173 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
1176 "If you are getting tripped up, you can just expose everything for now. It should\
1177 \ get easier to make an explicit exposing list as you see more examples in the wild."
1181 ExposingValue row col ->
1182 case Code.whatIsNext source row col of
1183 Code.Keyword keyword ->
1185 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1186 region = toKeywordRegion row col keyword
1188 Report.Report "RESERVED WORD" region [] $
1189 Code.toSnippet source surroundings (Just region)
1192 "I got stuck on this reserved word:"
1195 "It looks like you are trying to expose `" ++ keyword ++ "` but that is a reserved word. Is there a typo?"
1200 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1201 region = toKeywordRegion row col op
1203 Report.Report "UNEXPECTED SYMBOL" region [] $
1204 Code.toSnippet source surroundings (Just region)
1207 "I got stuck on this symbol:"
1211 "If you are trying to expose an operator, add parentheses around it like this:"
1212 , D.indent 4 $ D.dullyellow (D.fromChars op) <> " -> " <> D.green ("(" <> D.fromChars op <> ")")
1218 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1219 region = toRegion row col
1221 Report.Report "PROBLEM IN EXPOSING" region [] $
1222 Code.toSnippet source surroundings (Just region)
1225 "I got stuck while parsing these exposed values:"
1229 "I do not have an exact recommendation, so here are some valid examples\
1230 \ of `exposing` for reference:"
1231 , D.indent 4 $ D.vcat $
1232 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1233 , D.fillSep [D.cyan "import","Basics",D.cyan "exposing","(Int, Float, Bool(..), (+), not, sqrt)"]
1236 "These examples show how to expose types, variants, operators, and functions. Everything\
1237 \ should be some permutation of these examples, just with different names."
1241 ExposingOperator row col ->
1243 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1244 region = toRegion row col
1246 Report.Report "PROBLEM IN EXPOSING" region [] $
1247 Code.toSnippet source surroundings (Just region)
1250 "I just saw an open parenthesis, so I was expecting an operator next:"
1253 ["It","is","possible","to","expose","operators,","so","I","was","expecting"
1254 ,"to","see","something","like",D.dullyellow "(+)","or",D.dullyellow "(|=)"
1255 ,"or",D.dullyellow "(||)","after","I","saw","that","open","parenthesis."
1259 ExposingOperatorReserved op row col ->
1261 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1262 region = toRegion row col
1264 Report.Report "RESERVED SYMBOL" region [] $
1265 Code.toSnippet source surroundings (Just region)
1268 "I cannot expose this as an operator:"
1271 BadDot -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1272 BadPipe -> D.fillSep ["Maybe","you","want",D.dullyellow "(||)","instead?"]
1273 BadArrow -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1274 BadEquals -> D.fillSep ["Maybe","you","want",D.dullyellow "(==)","instead?"]
1275 BadHasType -> D.fillSep ["Maybe","you","want",D.dullyellow "(::)","instead?"]
1278 ExposingOperatorRightParen row col ->
1280 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1281 region = toRegion row col
1283 Report.Report "PROBLEM IN EXPOSING" region [] $
1284 Code.toSnippet source surroundings (Just region)
1287 "It looks like you are exposing an operator, but I got stuck here:"
1290 ["I","was","expecting","to","see","the","closing","parenthesis","immediately"
1291 ,"after","the","operator.","Try","adding","a",D.green ")","right","here?"
1295 ExposingEnd row col ->
1297 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1298 region = toRegion row col
1300 Report.Report "UNFINISHED EXPOSING" region [] $
1301 Code.toSnippet source surroundings (Just region)
1304 "I was partway through parsing exposed values, but I got stuck here:"
1307 "Maybe there is a comma missing before this?"
1310 ExposingTypePrivacy row col ->
1312 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1313 region = toRegion row col
1315 Report.Report "PROBLEM EXPOSING CUSTOM TYPE VARIANTS" region [] $
1316 Code.toSnippet source surroundings (Just region)
1319 "It looks like you are trying to expose the variants of a custom type:"
1323 ["You","need","to","write","something","like"
1324 ,D.dullyellow "Status(..)","or",D.dullyellow "Entity(..)"
1325 ,"though.","It","is","all","or","nothing,","otherwise","`case`"
1326 ,"expressions","could","miss","a","variant","and","crash!"
1329 "It is often best to keep the variants hidden! If someone pattern matches on\
1330 \ the variants, it is a MAJOR change if any new variants are added. Suddenly\
1331 \ their `case` expressions do not cover all variants! So if you do not need\
1332 \ people to pattern match, keep the variants hidden and expose functions to\
1333 \ construct values of this type. This way you can add new variants as a MINOR change!"
1337 ExposingIndentEnd row col ->
1339 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1340 region = toRegion row col
1342 Report.Report "UNFINISHED EXPOSING" region [] $
1343 Code.toSnippet source surroundings (Just region)
1346 "I was partway through parsing exposed values, but I got stuck here:"
1350 ["I","was","expecting","a","closing","parenthesis."
1351 ,"Try","adding","a",D.green ")","right","here?"
1354 "I can get confused when there is not enough indentation, so if you already\
1355 \ have a closing parenthesis, it probably just needs some spaces in front of it."
1359 ExposingIndentValue row col ->
1361 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1362 region = toRegion row col
1364 Report.Report "UNFINISHED EXPOSING" region [] $
1365 Code.toSnippet source surroundings (Just region)
1368 "I was partway through parsing exposed values, but I got stuck here:"
1371 "I was expecting another value to expose."
1379toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
1380toSpaceReport source space row col =
1384 region = toRegion row col
1386 Report.Report "NO TABS" region [] $
1387 Code.toSnippet source region Nothing
1390 "I ran into a tab, but tabs are not allowed in Elm files."
1393 "Replace the tab with spaces."
1396 EndlessMultiComment ->
1398 region = toWiderRegion row col 2
1400 Report.Report "ENDLESS COMMENT" region [] $
1401 Code.toSnippet source region Nothing
1404 "I cannot find the end of this multi-line comment:"
1407 [ D.reflow "Add a -} somewhere after this to end the comment."
1409 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
1410 \ that happens to contain another comment. Like parentheses and curly braces,\
1411 \ the start and end markers must always be balanced. Maybe that is the problem?"
1420toRegion :: Row -> Col -> A.Region
1423 pos = A.Position row col
1428toWiderRegion :: Row -> Col -> Word16 -> A.Region
1429toWiderRegion row col extra =
1431 (A.Position row col)
1432 (A.Position row (col + extra))
1435toKeywordRegion :: Row -> Col -> [Char.Char] -> A.Region
1436toKeywordRegion row col keyword =
1438 (A.Position row col)
1439 (A.Position row (col + fromIntegral (length keyword)))
1442toDeclarationsReport :: Code.Source -> Decl -> Report.Report
1443toDeclarationsReport source decl =
1445 DeclStart row col ->
1446 toDeclStartReport source row col
1448 DeclSpace space row col ->
1449 toSpaceReport source space row col
1451 Port port_ row col ->
1452 toPortReport source port_ row col
1454 DeclType declType row col ->
1455 toDeclTypeReport source declType row col
1457 DeclDef name declDef row col ->
1458 toDeclDefReport source name declDef row col
1460 DeclFreshLineAfterDocComment row col ->
1462 region = toRegion row col
1464 Report.Report "EXPECTING DECLARATION" region [] $
1465 Code.toSnippet source region Nothing
1468 "I just saw a doc comment, but then I got stuck here:"
1471 "I was expecting to see the corresponding declaration next, starting on a fresh\
1472 \ line with no indentation."
1476toDeclStartReport :: Code.Source -> Row -> Col -> Report.Report
1477toDeclStartReport source row col =
1478 case Code.whatIsNext source row col of
1479 Code.Close term bracket ->
1481 region = toRegion row col
1483 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1484 Code.toSnippet source region Nothing
1487 "I was not expecting to see a " ++ term ++ " here:"
1489 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1492 Code.Keyword keyword ->
1494 region = toKeywordRegion row col keyword
1496 Report.Report "RESERVED WORD" region [] $
1497 Code.toSnippet source region Nothing
1500 "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1505 "It is reserved for declaring imports at the top of your module. If you want\
1506 \ another import, try moving it up top with the other imports. If you want to\
1507 \ define a value or function, try changing the name to something else!"
1512 "It is reserved for writing `case` expressions. Try using a different name?"
1514 "If you are trying to write a `case` expression, it needs to be part of a\
1515 \ definition. So you could write something like this instead:"
1516 , D.indent 4 $ D.vcat $
1517 [ D.indent 0 $ D.fillSep ["getWidth","maybeWidth","="]
1518 , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1519 , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1520 , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1522 , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1523 , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1526 "This defines a `getWidth` function that you can use elsewhere in your program."
1532 "It is reserved for writing `if` expressions. Try using a different name?"
1534 "If you are trying to write an `if` expression, it needs to be part of a\
1535 \ definition. So you could write something like this instead:"
1536 , D.indent 4 $ D.vcat $
1540 ,D.cyan "if","name","==",D.dullyellow "\"Abraham Lincoln\""
1541 ,D.cyan "then",D.dullyellow "\"Greetings Mr. President.\""
1542 ,D.cyan "else",D.dullyellow "\"Hey!\""
1546 "This defines a `reviewPowerLevel` function that you can use elsewhere in your program."
1551 "It is a reserved word. Try changing the name to something else?"
1556 region = toRegion row col
1558 Report.Report "UNEXPECTED CAPITAL LETTER" region [] $
1559 Code.toSnippet source region Nothing
1562 "Declarations always start with a lower-case letter, so I am getting stuck here:"
1566 ["Try","a","name","like"
1567 ,D.green (D.fromChars (Char.toLower c : cs))
1571 "Here are a couple valid declarations for reference:"
1572 , D.indent 4 $ D.vcat $
1573 [ "greet : String -> String"
1575 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1577 , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1580 "Notice that they always start with a lower-case letter. Capitalization matters!"
1584 Code.Other (Just char) | elem char ['(', '{', '[', '+', '-', '*', '/', '^', '&', '|', '"', '\'', '!', '@', '#', '$', '%'] ->
1586 region = toRegion row col
1588 Report.Report "UNEXPECTED SYMBOL" region [] $
1589 Code.toSnippet source region Nothing
1592 "I am getting stuck because this line starts with the " ++ [char] ++ " symbol:"
1596 "When a line has no spaces at the beginning, I expect it to be a declaration like one of these:"
1597 , D.indent 4 $ D.vcat $
1598 [ "greet : String -> String"
1600 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1602 , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1605 "If this is not supposed to be a declaration, try adding some spaces before it?"
1611 region = toRegion row col
1613 Report.Report "WEIRD DECLARATION" region [] $
1614 Code.toSnippet source region Nothing
1617 "I am trying to parse a declaration, but I am getting stuck here:"
1621 "When a line has no spaces at the beginning, I expect it to be a declaration like one of these:"
1622 , D.indent 4 $ D.vcat $
1623 [ "greet : String -> String"
1625 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1627 , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1630 "Try to make your declaration look like one of those? Or if this is not\
1631 \ supposed to be a declaration, try adding some spaces before it?"
1639toPortReport :: Code.Source -> Port -> Row -> Col -> Report.Report
1640toPortReport source port_ startRow startCol =
1642 PortSpace space row col ->
1643 toSpaceReport source space row col
1646 case Code.whatIsNext source row col of
1647 Code.Keyword keyword ->
1649 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1650 region = toKeywordRegion row col keyword
1652 Report.Report "RESERVED WORD" region [] $
1653 Code.toSnippet source surroundings (Just region)
1656 "I cannot handle ports with names like this:"
1659 "You are trying to make a port named `" ++ keyword
1660 ++ "` but that is a reserved word. Try using some other name?"
1665 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1666 region = toRegion row col
1668 Report.Report "PORT PROBLEM" region [] $
1669 Code.toSnippet source surroundings (Just region)
1672 "I just saw the start of a `port` declaration, but then I got stuck here:"
1676 ["I","was","expecting","to","see","a","name","like"
1677 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1678 ,"Something","that","starts","with","a","lower-case","letter."
1684 PortColon row col ->
1686 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1687 region = toRegion row col
1689 Report.Report "PORT PROBLEM" region [] $
1690 Code.toSnippet source surroundings (Just region)
1693 "I just saw the start of a `port` declaration, but then I got stuck here:"
1697 "I was expecting to see a colon next. And then a type that tells me\
1698 \ what type of values are going to flow through."
1703 PortType tipe row col ->
1704 toTypeReport source TC_Port tipe row col
1706 PortIndentName row col ->
1708 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1709 region = toRegion row col
1711 Report.Report "UNFINISHED PORT" region [] $
1712 Code.toSnippet source surroundings (Just region)
1715 "I just saw the start of a `port` declaration, but then I got stuck here:"
1719 ["I","was","expecting","to","see","a","name","like"
1720 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1721 ,"Something","that","starts","with","a","lower-case","letter."
1727 PortIndentColon row col ->
1729 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1730 region = toRegion row col
1732 Report.Report "UNFINISHED PORT" region [] $
1733 Code.toSnippet source surroundings (Just region)
1736 "I just saw the start of a `port` declaration, but then I got stuck here:"
1740 "I was expecting to see a colon next. And then a type that tells me\
1741 \ what type of values are going to flow through."
1746 PortIndentType row col ->
1748 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1749 region = toRegion row col
1751 Report.Report "UNFINISHED PORT" region [] $
1752 Code.toSnippet source surroundings (Just region)
1755 "I just saw the start of a `port` declaration, but then I got stuck here:"
1759 "I was expecting to see a type next. Here are examples of outgoing and\
1760 \ incoming ports for reference:"
1761 , D.indent 4 $ D.vcat $
1762 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1763 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1766 "The first line defines a `send` port so you can send strings out to JavaScript.\
1767 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1768 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1769 \ get receive messages when new WebSocket messages come in or when an entry in\
1770 \ IndexedDB changes for some external reason."
1779 "Here are some example `port` declarations for reference:"
1780 , D.indent 4 $ D.vcat $
1781 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1782 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1785 "The first line defines a `send` port so you can send strings out to JavaScript.\
1786 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1787 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1788 \ get receive messages when new WebSocket messages come in or when the IndexedDB\
1789 \ is changed for some external reason."
1797toDeclTypeReport :: Code.Source -> DeclType -> Row -> Col -> Report.Report
1798toDeclTypeReport source declType startRow startCol =
1800 DT_Space space row col ->
1801 toSpaceReport source space row col
1805 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1806 region = toRegion row col
1808 Report.Report "EXPECTING TYPE NAME" region [] $
1809 Code.toSnippet source surroundings (Just region)
1812 "I think I am parsing a type declaration, but I got stuck here:"
1816 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1817 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1823 DT_Alias typeAlias row col ->
1824 toTypeAliasReport source typeAlias row col
1826 DT_Union customType row col ->
1827 toCustomTypeReport source customType row col
1829 DT_IndentName row col ->
1831 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1832 region = toRegion row col
1834 Report.Report "EXPECTING TYPE NAME" region [] $
1835 Code.toSnippet source surroundings (Just region)
1838 "I think I am parsing a type declaration, but I got stuck here:"
1842 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1843 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1850toTypeAliasReport :: Code.Source -> TypeAlias -> Row -> Col -> Report.Report
1851toTypeAliasReport source typeAlias startRow startCol =
1853 AliasSpace space row col ->
1854 toSpaceReport source space row col
1856 AliasName row col ->
1858 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1859 region = toRegion row col
1861 Report.Report "EXPECTING TYPE ALIAS NAME" region [] $
1862 Code.toSnippet source surroundings (Just region)
1865 "I am partway through parsing a type alias, but I got stuck here:"
1869 ["I","was","expecting","a","name","like",D.dullyellow "Person","or",D.dullyellow "Point"
1870 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1876 AliasEquals row col ->
1877 case Code.whatIsNext source row col of
1878 Code.Keyword keyword ->
1880 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1881 region = toKeywordRegion row col keyword
1883 Report.Report "RESERVED WORD" region [] $
1884 Code.toSnippet source surroundings (Just region)
1887 "I ran into a reserved word unexpectedly while parsing this type alias:"
1891 "It looks like you are trying use `" ++ keyword
1892 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1899 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1900 region = toRegion row col
1902 Report.Report "PROBLEM IN TYPE ALIAS" region [] $
1903 Code.toSnippet source surroundings (Just region)
1906 "I am partway through parsing a type alias, but I got stuck here:"
1910 "I was expecting to see a type variable or an equals sign next."
1915 AliasBody tipe row col ->
1916 toTypeReport source TC_TypeAlias tipe row col
1918 AliasIndentEquals row col ->
1920 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1921 region = toRegion row col
1923 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1924 Code.toSnippet source surroundings (Just region)
1927 "I am partway through parsing a type alias, but I got stuck here:"
1931 "I was expecting to see a type variable or an equals sign next."
1936 AliasIndentBody row col ->
1938 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1939 region = toRegion row col
1941 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1942 Code.toSnippet source surroundings (Just region)
1945 "I am partway through parsing a type alias, but I got stuck here:"
1949 ["I","was","expecting","to","see","a","type","next.","Something","as","simple"
1950 ,"as",D.dullyellow "Int","or",D.dullyellow "Float","would","work!"
1957typeAliasNote :: D.Doc
1961 "Here is an example of a valid `type alias` for reference:"
1963 [ D.indent 4 $ D.fillSep [D.cyan "type",D.cyan "alias","Person","="]
1964 , D.indent 6 $ D.vcat $
1972 "This would let us use `Person` as a shorthand for that record type. Using this\
1973 \ shorthand makes type annotations much easier to read, and makes changing code\
1974 \ easier if you decide later that there is more to a person than age and height!"
1978toCustomTypeReport :: Code.Source -> CustomType -> Row -> Col -> Report.Report
1979toCustomTypeReport source customType startRow startCol =
1981 CT_Space space row col ->
1982 toSpaceReport source space row col
1986 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1987 region = toRegion row col
1989 Report.Report "EXPECTING TYPE NAME" region [] $
1990 Code.toSnippet source surroundings (Just region)
1993 "I think I am parsing a type declaration, but I got stuck here:"
1997 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1998 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
2004 CT_Equals row col ->
2005 case Code.whatIsNext source row col of
2006 Code.Keyword keyword ->
2008 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2009 region = toKeywordRegion row col keyword
2011 Report.Report "RESERVED WORD" region [] $
2012 Code.toSnippet source surroundings (Just region)
2015 "I ran into a reserved word unexpectedly while parsing this custom type:"
2019 "It looks like you are trying use `" ++ keyword
2020 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
2027 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2028 region = toRegion row col
2030 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
2031 Code.toSnippet source surroundings (Just region)
2034 "I am partway through parsing a custom type, but I got stuck here:"
2038 "I was expecting to see a type variable or an equals sign next."
2045 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2046 region = toRegion row col
2048 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
2049 Code.toSnippet source surroundings (Just region)
2052 "I am partway through parsing a custom type, but I got stuck here:"
2056 "I was expecting to see a vertical bar like | next."
2061 CT_Variant row col ->
2063 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2064 region = toRegion row col
2066 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
2067 Code.toSnippet source surroundings (Just region)
2070 "I am partway through parsing a custom type, but I got stuck here:"
2074 ["I","was","expecting","to","see","a","variant","name","next."
2075 ,"Something","like",D.dullyellow "Success","or",D.dullyellow "Sandwich" <> "."
2076 ,"Any","name","that","starts","with","a","capital","letter","really!"
2082 CT_VariantArg tipe row col ->
2083 toTypeReport source TC_CustomType tipe row col
2085 CT_IndentEquals row col ->
2087 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2088 region = toRegion row col
2090 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2091 Code.toSnippet source surroundings (Just region)
2094 "I am partway through parsing a custom type, but I got stuck here:"
2098 "I was expecting to see a type variable or an equals sign next."
2103 CT_IndentBar row col ->
2105 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2106 region = toRegion row col
2108 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2109 Code.toSnippet source surroundings (Just region)
2112 "I am partway through parsing a custom type, but I got stuck here:"
2116 "I was expecting to see a vertical bar like | next."
2121 CT_IndentAfterBar row col ->
2123 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2124 region = toRegion row col
2126 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2127 Code.toSnippet source surroundings (Just region)
2130 "I am partway through parsing a custom type, but I got stuck here:"
2134 "I just saw a vertical bar, so I was expecting to see another variant defined next."
2139 CT_IndentAfterEquals row col ->
2141 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2142 region = toRegion row col
2144 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2145 Code.toSnippet source surroundings (Just region)
2148 "I am partway through parsing a custom type, but I got stuck here:"
2152 "I just saw an equals sign, so I was expecting to see the first variant defined next."
2158customTypeNote :: D.Doc
2162 "Here is an example of a valid `type` declaration for reference:"
2164 [ D.indent 4 $ D.fillSep [D.cyan "type","Status"]
2165 , D.indent 6 $ D.fillSep ["=","Failure"]
2166 , D.indent 6 $ D.fillSep ["|","Waiting"]
2167 , D.indent 6 $ D.fillSep ["|","Success","String"]
2170 "This defines a new `Status` type with three variants. This could be useful if\
2171 \ we are waiting for an HTTP request. Maybe we start with `Waiting` and then\
2172 \ switch to `Failure` or `Success \"message from server\"` depending on how\
2173 \ things go. Notice that the Success variant has some associated data, allowing\
2174 \ us to store a String if the request goes well!"
2182toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
2183toDeclDefReport source name declDef startRow startCol =
2185 DeclDefSpace space row col ->
2186 toSpaceReport source space row col
2188 DeclDefEquals row col ->
2189 case Code.whatIsNext source row col of
2190 Code.Keyword keyword ->
2192 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2193 region = toKeywordRegion row col keyword
2195 Report.Report "RESERVED WORD" region [] $
2196 Code.toSnippet source surroundings (Just region)
2200 ,"`" <> D.cyan (D.fromChars keyword) <> "`"
2201 ,"is","reserved","in","Elm,","so","it","cannot"
2202 ,"be","used","as","an","argument","here:"
2207 "Try renaming it to something else."
2211 ["This","keyword","is","reserved","for","pattern","matches","like"
2212 ,"((x,y)",D.cyan "as","point)","where","you","want","to","name","a","tuple","and"
2213 ,"the","values","it","contains."
2218 "The `" ++ keyword ++ "` keyword has a special meaning in Elm, so it can only be used in certain situations."
2222 Code.Operator "->" ->
2224 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2225 region = toWiderRegion row col 2
2227 Report.Report "MISSING COLON?" region [] $
2228 Code.toSnippet source surroundings (Just region)
2231 "I was not expecting to see an arrow here:"
2235 ["This","usually","means","a",D.green ":","is","missing","a","bit","earlier","in"
2236 ,"a","type","annotation.","It","could","be","something","else","though,","so"
2237 ,"here","is","a","valid","definition","for","reference:"
2239 , D.indent 4 $ D.vcat $
2240 [ "greet : String -> String"
2242 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2245 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
2251 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2252 region = toKeywordRegion row col op
2254 Report.Report "UNEXPECTED SYMBOL" region [] $
2255 Code.toSnippet source surroundings (Just region)
2258 "I was not expecting to see this symbol here:"
2262 "I am not sure what is going wrong exactly, so here is a valid\
2263 \ definition (with an optional type annotation) for reference:"
2264 , D.indent 4 $ D.vcat $
2265 [ "greet : String -> String"
2267 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2270 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
2276 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2277 region = toRegion row col
2279 Report.Report "PROBLEM IN DEFINITION" region [] $
2280 Code.toSnippet source surroundings (Just region)
2283 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2287 "I am not sure what is going wrong exactly, so here is a valid\
2288 \ definition (with an optional type annotation) for reference:"
2289 , D.indent 4 $ D.vcat $
2290 [ "greet : String -> String"
2292 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2295 "Try to use that format!"
2299 DeclDefType tipe row col ->
2300 toTypeReport source (TC_Annotation name) tipe row col
2302 DeclDefArg pattern row col ->
2303 toPatternReport source PArg pattern row col
2305 DeclDefBody expr row col ->
2306 toExprReport source (InDef name startRow startCol) expr row col
2308 DeclDefNameRepeat row col ->
2310 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2311 region = toRegion row col
2313 Report.Report "EXPECTING DEFINITION" region [] $
2314 Code.toSnippet source surroundings (Just region)
2317 "I just saw the type annotation for `" ++ Name.toChars name
2318 ++ "` so I was expecting to see its definition here:"
2322 "Type annotations always appear directly above the relevant\
2323 \ definition, without anything else in between. (Not even doc comments!)"
2328 DeclDefNameMatch defName row col ->
2330 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2331 region = toRegion row col
2333 Report.Report "NAME MISMATCH" region [] $
2334 Code.toSnippet source surroundings (Just region)
2337 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
2341 "These names do not match! Is there a typo?"
2342 , D.indent 4 $ D.fillSep $
2343 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
2347 DeclDefIndentType row col ->
2349 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2350 region = toRegion row col
2352 Report.Report "UNFINISHED DEFINITION" region [] $
2353 Code.toSnippet source surroundings (Just region)
2356 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
2360 "I just saw a colon, so I am expecting to see a type next."
2365 DeclDefIndentEquals row col ->
2367 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2368 region = toRegion row col
2370 Report.Report "UNFINISHED DEFINITION" region [] $
2371 Code.toSnippet source surroundings (Just region)
2374 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2378 "I was expecting to see an argument or an equals sign next."
2383 DeclDefIndentBody row col ->
2385 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2386 region = toRegion row col
2388 Report.Report "UNFINISHED DEFINITION" region [] $
2389 Code.toSnippet source surroundings (Just region)
2392 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2396 "I was expecting to see an expression next. What is it equal to?"
2406 "Here is a valid definition (with a type annotation) for reference:"
2407 , D.indent 4 $ D.vcat $
2408 [ "greet : String -> String"
2410 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2413 "The top line (called a \"type annotation\") is optional. You can leave it off\
2414 \ if you want. As you get more comfortable with Elm and as your project grows,\
2415 \ it becomes more and more valuable to add them though! They work great as\
2416 \ compiler-verified documentation, and they often improve error messages!"
2425 = InNode Node Row Col Context
2426 | InDef Name.Name Row Col
2427 | InDestruct Row Col
2443getDefName :: Context -> Maybe Name.Name
2446 InDestruct _ _ -> Nothing
2447 InDef name _ _ -> Just name
2448 InNode _ _ _ c -> getDefName c
2451isWithin :: Node -> Context -> Bool
2452isWithin desiredNode context =
2454 InDestruct _ _ -> False
2455 InDef _ _ _ -> False
2456 InNode actualNode _ _ _ -> desiredNode == actualNode
2463toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
2464toExprReport source context expr startRow startCol =
2467 toLetReport source context let_ row col
2469 Case case_ row col ->
2470 toCaseReport source context case_ row col
2473 toIfReport source context if_ row col
2475 List list row col ->
2476 toListReport source context list row col
2478 Record record row col ->
2479 toRecordReport source context record row col
2481 Tuple tuple row col ->
2482 toTupleReport source context tuple row col
2484 Func func row col ->
2485 toFuncReport source context func row col
2488 let region = toRegion row col in
2489 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2490 Code.toSnippet source region Nothing
2493 "I was expecting to see a record accessor here:"
2496 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2497 ,"that","accesses","a","value","from","a","record."
2502 let region = toRegion row col in
2503 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2504 Code.toSnippet source region Nothing
2507 "I am trying to parse a record accessor here:"
2512 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2513 ,"that","accesses","a","value","from","a","record."
2517 "Record field names must start with a lower case letter!"
2521 OperatorRight op row col ->
2523 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2524 region = toRegion row col
2525 isMath = elem op ["-","+","*","/","^"]
2527 Report.Report "MISSING EXPRESSION" region [] $
2528 Code.toSnippet source surroundings (Just region)
2531 "I just saw a " ++ Name.toChars op ++ " "
2532 ++ (if isMath then "sign" else "operator")
2533 ++ ", so I am getting stuck here:"
2537 ["I","was","expecting","to","see","an","expression","next."
2538 ,"Something","like",D.dullyellow "42","or",D.dullyellow "1000"
2539 ,"that","makes","sense","with","a",D.fromName op,"sign."
2541 else if op == "&&" || op == "||" then
2543 ["I","was","expecting","to","see","an","expression","next."
2544 ,"Something","like",D.dullyellow "True","or",D.dullyellow "False"
2545 ,"that","makes","sense","with","boolean","logic."
2547 else if op == "|>" then
2549 "I was expecting to see a function next."
2550 else if op == "<|" then
2552 "I was expecting to see an argument next."
2555 "I was expecting to see an expression next."
2558 OperatorReserved operator row col ->
2559 toOperatorReport source context operator row col
2563 (contextRow, contextCol, aThing) =
2565 InDestruct r c -> (r, c, "a definition")
2566 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
2567 InNode NRecord r c _ -> (r, c, "a record")
2568 InNode NParens r c _ -> (r, c, "some parentheses")
2569 InNode NList r c _ -> (r, c, "a list")
2570 InNode NFunc r c _ -> (r, c, "an anonymous function")
2571 InNode NCond r c _ -> (r, c, "an `if` expression")
2572 InNode NThen r c _ -> (r, c, "an `if` expression")
2573 InNode NElse r c _ -> (r, c, "an `if` expression")
2574 InNode NCase r c _ -> (r, c, "a `case` expression")
2575 InNode NBranch r c _ -> (r, c, "a `case` expression")
2577 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
2578 region = toRegion row col
2580 Report.Report "MISSING EXPRESSION" region [] $
2581 Code.toSnippet source surroundings (Just region)
2584 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
2588 ["I","was","expecting","to","see","an","expression","like"
2589 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2590 ,"Once","there","is","something","there,","I","can","probably"
2591 ,"give","a","more","specific","hint!"
2594 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
2595 \ Or if I run into operators in unexpected spots. Point is, there are a\
2596 \ couple ways I can get confused and give sort of weird advice!"
2600 Char char row col ->
2601 toCharReport source char row col
2603 String string row col ->
2604 toStringReport source string row col
2606 Number number row col ->
2607 toNumberReport source number row col
2609 Space space row col ->
2610 toSpaceReport source space row col
2612 EndlessShader row col ->
2614 region = toWiderRegion row col 6
2616 Report.Report "ENDLESS SHADER" region [] $
2617 Code.toSnippet source region Nothing
2619 D.reflow "I cannot find the end of this shader:"
2621 D.reflow "Add a |] somewhere after this to end the shader."
2624 ShaderProblem problem row col ->
2626 region = toRegion row col
2628 Report.Report "SHADER PROBLEM" region [] $
2629 Code.toSnippet source region Nothing
2632 "I ran into a problem while parsing this GLSL block."
2636 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
2637 , D.indent 4 $ D.vcat $
2638 map D.fromChars (filter (/="") (lines problem))
2642 IndentOperatorRight op row col ->
2644 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2645 region = toRegion row col
2647 Report.Report "MISSING EXPRESSION" region [] $
2648 Code.toSnippet source surroundings (Just region)
2651 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
2656 ["You","can","just","put","anything","for","now,","like"
2657 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2658 ,"Once","there","is","something","there,","I","can","probably"
2659 ,"give","a","more","specific","hint!"
2663 "I may be getting confused by your indentation? The easiest way to make sure\
2664 \ this is not an indentation problem is to put the expression on the right of\
2665 \ the " ++ Name.toChars op ++ " operator on the same line."
2674toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
2675toCharReport source char row col =
2679 region = toRegion row col
2681 Report.Report "MISSING SINGLE QUOTE" region [] $
2682 Code.toSnippet source region Nothing
2685 "I thought I was parsing a character, but I got to the end of\
2686 \ the line without seeing the closing single quote:"
2689 "Add a closing single quote here!"
2692 CharEscape escape ->
2693 toEscapeReport source escape row col
2695 CharNotString width ->
2697 region = toWiderRegion row col width
2699 Report.Report "NEEDS DOUBLE QUOTES" region [] $
2700 Code.toSnippet source region Nothing
2702 "The following string uses single quotes:"
2705 [ "Please switch to double quotes instead:"
2707 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
2709 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
2710 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
2711 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
2712 \ individual characters."
2721toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
2722toStringReport source string row col =
2724 StringEndless_Single ->
2726 region = toRegion row col
2728 Report.Report "ENDLESS STRING" region [] $
2729 Code.toSnippet source region Nothing
2732 "I got to the end of the line without seeing the closing double quote:"
2736 ["Strings","look","like",D.green "\"this\"","with","double"
2737 ,"quotes","on","each","end.","Is","the","closing","double"
2738 ,"quote","missing","in","your","code?"
2741 "For a string that spans multiple lines, you can use the multi-line string\
2742 \ syntax like this:"
2743 , D.dullyellow $ D.indent 4 $ D.vcat $
2745 , "# Multi-line Strings"
2747 , "- start with triple double quotes"
2748 , "- write whatever you want"
2749 , "- no need to escape newlines or double quotes"
2750 , "- end with triple double quotes"
2756 StringEndless_Multi ->
2758 region = toWiderRegion row col 3
2760 Report.Report "ENDLESS STRING" region [] $
2761 Code.toSnippet source region Nothing
2764 "I cannot find the end of this multi-line string:"
2767 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
2769 "Here is a valid multi-line string for reference:"
2770 , D.dullyellow $ D.indent 4 $ D.vcat $
2772 , "# Multi-line Strings"
2774 , "- start with triple double quotes"
2775 , "- write whatever you want"
2776 , "- no need to escape newlines or double quotes"
2777 , "- end with triple double quotes"
2783 StringEscape escape ->
2784 toEscapeReport source escape row col
2791toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
2792toEscapeReport source escape row col =
2796 region = toWiderRegion row col 2
2798 Report.Report "UNKNOWN ESCAPE" region [] $
2799 Code.toSnippet source region Nothing
2802 "Backslashes always start escaped characters, but I do not recognize this one:"
2806 "Valid escape characters include:"
2807 , D.dullyellow $ D.indent 4 $ D.vcat $
2817 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
2819 "The last style lets encode ANY character by its Unicode code\
2820 \ point. That means \\u{0009} and \\t are the same. You can use\
2821 \ that style for anything not covered by the other six escapes!"
2825 BadUnicodeFormat width ->
2827 region = toWiderRegion row col width
2829 Report.Report "BAD UNICODE ESCAPE" region [] $
2830 Code.toSnippet source region Nothing
2833 "I ran into an invalid Unicode escape:"
2837 "Here are some examples of valid Unicode escapes:"
2838 , D.dullyellow $ D.indent 4 $ D.vcat $
2845 "Notice that the code point is always surrounded by curly braces.\
2846 \ Maybe you are missing the opening or closing curly brace?"
2849 BadUnicodeCode width ->
2851 region = toWiderRegion row col width
2853 Report.Report "BAD UNICODE ESCAPE" region [] $
2854 Code.toSnippet source region Nothing
2857 "This is not a valid code point:"
2860 "The valid code points are between 0 and 10FFFF inclusive."
2863 BadUnicodeLength width numDigits badCode ->
2865 region = toWiderRegion row col width
2867 Report.Report "BAD UNICODE ESCAPE" region [] $
2868 Code.toSnippet source region Nothing $
2869 if numDigits < 4 then
2872 "Every code point needs at least four digits:"
2875 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
2876 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
2878 D.fillSep ["Try",D.green suggestion,"instead?"]
2884 "This code point has too many digits:"
2887 ["Valid","code","points","are","between"
2888 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
2889 ,"so","try","trimming","any","leading","zeros","until"
2890 ,"you","have","between","four","and","six","digits."
2899toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
2900toNumberReport source number row col =
2902 region = toRegion row col
2906 Report.Report "WEIRD NUMBER" region [] $
2907 Code.toSnippet source region Nothing
2910 "I thought I was reading a number, but I ran into some weird stuff here:"
2914 "I recognize numbers in the following formats:"
2915 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
2917 "So is there a way to write it like one of those?"
2922 Report.Report "WEIRD NUMBER" region [] $
2923 Code.toSnippet source region Nothing
2926 "Numbers cannot end with a dot like this:"
2929 ["Switching","to",D.green (D.fromChars (show int))
2930 ,"or",D.green (D.fromChars (show int ++ ".0"))
2931 ,"will","work","though!"
2936 Report.Report "WEIRD HEXIDECIMAL" region [] $
2937 Code.toSnippet source region Nothing
2940 "I thought I was reading a hexidecimal number until I got here:"
2944 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
2945 \ only recognize things like this:"
2946 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
2950 NumberNoLeadingZero ->
2951 Report.Report "LEADING ZEROS" region [] $
2952 Code.toSnippet source region Nothing
2955 "I do not accept numbers with leading zeros:"
2959 "Just delete the leading zeros and it should work!"
2961 "Some languages let you to specify octal numbers by adding a leading zero.\
2962 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
2963 \ that, but others probably want it to equal 111. Either path is going to\
2964 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
2974toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
2975toOperatorReport source context operator row col =
2979 region = toRegion row col
2981 Report.Report "UNEXPECTED SYMBOL" region [] $
2982 Code.toSnippet source region Nothing
2984 "I was not expecting this dot:"
2987 "Dots are for record access and decimal points, so\
2988 \ they cannot float around on their own. Maybe\
2989 \ there is some extra whitespace?"
2994 region = toRegion row col
2996 Report.Report "UNEXPECTED SYMBOL" region [] $
2997 Code.toSnippet source region Nothing
3000 "I was not expecting this vertical bar:"
3003 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
3008 region = toWiderRegion row col 2
3010 Report.Report "UNEXPECTED ARROW" region [] $
3011 Code.toSnippet source region Nothing $
3012 if isWithin NCase context then
3015 "I am parsing a `case` expression right now, but this arrow is confusing me:"
3018 [ D.reflow "Maybe the `of` keyword is missing on a previous line?"
3023 else if isWithin NBranch context then
3026 "I am parsing a `case` expression right now, but this arrow is confusing me:"
3030 "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?"
3031 , noteForCaseIndentError
3038 "I was partway through parsing an expression when I got stuck on this arrow:"
3041 [ "Arrows should only appear in `case` expressions and anonymous functions.\n\
3042 \Maybe it was supposed to be a > sign instead?"
3044 "The syntax for anonymous functions is (\\x -> x + 1) so the arguments all appear\
3045 \ after the backslash and before the arrow. Maybe a backslash is missing earlier?"
3051 region = toRegion row col
3053 Report.Report "UNEXPECTED EQUALS" region [] $
3054 Code.toSnippet source region Nothing
3057 "I was not expecting to see this equals sign:"
3061 D.reflow "Maybe you want == instead? To check if two values are equal?"
3064 if isWithin NRecord context then
3065 "Records look like { x = 3, y = 4 } with the equals sign right\
3066 \ after the field name. So maybe you forgot a comma?"
3068 case getDefName context of
3070 "I may be getting confused by your indentation. I need all definitions to be indented\
3071 \ exactly the same amount, so if this is meant to be a new definition, it may have too\
3072 \ many spaces in front of it."
3075 "I may be getting confused by your indentation. I think I am still parsing the `"
3076 ++ Name.toChars name ++ "` definition. Is this supposed to be part of a definition\
3077 \ after that? If so, the problem may be a bit before the equals sign. I need all\
3078 \ definitions to be indented exactly the same amount, so the problem may be that\
3079 \ this new definition has too many spaces in front of it."
3085 region = toRegion row col
3087 Report.Report "UNEXPECTED SYMBOL" region [] $
3088 Code.toSnippet source region Nothing $
3091 "I was not expecting to run into the \"has type\" symbol here:"
3093 case getDefName context of
3096 ["Maybe","you","want",D.green "::","instead?"
3097 ,"To","put","something","on","the","front","of","a","list?"
3104 ["Maybe","you","want",D.green "::","instead?"
3105 ,"To","put","something","on","the","front","of","a","list?"
3108 "The single colon is reserved for type annotations and record types, but I think\
3109 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
3112 "I may be getting confused by your indentation. Is this supposed to be part of\
3113 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
3114 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
3115 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
3116 \ this new definition is indented a bit too much."
3125toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
3126toLetReport source context let_ startRow startCol =
3128 LetSpace space row col ->
3129 toSpaceReport source space row col
3133 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3134 region = toRegion row col
3136 Report.Report "LET PROBLEM" region [] $
3137 Code.toSnippet source surroundings (Just region)
3140 "I was partway through parsing a `let` expression, but I got stuck here:"
3144 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
3145 ,"keyword","next.","Is","there","a","typo?"
3148 "This can also happen if you are trying to define another value within the `let` but\
3149 \ it is not indented enough. Make sure each definition has exactly the same amount of\
3150 \ spaces before it. They should line up exactly!"
3154 LetDefAlignment _ row col ->
3156 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3157 region = toRegion row col
3159 Report.Report "LET PROBLEM" region [] $
3160 Code.toSnippet source surroundings (Just region)
3163 "I was partway through parsing a `let` expression, but I got stuck here:"
3167 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
3168 ,"keyword","next.","Is","there","a","typo?"
3171 "This can also happen if you are trying to define another value within the `let` but\
3172 \ it is not indented enough. Make sure each definition has exactly the same amount of\
3173 \ spaces before it. They should line up exactly!"
3177 LetDefName row col ->
3178 case Code.whatIsNext source row col of
3179 Code.Keyword keyword ->
3181 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3182 region = toKeywordRegion row col keyword
3184 Report.Report "RESERVED WORD" region [] $
3185 Code.toSnippet source surroundings (Just region)
3188 "I was partway through parsing a `let` expression, but I got stuck here:"
3191 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
3192 \ it is a reserved word! Try using a different name instead."
3196 toUnfinishLetReport source row col startRow startCol $
3198 "I was expecting the name of a definition next."
3200 LetDef name def row col ->
3201 toLetDefReport source name def row col
3203 LetDestruct destruct row col ->
3204 toLetDestructReport source destruct row col
3206 LetBody expr row col ->
3207 toExprReport source context expr row col
3209 LetIndentDef row col ->
3210 toUnfinishLetReport source row col startRow startCol $
3212 "I was expecting a value to be defined here."
3214 LetIndentIn row col ->
3215 toUnfinishLetReport source row col startRow startCol $
3217 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
3218 ,"Or","maybe","more","of","that","expression?"
3221 LetIndentBody row col ->
3222 toUnfinishLetReport source row col startRow startCol $
3224 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
3227toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3228toUnfinishLetReport source row col startRow startCol message =
3230 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3231 region = toRegion row col
3233 Report.Report "UNFINISHED LET" region [] $
3234 Code.toSnippet source surroundings (Just region)
3237 "I was partway through parsing a `let` expression, but I got stuck here:"
3242 "Here is an example with a valid `let` expression for reference:"
3243 , D.indent 4 $ D.vcat $
3244 [ D.indent 0 $ D.fillSep ["viewPerson","person","="]
3245 , D.indent 2 $ D.fillSep [D.cyan "let"]
3246 , D.indent 4 $ D.fillSep ["fullName","="]
3247 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
3248 , D.indent 2 $ D.fillSep [D.cyan "in"]
3249 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
3252 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
3253 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
3254 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
3255 \ indented a bit more than that. That is important!"
3260toLetDefReport :: Code.Source -> Name.Name -> Def -> Row -> Col -> Report.Report
3261toLetDefReport source name def startRow startCol =
3263 DefSpace space row col ->
3264 toSpaceReport source space row col
3266 DefType tipe row col ->
3267 toTypeReport source (TC_Annotation name) tipe row col
3269 DefNameRepeat row col ->
3271 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3272 region = toRegion row col
3274 Report.Report "EXPECTING DEFINITION" region [] $
3275 Code.toSnippet source surroundings (Just region)
3278 "I just saw the type annotation for `" ++ Name.toChars name
3279 ++ "` so I was expecting to see its definition here:"
3283 "Type annotations always appear directly above the relevant\
3284 \ definition, without anything else in between."
3289 DefNameMatch defName row col ->
3291 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3292 region = toRegion row col
3294 Report.Report "NAME MISMATCH" region [] $
3295 Code.toSnippet source surroundings (Just region)
3298 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
3302 "These names do not match! Is there a typo?"
3303 , D.indent 4 $ D.fillSep $
3304 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
3308 DefArg pattern row col ->
3309 toPatternReport source PArg pattern row col
3311 DefEquals row col ->
3312 case Code.whatIsNext source row col of
3313 Code.Keyword keyword ->
3315 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3316 region = toKeywordRegion row col keyword
3318 Report.Report "RESERVED WORD" region [] $
3319 Code.toSnippet source surroundings (Just region)
3323 ,"`" <> D.cyan (D.fromChars keyword) <> "`"
3324 ,"is","reserved","in","Elm,","so","it","cannot"
3325 ,"be","used","as","an","argument","here:"
3330 "Try renaming it to something else."
3334 ["This","keyword","is","reserved","for","pattern","matches","like"
3335 ,"((x,y)",D.cyan "as","point)","where","you","want","to","name","a","tuple","and"
3336 ,"the","values","it","contains."
3341 "The `" ++ keyword ++ "` keyword has a special meaning in Elm, so it can only be used in certain situations."
3345 Code.Operator "->" ->
3347 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3348 region = toWiderRegion row col 2
3350 Report.Report "MISSING COLON?" region [] $
3351 Code.toSnippet source surroundings (Just region)
3354 "I was not expecting to see an arrow here:"
3358 ["This","usually","means","a",D.green ":","is","missing","a","bit","earlier","in"
3359 ,"a","type","annotation.","It","could","be","something","else","though,","so"
3360 ,"here","is","a","valid","definition","for","reference:"
3362 , D.indent 4 $ D.vcat $
3363 [ "greet : String -> String"
3365 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3368 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
3374 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3375 region = toKeywordRegion row col op
3377 Report.Report "UNEXPECTED SYMBOL" region [] $
3378 Code.toSnippet source surroundings (Just region)
3381 "I was not expecting to see this symbol here:"
3385 "I am not sure what is going wrong exactly, so here is a valid\
3386 \ definition (with an optional type annotation) for reference:"
3387 , D.indent 4 $ D.vcat $
3388 [ "greet : String -> String"
3390 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3393 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
3399 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3400 region = toRegion row col
3402 Report.Report "PROBLEM IN DEFINITION" region [] $
3403 Code.toSnippet source surroundings (Just region)
3406 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3410 "I am not sure what is going wrong exactly, so here is a valid\
3411 \ definition (with an optional type annotation) for reference:"
3412 , D.indent 4 $ D.vcat $
3413 [ "greet : String -> String"
3415 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3418 "Try to use that format!"
3422 DefBody expr row col ->
3423 toExprReport source (InDef name startRow startCol) expr row col
3425 DefIndentEquals row col ->
3427 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3428 region = toRegion row col
3430 Report.Report "UNFINISHED DEFINITION" region [] $
3431 Code.toSnippet source surroundings (Just region)
3434 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3438 "I was expecting to see an argument or an equals sign next."
3443 DefIndentType row col ->
3445 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3446 region = toRegion row col
3448 Report.Report "UNFINISHED DEFINITION" region [] $
3449 Code.toSnippet source surroundings (Just region)
3452 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
3456 "I just saw a colon, so I am expecting to see a type next."
3461 DefIndentBody row col ->
3463 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3464 region = toRegion row col
3466 Report.Report "UNFINISHED DEFINITION" region [] $
3467 Code.toSnippet source surroundings (Just region)
3470 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3474 "I was expecting to see an expression next. What is it equal to?"
3479 DefAlignment indent row col ->
3481 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3482 region = toRegion row col
3483 offset = indent - col
3485 Report.Report "PROBLEM IN DEFINITION" region [] $
3486 Code.toSnippet source surroundings (Just region)
3489 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3492 "I just saw a type annotation indented " ++ show indent ++ " spaces, so I was\
3493 \ expecting to see the corresponding definition next with the exact same amount\
3494 \ of indentation. It looks like this line needs "
3495 ++ show offset ++ " more " ++ (if offset == 1 then "space" else "spaces") ++ "?"
3504 "Here is a valid definition (with a type annotation) for reference:"
3505 , D.indent 4 $ D.vcat $
3506 [ "greet : String -> String"
3508 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3511 "The top line (called a \"type annotation\") is optional. You can leave it off\
3512 \ if you want. As you get more comfortable with Elm and as your project grows,\
3513 \ it becomes more and more valuable to add them though! They work great as\
3514 \ compiler-verified documentation, and they often improve error messages!"
3518toLetDestructReport :: Code.Source -> Destruct -> Row -> Col -> Report.Report
3519toLetDestructReport source destruct startRow startCol =
3521 DestructSpace space row col ->
3522 toSpaceReport source space row col
3524 DestructPattern pattern row col ->
3525 toPatternReport source PLet pattern row col
3527 DestructEquals row col ->
3529 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3530 region = toRegion row col
3532 Report.Report "PROBLEM IN DEFINITION" region [] $
3533 Code.toSnippet source surroundings (Just region)
3536 "I got stuck trying to parse this definition:"
3538 case Code.whatIsNext source row col of
3539 Code.Operator ":" ->
3542 "I was expecting to see an equals sign next, followed by an expression\
3543 \ telling me what to compute."
3545 "It looks like you may be trying to write a type annotation? It is not\
3546 \ possible to add type annotations on destructuring definitions like this.\
3547 \ You can assign a name to the overall structure, put a type annotation on\
3548 \ that, and then destructure separately though."
3553 "I was expecting to see an equals sign next, followed by an expression\
3554 \ telling me what to compute."
3557 DestructBody expr row col ->
3558 toExprReport source (InDestruct startRow startCol) expr row col
3560 DestructIndentEquals row col ->
3562 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3563 region = toRegion row col
3565 Report.Report "UNFINISHED DEFINITION" region [] $
3566 Code.toSnippet source surroundings (Just region)
3569 "I got stuck trying to parse this definition:"
3572 "I was expecting to see an equals sign next, followed by an expression\
3573 \ telling me what to compute."
3576 DestructIndentBody row col ->
3578 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3579 region = toRegion row col
3581 Report.Report "UNFINISHED DEFINITION" region [] $
3582 Code.toSnippet source surroundings (Just region)
3585 "I got stuck while parsing this definition:"
3588 "I was expecting to see an expression next. What is it equal to?"
3596toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
3597toCaseReport source context case_ startRow startCol =
3599 CaseSpace space row col ->
3600 toSpaceReport source space row col
3603 toUnfinishCaseReport source row col startRow startCol $
3604 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3606 CasePattern pattern row col ->
3607 toPatternReport source PCase pattern row col
3609 CaseArrow row col ->
3610 case Code.whatIsNext source row col of
3611 Code.Keyword keyword ->
3613 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3614 region = toKeywordRegion row col keyword
3616 Report.Report "RESERVED WORD" region [] $
3617 Code.toSnippet source surroundings (Just region)
3620 "I am partway through parsing a `case` expression, but I got stuck here:"
3623 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
3624 \ patterns, but it is a reserved word. Try using a different name?"
3627 Code.Operator ":" ->
3629 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3630 region = toRegion row col
3632 Report.Report "UNEXPECTED OPERATOR" region [] $
3633 Code.toSnippet source surroundings (Just region)
3636 "I am partway through parsing a `case` expression, but I got stuck here:"
3639 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
3640 ,"For","pattern","matching","on","lists?"
3644 Code.Operator "=" ->
3646 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3647 region = toRegion row col
3649 Report.Report "UNEXPECTED OPERATOR" region [] $
3650 Code.toSnippet source surroundings (Just region)
3653 "I am partway through parsing a `case` expression, but I got stuck here:"
3656 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
3662 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3663 region = toRegion row col
3665 Report.Report "MISSING ARROW" region [] $
3666 Code.toSnippet source surroundings (Just region)
3669 "I am partway through parsing a `case` expression, but I got stuck here:"
3672 [ D.reflow "I was expecting to see an arrow next."
3673 , noteForCaseIndentError
3677 CaseExpr expr row col ->
3678 toExprReport source (InNode NCase startRow startCol context) expr row col
3680 CaseBranch expr row col ->
3681 toExprReport source (InNode NBranch startRow startCol context) expr row col
3683 CaseIndentOf row col ->
3684 toUnfinishCaseReport source row col startRow startCol $
3685 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3687 CaseIndentExpr row col ->
3688 toUnfinishCaseReport source row col startRow startCol $
3689 D.reflow "I was expecting to see a expression next."
3691 CaseIndentPattern row col ->
3692 toUnfinishCaseReport source row col startRow startCol $
3693 D.reflow "I was expecting to see a pattern next."
3695 CaseIndentArrow row col ->
3696 toUnfinishCaseReport source row col startRow startCol $
3698 ["I","just","saw","a","pattern,","so","I","was","expecting"
3699 ,"to","see","a",D.dullyellow "->","next."
3702 CaseIndentBranch row col ->
3703 toUnfinishCaseReport source row col startRow startCol $
3705 "I was expecting to see an expression next. What should I do when\
3706 \ I run into this particular pattern?"
3708 CasePatternAlignment indent row col ->
3709 toUnfinishCaseReport source row col startRow startCol $
3711 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
3714toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3715toUnfinishCaseReport source row col startRow startCol message =
3717 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3718 region = toRegion row col
3720 Report.Report "UNFINISHED CASE" region [] $
3721 Code.toSnippet source surroundings (Just region)
3724 "I was partway through parsing a `case` expression, but I got stuck here:"
3733noteForCaseError :: D.Doc
3737 "Here is an example of a valid `case` expression for reference."
3739 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3740 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3741 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3743 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3744 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3747 "Notice the indentation. Each pattern is aligned, and each branch is indented\
3748 \ a bit more than the corresponding pattern. That is important!"
3752noteForCaseIndentError :: D.Doc
3753noteForCaseIndentError =
3756 "Sometimes I get confused by indentation, so try to make your `case` look\
3757 \ something like this:"
3759 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3760 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3761 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3763 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3764 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3767 "Notice the indentation! Patterns are aligned with each other. Same indentation.\
3768 \ The expressions after each arrow are all indented a bit more than the patterns.\
3769 \ That is important!"
3777toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
3778toIfReport source context if_ startRow startCol =
3780 IfSpace space row col ->
3781 toSpaceReport source space row col
3785 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3786 region = toRegion row col
3788 Report.Report "UNFINISHED IF" region [] $
3789 Code.toSnippet source surroundings (Just region)
3792 "I was expecting to see more of this `if` expression, but I got stuck here:"
3795 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3801 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3802 region = toRegion row col
3804 Report.Report "UNFINISHED IF" region [] $
3805 Code.toSnippet source surroundings (Just region)
3808 "I was expecting to see more of this `if` expression, but I got stuck here:"
3811 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
3815 IfElseBranchStart row col ->
3817 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3818 region = toRegion row col
3820 Report.Report "UNFINISHED IF" region [] $
3821 Code.toSnippet source surroundings (Just region)
3824 "I just saw the start of an `else` branch, but then I got stuck here:"
3827 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3830 IfCondition expr row col ->
3831 toExprReport source (InNode NCond startRow startCol context) expr row col
3833 IfThenBranch expr row col ->
3834 toExprReport source (InNode NThen startRow startCol context) expr row col
3836 IfElseBranch expr row col ->
3837 toExprReport source (InNode NElse startRow startCol context) expr row col
3839 IfIndentCondition row col ->
3841 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3842 region = toRegion row col
3844 Report.Report "UNFINISHED IF" region [] $
3845 Code.toSnippet source surroundings (Just region)
3848 "I was expecting to see more of this `if` expression, but I got stuck here:"
3852 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
3853 ,"that","evaluates","to","True","or","False."
3856 "I can be confused by indentation. Maybe something is not indented enough?"
3860 IfIndentThen row col ->
3862 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3863 region = toRegion row col
3865 Report.Report "UNFINISHED IF" region [] $
3866 Code.toSnippet source surroundings (Just region)
3869 "I was expecting to see more of this `if` expression, but I got stuck here:"
3873 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3876 "I can be confused by indentation. Maybe something is not indented enough?"
3880 IfIndentThenBranch row col ->
3882 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3883 region = toRegion row col
3885 Report.Report "UNFINISHED IF" region [] $
3886 Code.toSnippet source surroundings (Just region)
3889 "I got stuck after the start of this `then` branch:"
3893 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3895 "I can be confused by indentation, so if the `then` branch is already\
3896 \ present, it may not be indented enough for me to recognize it."
3900 IfIndentElseBranch row col ->
3902 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3903 region = toRegion row col
3905 Report.Report "UNFINISHED IF" region [] $
3906 Code.toSnippet source surroundings (Just region)
3909 "I got stuck after the start of this `else` branch:"
3913 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3915 "I can be confused by indentation, so if the `else` branch is already\
3916 \ present, it may not be indented enough for me to recognize it."
3920 IfIndentElse row col ->
3921 case Code.nextLineStartsWithKeyword "else" source row of
3922 Just (elseRow, elseCol) ->
3924 surroundings = A.Region (A.Position startRow startCol) (A.Position elseRow elseCol)
3925 region = toWiderRegion elseRow elseCol 4
3927 Report.Report "WEIRD ELSE BRANCH" region [] $
3928 Code.toSnippet source surroundings (Just region)
3931 "I was partway through an `if` expression when I got stuck here:"
3934 ["I","think","this",D.cyan "else","keyword","needs","to","be","indented","more."
3935 ,"Try","adding","some","spaces","before","it."
3941 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3942 region = toRegion row col
3944 Report.Report "UNFINISHED IF" region [] $
3945 Code.toSnippet source surroundings (Just region)
3948 "I was expecting to see an `else` branch after this:"
3952 ["I","know","what","to","do","when","the","condition","is","True,"
3953 ,"but","what","happens","when","it","is","False?"
3954 ,"Add","an",D.cyan "else","branch","to","handle","that","scenario!"
3964toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
3965toRecordReport source context record startRow startCol =
3967 RecordOpen row col ->
3968 case Code.whatIsNext source row col of
3969 Code.Keyword keyword ->
3971 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3972 region = toKeywordRegion row col keyword
3974 Report.Report "RESERVED WORD" region [] $
3975 Code.toSnippet source surroundings (Just region)
3978 "I just started parsing a record, but I got stuck on this field name:"
3981 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3982 \ that is a reserved word. Try using a different name!"
3987 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3988 region = toRegion row col
3990 Report.Report "PROBLEM IN RECORD" region [] $
3991 Code.toSnippet source surroundings (Just region)
3994 "I just started parsing a record, but I got stuck here:"
3998 ["I","was","expecting","to","see","a","record","field","defined","next,"
3999 ,"so","I","am","looking","for","a","name","like"
4000 ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
4003 "Field names must start with a lower-case letter. After that, you can use\
4004 \ any sequence of letters, numbers, and underscores."
4005 , noteForRecordError
4009 RecordEnd row col ->
4011 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4012 region = toRegion row col
4014 Report.Report "PROBLEM IN RECORD" region [] $
4015 Code.toSnippet source surroundings (Just region)
4018 "I am partway through parsing a record, but I got stuck here:"
4022 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
4023 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
4026 "When I get stuck like this, it usually means that there is a missing parenthesis\
4027 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4031 RecordField row col ->
4032 case Code.whatIsNext source row col of
4033 Code.Keyword keyword ->
4035 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4036 region = toKeywordRegion row col keyword
4038 Report.Report "RESERVED WORD" region [] $
4039 Code.toSnippet source surroundings (Just region)
4042 "I am partway through parsing a record, but I got stuck on this field name:"
4045 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
4046 \ that is a reserved word. Try using a different name!"
4049 Code.Other (Just ',') ->
4051 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4052 region = toRegion row col
4054 Report.Report "EXTRA COMMA" region [] $
4055 Code.toSnippet source surroundings (Just region)
4058 "I am partway through parsing a record, but I got stuck here:"
4062 "I am seeing two commas in a row. This is the second one!"
4064 "Just delete one of the commas and you should be all set!"
4065 , noteForRecordError
4071 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4072 region = toRegion row col
4074 Report.Report "EXTRA COMMA" region [] $
4075 Code.toSnippet source surroundings (Just region)
4078 "I am partway through parsing a record, but I got stuck here:"
4082 "Trailing commas are not allowed in records. Try deleting the comma that appears\
4083 \ before this closing curly brace."
4084 , noteForRecordError
4090 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4091 region = toRegion row col
4093 Report.Report "PROBLEM IN RECORD" region [] $
4094 Code.toSnippet source surroundings (Just region)
4097 "I am partway through parsing a record, but I got stuck here:"
4101 ["I","was","expecting","to","see","another","record","field","defined","next,"
4102 ,"so","I","am","looking","for","a","name","like"
4103 ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
4106 "Field names must start with a lower-case letter. After that, you can use\
4107 \ any sequence of letters, numbers, and underscores."
4108 , noteForRecordError
4112 RecordEquals row col ->
4114 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4115 region = toRegion row col
4117 Report.Report "PROBLEM IN RECORD" region [] $
4118 Code.toSnippet source surroundings (Just region)
4121 "I am partway through parsing a record, but I got stuck here:"
4125 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
4126 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
4128 , noteForRecordError
4132 RecordExpr expr row col ->
4133 toExprReport source (InNode NRecord startRow startCol context) expr row col
4135 RecordSpace space row col ->
4136 toSpaceReport source space row col
4138 RecordIndentOpen row col ->
4140 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4141 region = toRegion row col
4143 Report.Report "UNFINISHED RECORD" region [] $
4144 Code.toSnippet source surroundings (Just region)
4147 "I just saw the opening curly brace of a record, but then I got stuck here:"
4151 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
4152 ,"Try","defining","some","fields","of","your","own?"
4154 , noteForRecordIndentError
4158 RecordIndentEnd row col ->
4159 case Code.nextLineStartsWithCloseCurly source row of
4160 Just (curlyRow, curlyCol) ->
4162 surroundings = A.Region (A.Position startRow startCol) (A.Position curlyRow curlyCol)
4163 region = toRegion curlyRow curlyCol
4165 Report.Report "NEED MORE INDENTATION" region [] $
4166 Code.toSnippet source surroundings (Just region)
4169 "I was partway through parsing a record, but I got stuck here:"
4173 "I need this curly brace to be indented more. Try adding some spaces before it!"
4174 , noteForRecordError
4180 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4181 region = toRegion row col
4183 Report.Report "UNFINISHED RECORD" region [] $
4184 Code.toSnippet source surroundings (Just region)
4187 "I was partway through parsing a record, but I got stuck here:"
4191 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4192 ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
4194 , noteForRecordIndentError
4198 RecordIndentField row col ->
4200 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4201 region = toRegion row col
4203 Report.Report "UNFINISHED RECORD" region [] $
4204 Code.toSnippet source surroundings (Just region)
4207 "I am partway through parsing a record, but I got stuck after that last comma:"
4211 "Trailing commas are not allowed in records, so the fix may be to\
4212 \ delete that last comma? Or maybe you were in the middle of defining\
4213 \ an additional field?"
4214 , noteForRecordError
4218 RecordIndentEquals row col ->
4220 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4221 region = toRegion row col
4223 Report.Report "UNFINISHED RECORD" region [] $
4224 Code.toSnippet source surroundings (Just region)
4227 "I am partway through parsing a record. I just saw a record\
4228 \ field, so I was expecting to see an equals sign next:"
4232 ["Try","putting","an",D.green "=","followed","by","an","expression?"
4234 , noteForRecordIndentError
4238 RecordIndentExpr row col ->
4240 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4241 region = toRegion row col
4243 Report.Report "UNFINISHED RECORD" region [] $
4244 Code.toSnippet source surroundings (Just region)
4247 "I am partway through parsing a record, and I was expecting to run into an expression next:"
4251 ["Try","putting","something","like"
4252 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
4254 , noteForRecordIndentError
4259noteForRecordError :: D.Doc
4263 "If you are trying to define a record across multiple lines, I recommend using this format:"
4264 , D.indent 4 $ D.vcat $
4265 [ "{ name = " <> D.dullyellow "\"Alice\""
4266 , ", age = " <> D.dullyellow "42"
4267 , ", height = " <> D.dullyellow "1.75"
4271 "Notice that each line starts with some indentation. Usually two or four spaces.\
4272 \ This is the stylistic convention in the Elm ecosystem."
4276noteForRecordIndentError :: D.Doc
4277noteForRecordIndentError =
4280 "I may be confused by indentation. For example, if you are trying to define\
4281 \ a record across multiple lines, I recommend using this format:"
4282 , D.indent 4 $ D.vcat $
4283 [ "{ name = " <> D.dullyellow "\"Alice\""
4284 , ", age = " <> D.dullyellow "42"
4285 , ", height = " <> D.dullyellow "1.75"
4289 "Notice that each line starts with some indentation. Usually two or four spaces.\
4290 \ This is the stylistic convention in the Elm ecosystem!"
4298toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
4299toTupleReport source context tuple startRow startCol =
4301 TupleExpr expr row col ->
4302 toExprReport source (InNode NParens startRow startCol context) expr row col
4304 TupleSpace space row col ->
4305 toSpaceReport source space row col
4309 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4310 region = toRegion row col
4312 Report.Report "UNFINISHED PARENTHESES" region [] $
4313 Code.toSnippet source surroundings (Just region)
4316 "I was expecting to see a closing parentheses next, but I got stuck here:"
4319 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
4321 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
4322 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
4323 \ or missing brackets) that is confusing me."
4327 TupleOperatorClose row col ->
4329 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4330 region = toRegion row col
4332 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
4333 Code.toSnippet source surroundings (Just region)
4335 D.reflow "I was expecting a closing parenthesis here:"
4338 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4340 "I think I am parsing an operator function right now, so I am expecting to see\
4341 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
4346 TupleOperatorReserved operator row col ->
4348 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4349 region = toRegion row col
4351 Report.Report "UNEXPECTED SYMBOL" region [] $
4352 Code.toSnippet source surroundings (Just region)
4355 "I ran into an unexpected symbol here:"
4359 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
4360 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
4361 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
4362 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
4363 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
4366 TupleIndentExpr1 row col ->
4368 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4369 region = toRegion row col
4371 Report.Report "UNFINISHED PARENTHESES" region [] $
4372 Code.toSnippet source surroundings (Just region)
4375 "I just saw an open parenthesis, so I was expecting to see an expression next."
4379 ["Something","like",D.dullyellow "(4 + 5)","or"
4380 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
4381 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
4384 "I can get confused by indentation in cases like this, so\
4385 \ maybe you have an expression but it is not indented enough?"
4389 TupleIndentExprN row col ->
4391 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4392 region = toRegion row col
4394 Report.Report "UNFINISHED TUPLE" region [] $
4395 Code.toSnippet source surroundings (Just region)
4398 "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."
4402 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
4403 ,D.dullyellow "(\"Tom\",42)" <> ","
4404 ,"so","I","think","there","is","an","expression","missing","here?"
4407 "I can get confused by indentation in cases like this, so\
4408 \ maybe you have an expression but it is not indented enough?"
4412 TupleIndentEnd row col ->
4414 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4415 region = toRegion row col
4417 Report.Report "UNFINISHED PARENTHESES" region [] $
4418 Code.toSnippet source surroundings (Just region)
4421 "I was expecting to see a closing parenthesis next:"
4424 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4426 "I can get confused by indentation in cases like this, so\
4427 \ maybe you have a closing parenthesis but it is not indented enough?"
4432toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
4433toListReport source context list startRow startCol =
4435 ListSpace space row col ->
4436 toSpaceReport source space row col
4440 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4441 region = toRegion row col
4443 Report.Report "UNFINISHED LIST" region [] $
4444 Code.toSnippet source surroundings (Just region)
4447 "I am partway through parsing a list, but I got stuck here:"
4451 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
4452 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4455 "When I get stuck like this, it usually means that there is a missing parenthesis\
4456 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4460 ListExpr expr row col ->
4464 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
4465 region = toRegion r c
4467 Report.Report "UNFINISHED LIST" region [] $
4468 Code.toSnippet source surroundings (Just region)
4471 "I was expecting to see another list entry after that last comma:"
4475 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4477 "I recommend using the following format for lists that span multiple lines:"
4478 , D.indent 4 $ D.vcat $
4479 [ "[ " <> D.dullyellow "\"Alice\""
4480 , ", " <> D.dullyellow "\"Bob\""
4481 , ", " <> D.dullyellow "\"Chuck\""
4485 "Notice that each line starts with some indentation. Usually two or four spaces.\
4486 \ This is the stylistic convention in the Elm ecosystem."
4491 toExprReport source (InNode NList startRow startCol context) expr row col
4495 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4496 region = toRegion row col
4498 Report.Report "UNFINISHED LIST" region [] $
4499 Code.toSnippet source surroundings (Just region)
4502 "I am partway through parsing a list, but I got stuck here:"
4506 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
4507 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4510 "When I get stuck like this, it usually means that there is a missing parenthesis\
4511 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4515 ListIndentOpen row col ->
4517 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4518 region = toRegion row col
4520 Report.Report "UNFINISHED LIST" region [] $
4521 Code.toSnippet source surroundings (Just region)
4524 "I cannot find the end of this list:"
4528 ["You","could","change","it","to","something","like"
4529 ,D.dullyellow "[3,4,5]"
4531 ,D.dullyellow "[]" <> "."
4532 ,"Anything","where","there","is","an","open","and","close","square","brace,"
4533 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
4536 "I may be confused by indentation. For example, if you are trying to define\
4537 \ a list across multiple lines, I recommend using this format:"
4538 , D.indent 4 $ D.vcat $
4539 [ "[ " <> D.dullyellow "\"Alice\""
4540 , ", " <> D.dullyellow "\"Bob\""
4541 , ", " <> D.dullyellow "\"Chuck\""
4545 "Notice that each line starts with some indentation. Usually two or four spaces.\
4546 \ This is the stylistic convention in the Elm ecosystem."
4550 ListIndentEnd row col ->
4552 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4553 region = toRegion row col
4555 Report.Report "UNFINISHED LIST" region [] $
4556 Code.toSnippet source surroundings (Just region)
4559 "I cannot find the end of this list:"
4563 ["You","can","just","add","a","closing",D.dullyellow "]"
4564 ,"right","here,","and","I","will","be","all","set!"
4567 "I may be confused by indentation. For example, if you are trying to define\
4568 \ a list across multiple lines, I recommend using this format:"
4569 , D.indent 4 $ D.vcat $
4570 [ "[ " <> D.dullyellow "\"Alice\""
4571 , ", " <> D.dullyellow "\"Bob\""
4572 , ", " <> D.dullyellow "\"Chuck\""
4576 "Notice that each line starts with some indentation. Usually two or four spaces.\
4577 \ This is the stylistic convention in the Elm ecosystem."
4581 ListIndentExpr row col ->
4583 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4584 region = toRegion row col
4586 Report.Report "UNFINISHED LIST" region [] $
4587 Code.toSnippet source surroundings (Just region)
4590 "I was expecting to see another list entry after this comma:"
4594 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4596 "I recommend using the following format for lists that span multiple lines:"
4597 , D.indent 4 $ D.vcat $
4598 [ "[ " <> D.dullyellow "\"Alice\""
4599 , ", " <> D.dullyellow "\"Bob\""
4600 , ", " <> D.dullyellow "\"Chuck\""
4604 "Notice that each line starts with some indentation. Usually two or four spaces.\
4605 \ This is the stylistic convention in the Elm ecosystem."
4610toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
4611toFuncReport source context func startRow startCol =
4613 FuncSpace space row col ->
4614 toSpaceReport source space row col
4616 FuncArg pattern row col ->
4617 toPatternReport source PArg pattern row col
4619 FuncBody expr row col ->
4620 toExprReport source (InNode NFunc startRow startCol context) expr row col
4622 FuncArrow row col ->
4623 case Code.whatIsNext source row col of
4624 Code.Keyword keyword ->
4626 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4627 region = toKeywordRegion row col keyword
4629 Report.Report "RESERVED WORD" region [] $
4630 Code.toSnippet source surroundings (Just region)
4633 "I was parsing an anonymous function, but I got stuck here:"
4636 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
4637 \ it is a reserved word in this language. Try using a different argument name!"
4642 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4643 region = toRegion row col
4645 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4646 Code.toSnippet source surroundings (Just region)
4649 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4652 ["The","syntax","for","anonymous","functions","is"
4653 ,D.dullyellow "(\\x -> x + 1)"
4654 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4658 FuncIndentArg row col ->
4660 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4661 region = toRegion row col
4663 Report.Report "MISSING ARGUMENT" region [] $
4664 Code.toSnippet source surroundings (Just region)
4667 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
4671 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
4672 ,"Anything","that","starts","with","a","lower","case","letter!"
4675 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
4676 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
4677 \ like a better idea at the time!"
4681 FuncIndentArrow row col ->
4683 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4684 region = toRegion row col
4686 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4687 Code.toSnippet source surroundings (Just region)
4690 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4694 ["The","syntax","for","anonymous","functions","is"
4695 ,D.dullyellow "(\\x -> x + 1)"
4696 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4699 "It is possible that I am confused about indetation! I generally recommend\
4700 \ switching to named functions if the definition cannot fit inline nicely, so\
4701 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4702 \ the whole thing out into a named function. Things tend to be clearer that way!"
4706 FuncIndentBody row col ->
4708 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4709 region = toRegion row col
4711 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4712 Code.toSnippet source surroundings (Just region)
4715 "I was expecting to see the body of your anonymous function next:"
4719 ["The","syntax","for","anonymous","functions","is"
4720 ,D.dullyellow "(\\x -> x + 1)"
4721 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
4724 "It is possible that I am confused about indetation! I generally recommend\
4725 \ switching to named functions if the definition cannot fit inline nicely, so\
4726 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4727 \ the whole thing out into a named function. Things tend to be clearer that way!"
4742toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
4743toPatternReport source context pattern startRow startCol =
4745 PRecord record row col ->
4746 toPRecordReport source record row col
4748 PTuple tuple row col ->
4749 toPTupleReport source context tuple row col
4751 PList list row col ->
4752 toPListReport source context list row col
4755 case Code.whatIsNext source row col of
4756 Code.Keyword keyword ->
4758 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4759 region = toKeywordRegion row col keyword
4762 PArg -> "as an argument"
4763 PCase -> "in this pattern"
4764 PLet -> "in this pattern"
4766 Report.Report "RESERVED WORD" region [] $
4767 Code.toSnippet source surroundings (Just region)
4770 "It looks like you are trying to use `" ++ keyword ++ "` " ++ inThisThing ++ ":"
4773 "This is a reserved word! Try using some other name?"
4776 Code.Operator "-" ->
4778 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4779 region = toRegion row col
4781 Report.Report "UNEXPECTED SYMBOL" region [] $
4782 Code.toSnippet source surroundings (Just region)
4785 "I ran into a minus sign unexpectedly in this pattern:"
4788 "It is not possible to pattern match on negative numbers at this\
4789 \ time. Try using an `if` expression for that sort of thing for now."
4794 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4795 region = toRegion row col
4797 Report.Report "PROBLEM IN PATTERN" region [] $
4798 Code.toSnippet source surroundings (Just region)
4801 "I wanted to parse a pattern next, but I got stuck here:"
4804 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4805 ,"I","just","know","that","I","want","a","pattern","next."
4806 ,"Something","as","simple","as"
4807 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4812 PChar char row col ->
4813 toCharReport source char row col
4815 PString string row col ->
4816 toStringReport source string row col
4818 PNumber number row col ->
4819 toNumberReport source number row col
4821 PFloat width row col ->
4823 region = toWiderRegion row col width
4825 Report.Report "UNEXPECTED PATTERN" region [] $
4826 Code.toSnippet source region Nothing
4829 "I cannot pattern match with floating point numbers:"
4832 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
4833 ,"to","check","that","they","are","nearby","with","some","sort","of"
4834 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
4840 region = toRegion row col
4842 Report.Report "UNFINISHED PATTERN" region [] $
4843 Code.toSnippet source region Nothing $
4846 "I was expecting to see a variable name after the `as` keyword:"
4850 ["The","`as`","keyword","lets","you","write","patterns","like"
4851 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4852 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4853 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4854 ,"thing","with",D.dullyellow "point" <> "."
4857 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4858 \ people just want to use `as` as a variable name though. Try using a different name\
4863 PWildcardNotVar name width row col ->
4865 region = toWiderRegion row col (fromIntegral width)
4867 case dropWhile (=='_') (Name.toChars name) of
4868 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
4869 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
4871 Report.Report "UNEXPECTED NAME" region [] $
4872 Code.toSnippet source region Nothing $
4875 "Variable names cannot start with underscores like this:"
4878 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
4879 ,"ignore","the","value,","or","you","can","have","a","name","like"
4880 ] ++ examples ++ ["to","use","the","matched","value." ]
4883 PSpace space row col ->
4884 toSpaceReport source space row col
4886 PIndentStart row col ->
4888 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4889 region = toRegion row col
4891 Report.Report "UNFINISHED PATTERN" region [] $
4892 Code.toSnippet source surroundings (Just region)
4895 "I wanted to parse a pattern next, but I got stuck here:"
4899 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4900 ,"I","just","know","that","I","want","a","pattern","next."
4901 ,"Something","as","simple","as"
4902 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4906 "I can get confused by indentation. If you think there is a pattern next, maybe\
4907 \ it needs to be indented a bit more?"
4911 PIndentAlias row col ->
4913 region = toRegion row col
4915 Report.Report "UNFINISHED PATTERN" region [] $
4916 Code.toSnippet source region Nothing $
4919 "I was expecting to see a variable name after the `as` keyword:"
4923 ["The","`as`","keyword","lets","you","write","patterns","like"
4924 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4925 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4926 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4927 ,"thing","with",D.dullyellow "point."
4930 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4931 \ people just want to use `as` as a variable name though. Try using a different name\
4937toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
4938toPRecordReport source record startRow startCol =
4940 PRecordOpen row col ->
4941 toUnfinishRecordPatternReport source row col startRow startCol $
4942 D.reflow "I was expecting to see a field name next."
4944 PRecordEnd row col ->
4945 toUnfinishRecordPatternReport source row col startRow startCol $
4947 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4948 ,"Try","adding","a",D.dullyellow "}","here?"
4951 PRecordField row col ->
4952 case Code.whatIsNext source row col of
4953 Code.Keyword keyword ->
4955 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4956 region = toKeywordRegion row col keyword
4958 Report.Report "RESERVED WORD" region [] $
4959 Code.toSnippet source surroundings (Just region)
4962 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
4965 "This is a reserved word, not available for variable names. Try another name!"
4969 toUnfinishRecordPatternReport source row col startRow startCol $
4970 D.reflow "I was expecting to see a field name next."
4972 PRecordSpace space row col ->
4973 toSpaceReport source space row col
4975 PRecordIndentOpen row col ->
4976 toUnfinishRecordPatternReport source row col startRow startCol $
4977 D.reflow "I was expecting to see a field name next."
4979 PRecordIndentEnd row col ->
4980 toUnfinishRecordPatternReport source row col startRow startCol $
4982 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4983 ,"Try","adding","a",D.dullyellow "}","here?"
4986 PRecordIndentField row col ->
4987 toUnfinishRecordPatternReport source row col startRow startCol $
4988 D.reflow "I was expecting to see a field name next."
4991toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
4992toUnfinishRecordPatternReport source row col startRow startCol message =
4994 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4995 region = toRegion row col
4997 Report.Report "UNFINISHED RECORD PATTERN" region [] $
4998 Code.toSnippet source surroundings (Just region)
5001 "I was partway through parsing a record pattern, but I got stuck here:"
5006 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
5007 ,"where","you","list","the","field","names","you","want","to","access."
5014toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
5015toPTupleReport source context tuple startRow startCol =
5017 PTupleOpen row col ->
5018 case Code.whatIsNext source row col of
5019 Code.Keyword keyword ->
5021 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5022 region = toKeywordRegion row col keyword
5024 Report.Report "RESERVED WORD" region [] $
5025 Code.toSnippet source surroundings (Just region)
5028 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
5031 "This is a reserved word! Try using some other name?"
5036 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5037 region = toRegion row col
5039 Report.Report "UNFINISHED PARENTHESES" region [] $
5040 Code.toSnippet source surroundings (Just region)
5043 "I just saw an open parenthesis, but I got stuck here:"
5046 ["I","was","expecting","to","see","a","pattern","next."
5047 ,"Maybe","it","will","end","up","being","something"
5048 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
5052 PTupleEnd row col ->
5053 case Code.whatIsNext source row col of
5054 Code.Keyword keyword ->
5056 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5057 region = toKeywordRegion row col keyword
5059 Report.Report "RESERVED WORD" region [] $
5060 Code.toSnippet source surroundings (Just region) $
5063 "I ran into a reserved word in this pattern:"
5066 "The `" ++ keyword ++ "` keyword is reserved. Try using a different name instead!"
5071 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5072 region = toKeywordRegion row col op
5074 Report.Report "UNEXPECTED SYMBOL" region [] $
5075 Code.toSnippet source surroundings (Just region) $
5078 "I ran into the " ++ op ++ " symbol unexpectedly in this pattern:"
5081 "Only the :: symbol that works in patterns. It is useful if you\
5082 \ are pattern matching on lists, trying to get the first element\
5083 \ off the front. Did you want that instead?"
5086 Code.Close term bracket ->
5088 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5089 region = toRegion row col
5091 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
5092 Code.toSnippet source surroundings (Just region) $
5095 "I ran into a an unexpected " ++ term ++ " in this pattern:"
5098 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
5103 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5104 region = toRegion row col
5106 Report.Report "UNFINISHED PARENTHESES" region [] $
5107 Code.toSnippet source surroundings (Just region) $
5110 "I was partway through parsing a pattern, but I got stuck here:"
5113 ["I","was","expecting","a","closing","parenthesis","next,","so"
5114 ,"try","adding","a",D.dullyellow ")","to","see","if","that","helps?"
5118 PTupleExpr pattern row col ->
5119 toPatternReport source context pattern row col
5121 PTupleSpace space row col ->
5122 toSpaceReport source space row col
5124 PTupleIndentEnd row col ->
5126 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5127 region = toRegion row col
5129 Report.Report "UNFINISHED PARENTHESES" region [] $
5130 Code.toSnippet source surroundings (Just region) $
5133 "I was expecting a closing parenthesis next:"
5136 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
5138 "I can get confused by indentation in cases like this, so\
5139 \ maybe you have a closing parenthesis but it is not indented enough?"
5143 PTupleIndentExpr1 row col ->
5145 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5146 region = toRegion row col
5148 Report.Report "UNFINISHED PARENTHESES" region [] $
5149 Code.toSnippet source surroundings (Just region) $
5152 "I just saw an open parenthesis, but then I got stuck here:"
5155 ["I","was","expecting","to","see","a","pattern","next."
5156 ,"Maybe","it","will","end","up","being","something"
5157 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
5161 PTupleIndentExprN row col ->
5163 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5164 region = toRegion row col
5166 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
5167 Code.toSnippet source surroundings (Just region) $
5170 "I am partway through parsing a tuple pattern, but I got stuck here:"
5174 ["I","was","expecting","to","see","a","pattern","next."
5175 ,"I","am","expecting","the","final","result","to","be","something"
5176 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
5179 "I can get confused by indentation in cases like this, so the problem\
5180 \ may be that the next part is not indented enough?"
5185toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
5186toPListReport source context list startRow startCol =
5188 PListOpen row col ->
5189 case Code.whatIsNext source row col of
5190 Code.Keyword keyword ->
5192 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5193 region = toKeywordRegion row col keyword
5195 Report.Report "RESERVED WORD" region [] $
5196 Code.toSnippet source surroundings (Just region)
5199 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
5202 "This is a reserved word though! Try using some other name?"
5207 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5208 region = toRegion row col
5210 Report.Report "UNFINISHED LIST PATTERN" region [] $
5211 Code.toSnippet source surroundings (Just region) $
5214 "I just saw an open square bracket, but then I got stuck here:"
5216 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5221 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5222 region = toRegion row col
5224 Report.Report "UNFINISHED LIST PATTERN" region [] $
5225 Code.toSnippet source surroundings (Just region) $
5228 "I was expecting a closing square bracket to end this list pattern:"
5230 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5233 PListExpr pattern row col ->
5234 toPatternReport source context pattern row col
5236 PListSpace space row col ->
5237 toSpaceReport source space row col
5239 PListIndentOpen row col ->
5241 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5242 region = toRegion row col
5244 Report.Report "UNFINISHED LIST PATTERN" region [] $
5245 Code.toSnippet source surroundings (Just region) $
5248 "I just saw an open square bracket, but then I got stuck here:"
5251 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5253 "I can get confused by indentation in cases like this, so\
5254 \ maybe there is something next, but it is not indented enough?"
5258 PListIndentEnd row col ->
5260 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5261 region = toRegion row col
5263 Report.Report "UNFINISHED LIST PATTERN" region [] $
5264 Code.toSnippet source surroundings (Just region) $
5267 "I was expecting a closing square bracket to end this list pattern:"
5270 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5272 "I can get confused by indentation in cases like this, so\
5273 \ maybe you have a closing square bracket but it is not indented enough?"
5277 PListIndentExpr row col ->
5279 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5280 region = toRegion row col
5282 Report.Report "UNFINISHED LIST PATTERN" region [] $
5283 Code.toSnippet source surroundings (Just region) $
5286 "I am partway through parsing a list pattern, but I got stuck here:"
5290 "I was expecting to see another pattern next. Maybe a variable name."
5292 "I can get confused by indentation in cases like this, so\
5293 \ maybe there is more to this pattern but it is not indented enough?"
5303 = TC_Annotation Name.Name
5309toTypeReport :: Code.Source -> TContext -> Type -> Row -> Col -> Report.Report
5310toTypeReport source context tipe startRow startCol =
5312 TRecord record row col ->
5313 toTRecordReport source context record row col
5315 TTuple tuple row col ->
5316 toTTupleReport source context tuple row col
5319 case Code.whatIsNext source row col of
5320 Code.Keyword keyword ->
5322 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5323 region = toKeywordRegion row col keyword
5325 Report.Report "RESERVED WORD" region [] $
5326 Code.toSnippet source surroundings (Just region)
5329 "I was expecting to see a type next, but I got stuck on this reserved word:"
5332 "It looks like you are trying to use `" ++ keyword ++ "` as a type variable, but \
5333 \ it is a reserved word. Try using a different name!"
5338 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5339 region = toRegion row col
5343 TC_Annotation _ -> "type annotation"
5344 TC_CustomType -> "custom type"
5345 TC_TypeAlias -> "type alias"
5350 TC_Annotation name -> "the `" ++ Name.toChars name ++ "` type annotation"
5351 TC_CustomType -> "a custom type"
5352 TC_TypeAlias -> "a type alias"
5355 Report.Report ("PROBLEM IN " ++ map Char.toUpper thing) region [] $
5356 Code.toSnippet source surroundings (Just region)
5359 "I was partway through parsing " ++ something ++ ", but I got stuck here:"
5362 ["I","was","expecting","to","see","a","type","next."
5363 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5367 TSpace space row col ->
5368 toSpaceReport source space row col
5370 TIndentStart row col ->
5372 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5373 region = toRegion row col
5377 TC_Annotation _ -> "type annotation"
5378 TC_CustomType -> "custom type"
5379 TC_TypeAlias -> "type alias"
5382 Report.Report ("UNFINISHED " ++ map Char.toUpper thing) region [] $
5383 Code.toSnippet source surroundings (Just region)
5386 "I was partway through parsing a " ++ thing ++ ", but I got stuck here:"
5390 ["I","was","expecting","to","see","a","type","next."
5391 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5394 "I can get confused by indentation. If you think there is already a type\
5395 \ next, maybe it is not indented enough?"
5400toTRecordReport :: Code.Source -> TContext -> TRecord -> Row -> Col -> Report.Report
5401toTRecordReport source context record startRow startCol =
5403 TRecordOpen row col ->
5404 case Code.whatIsNext source row col of
5405 Code.Keyword keyword ->
5407 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5408 region = toKeywordRegion row col keyword
5410 Report.Report "RESERVED WORD" region [] $
5411 Code.toSnippet source surroundings (Just region)
5414 "I just started parsing a record type, but I got stuck on this field name:"
5417 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
5418 \ that is a reserved word. Try using a different name!"
5423 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5424 region = toRegion row col
5426 Report.Report "UNFINISHED RECORD TYPE" region [] $
5427 Code.toSnippet source surroundings (Just region)
5430 "I just started parsing a record type, but I got stuck here:"
5433 ["Record","types","look","like",D.dullyellow "{ name : String, age : Int },"
5434 ,"so","I","was","expecting","to","see","a","field","name","next."
5438 TRecordEnd row col ->
5440 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5441 region = toRegion row col
5443 Report.Report "UNFINISHED RECORD TYPE" region [] $
5444 Code.toSnippet source surroundings (Just region)
5447 "I am partway through parsing a record type, but I got stuck here:"
5451 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
5452 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
5455 "When I get stuck like this, it usually means that there is a missing parenthesis\
5456 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
5460 TRecordField row col ->
5461 case Code.whatIsNext source row col of
5462 Code.Keyword keyword ->
5464 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5465 region = toKeywordRegion row col keyword
5467 Report.Report "RESERVED WORD" region [] $
5468 Code.toSnippet source surroundings (Just region)
5471 "I am partway through parsing a record type, but I got stuck on this field name:"
5474 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
5475 \ that is a reserved word. Try using a different name!"
5478 Code.Other (Just ',') ->
5480 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5481 region = toRegion row col
5483 Report.Report "EXTRA COMMA" region [] $
5484 Code.toSnippet source surroundings (Just region)
5487 "I am partway through parsing a record type, but I got stuck here:"
5491 "I am seeing two commas in a row. This is the second one!"
5493 "Just delete one of the commas and you should be all set!"
5494 , noteForRecordTypeError
5500 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5501 region = toRegion row col
5503 Report.Report "EXTRA COMMA" region [] $
5504 Code.toSnippet source surroundings (Just region)
5507 "I am partway through parsing a record type, but I got stuck here:"
5511 "Trailing commas are not allowed in record types. Try deleting the comma that\
5512 \ appears before this closing curly brace."
5513 , noteForRecordTypeError
5519 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5520 region = toRegion row col
5522 Report.Report "PROBLEM IN RECORD TYPE" region [] $
5523 Code.toSnippet source surroundings (Just region)
5526 "I am partway through parsing a record type, but I got stuck here:"
5530 ["I","was","expecting","to","see","another","record","field","defined","next,"
5531 ,"so","I","am","looking","for","a","name","like"
5532 ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
5534 , noteForRecordTypeError
5538 TRecordColon row col ->
5540 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5541 region = toRegion row col
5543 Report.Report "UNFINISHED RECORD TYPE" region [] $
5544 Code.toSnippet source surroundings (Just region)
5547 "I am partway through parsing a record type, but I got stuck here:"
5551 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
5552 ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
5554 , noteForRecordTypeError
5558 TRecordType tipe row col ->
5559 toTypeReport source context tipe row col
5561 TRecordSpace space row col ->
5562 toSpaceReport source space row col
5564 TRecordIndentOpen row col ->
5566 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5567 region = toRegion row col
5569 Report.Report "UNFINISHED RECORD TYPE" region [] $
5570 Code.toSnippet source surroundings (Just region)
5573 "I just saw the opening curly brace of a record type, but then I got stuck here:"
5577 ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
5578 ,"Try","defining","some","fields","of","your","own?"
5580 , noteForRecordTypeIndentError
5584 TRecordIndentEnd row col ->
5585 case Code.nextLineStartsWithCloseCurly source row of
5586 Just (curlyRow, curlyCol) ->
5588 surroundings = A.Region (A.Position startRow startCol) (A.Position curlyRow curlyCol)
5589 region = toRegion curlyRow curlyCol
5591 Report.Report "NEED MORE INDENTATION" region [] $
5592 Code.toSnippet source surroundings (Just region)
5595 "I was partway through parsing a record type, but I got stuck here:"
5599 "I need this curly brace to be indented more. Try adding some spaces before it!"
5600 , noteForRecordTypeError
5606 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5607 region = toRegion row col
5609 Report.Report "UNFINISHED RECORD TYPE" region [] $
5610 Code.toSnippet source surroundings (Just region)
5613 "I was partway through parsing a record type, but I got stuck here:"
5617 ["I","was","expecting","to","see","a","closing","curly","brace","next."
5618 ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
5620 , noteForRecordTypeIndentError
5624 TRecordIndentField row col ->
5626 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5627 region = toRegion row col
5629 Report.Report "UNFINISHED RECORD TYPE" region [] $
5630 Code.toSnippet source surroundings (Just region)
5633 "I am partway through parsing a record type, but I got stuck after that last comma:"
5637 "Trailing commas are not allowed in record types, so the fix may be to\
5638 \ delete that last comma? Or maybe you were in the middle of defining\
5639 \ an additional field?"
5640 , noteForRecordTypeIndentError
5644 TRecordIndentColon row col ->
5646 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5647 region = toRegion row col
5649 Report.Report "UNFINISHED RECORD TYPE" region [] $
5650 Code.toSnippet source surroundings (Just region)
5653 "I am partway through parsing a record type. I just saw a record\
5654 \ field, so I was expecting to see a colon next:"
5658 ["Try","putting","an",D.green ":","followed","by","a","type?"
5660 , noteForRecordTypeIndentError
5664 TRecordIndentType row col ->
5666 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5667 region = toRegion row col
5669 Report.Report "UNFINISHED RECORD TYPE" region [] $
5670 Code.toSnippet source surroundings (Just region)
5673 "I am partway through parsing a record type, and I was expecting to run into a type next:"
5677 ["Try","putting","something","like"
5678 ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5680 , noteForRecordTypeIndentError
5685noteForRecordTypeError :: D.Doc
5686noteForRecordTypeError =
5689 "If you are trying to define a record type across multiple lines, I recommend using this format:"
5690 , D.indent 4 $ D.vcat $
5693 , ", height : Float"
5697 "Notice that each line starts with some indentation. Usually two or four spaces.\
5698 \ This is the stylistic convention in the Elm ecosystem."
5702noteForRecordTypeIndentError :: D.Doc
5703noteForRecordTypeIndentError =
5706 "I may be confused by indentation. For example, if you are trying to define\
5707 \ a record type across multiple lines, I recommend using this format:"
5708 , D.indent 4 $ D.vcat $
5711 , ", height : Float"
5715 "Notice that each line starts with some indentation. Usually two or four spaces.\
5716 \ This is the stylistic convention in the Elm ecosystem."
5720toTTupleReport :: Code.Source -> TContext -> TTuple -> Row -> Col -> Report.Report
5721toTTupleReport source context tuple startRow startCol =
5723 TTupleOpen row col ->
5724 case Code.whatIsNext source row col of
5725 Code.Keyword keyword ->
5727 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5728 region = toKeywordRegion row col keyword
5730 Report.Report "RESERVED WORD" region [] $
5731 Code.toSnippet source surroundings (Just region)
5734 "I ran into a reserved word unexpectedly:"
5737 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but \
5738 \ it is a reserved word. Try using a different name!"
5743 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5744 region = toRegion row col
5746 Report.Report "UNFINISHED PARENTHESES" region [] $
5747 Code.toSnippet source surroundings (Just region)
5750 "I just saw an open parenthesis, so I was expecting to see a type next."
5753 ["Something","like",D.dullyellow "(Maybe Int)","or"
5754 ,D.dullyellow "(List Person)" <> "."
5755 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5759 TTupleEnd row col ->
5761 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5762 region = toRegion row col
5764 Report.Report "UNFINISHED PARENTHESES" region [] $
5765 Code.toSnippet source surroundings (Just region)
5768 "I was expecting to see a closing parenthesis next, but I got stuck here:"
5771 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
5773 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
5774 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
5775 \ or missing brackets) that is confusing me."
5779 TTupleType tipe row col ->
5780 toTypeReport source context tipe row col
5782 TTupleSpace space row col ->
5783 toSpaceReport source space row col
5785 TTupleIndentType1 row col ->
5787 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5788 region = toRegion row col
5790 Report.Report "UNFINISHED PARENTHESES" region [] $
5791 Code.toSnippet source surroundings (Just region)
5794 "I just saw an open parenthesis, so I was expecting to see a type next."
5798 ["Something","like",D.dullyellow "(Maybe Int)","or"
5799 ,D.dullyellow "(List Person)" <> "."
5800 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5803 "I can get confused by indentation in cases like this, so\
5804 \ maybe you have a type but it is not indented enough?"
5808 TTupleIndentTypeN row col ->
5810 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5811 region = toRegion row col
5813 Report.Report "UNFINISHED TUPLE TYPE" region [] $
5814 Code.toSnippet source surroundings (Just region)
5817 "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."
5821 ["A","tuple","type","looks","like",D.dullyellow "(Float,Float)","or"
5822 ,D.dullyellow "(String,Int)" <> ","
5823 ,"so","I","think","there","is","a","type","missing","here?"
5826 "I can get confused by indentation in cases like this, so\
5827 \ maybe you have an expression but it is not indented enough?"
5831 TTupleIndentEnd row col ->
5833 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5834 region = toRegion row col
5836 Report.Report "UNFINISHED PARENTHESES" region [] $
5837 Code.toSnippet source surroundings (Just region)
5840 "I was expecting to see a closing parenthesis next:"
5843 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
5845 "I can get confused by indentation in cases like this, so\
5846 \ 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