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 ->
652 case Code.whatIsNext source row col of
653 Code.Keyword keyword ->
655 region = toKeywordRegion row col keyword
657 Report.Report "RESERVED WORD" region [] $
658 Code.toSnippet source region Nothing
661 "I got stuck on this reserved word:"
664 "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
669 region = toKeywordRegion row col op
671 Report.Report "UNEXPECTED SYMBOL" region [] $
672 Code.toSnippet source region Nothing
675 "I ran into an unexpected symbol:"
678 "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
679 \ I can give a better hint from there?"
682 Code.Close term bracket ->
684 region = toRegion row col
686 Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
687 Code.toSnippet source region Nothing
690 "I ran into an unexpected " ++ term ++ ":"
693 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
698 region = toKeywordRegion row col (c:cs)
700 Report.Report "UNEXPECTED NAME" region [] $
701 Code.toSnippet source region Nothing
704 "I got stuck on this name:"
707 "It is confusing me a lot! Normally I can give fairly specific hints, but\
708 \ something is really tripping me up this time."
713 region = toKeywordRegion row col (c:cs)
715 Report.Report "UNEXPECTED NAME" region [] $
716 Code.toSnippet source region Nothing
719 "I got stuck on this name:"
722 "It is confusing me a lot! Normally I can give fairly specific hints, but\
723 \ something is really tripping me up this time."
726 Code.Other maybeChar ->
728 region = toRegion row col
732 Report.Report "UNEXPECTED SEMICOLON" region [] $
733 Code.toSnippet source region Nothing
736 "I got stuck on this semicolon:"
739 [ D.reflow $ "Try removing it?"
741 "Some languages require semicolons at the end of each statement. These are\
742 \ often called C-like languages, and they usually share a lot of language design\
743 \ choices. (E.g. side-effects, for loops, etc.) Elm manages effects with commands\
744 \ and subscriptions instead, so there is no special syntax for \"statements\" and\
745 \ therefore no need to use semicolons to separate them. I think this will make\
746 \ more sense as you work through <https://guide.elm-lang.org> though!"
751 Report.Report "UNEXPECTED COMMA" region [] $
752 Code.toSnippet source region Nothing
755 "I got stuck on this comma:"
759 "I do not think I am parsing a list or tuple right now. Try deleting the comma?"
761 "If this is supposed to be part of a list, the problem may be a bit earlier.\
762 \ Perhaps the opening [ is missing? Or perhaps some value in the list has an extra\
763 \ closing ] that is making me think the list ended earlier? The same kinds of\
764 \ things could be going wrong if this is supposed to be a tuple."
769 Report.Report "UNEXPECTED CHARACTER" region [] $
770 Code.toSnippet source region Nothing
773 "I got stuck on this character:"
777 "It is not used for anything in Elm syntax. It is used for multi-line strings in\
778 \ some languages though, so if you want a string that spans multiple lines, you\
779 \ can use Elm's multi-line string syntax like this:"
780 , D.dullyellow $ D.indent 4 $ D.vcat $
782 , "# Multi-line Strings"
784 , "- start with triple double quotes"
785 , "- write whatever you want"
786 , "- no need to escape newlines or double quotes"
787 , "- end with triple double quotes"
791 "Otherwise I do not know what is going on! Try removing the character?"
796 Report.Report "UNEXPECTED SYMBOL" region [] $
797 Code.toSnippet source region Nothing
800 "I got stuck on this dollar sign:"
803 "It is not used for anything in Elm syntax. Are you coming from a language where\
804 \ dollar signs can be used in variable names? If so, try a name that (1) starts\
805 \ with a letter and (2) only contains letters, numbers, and underscores."
808 Just c | elem c ['#','@','!','%','~'] ->
809 Report.Report "UNEXPECTED SYMBOL" region [] $
810 Code.toSnippet source region Nothing
813 "I got stuck on this symbol:"
816 "It is not used for anything in Elm syntax. Try removing it?"
820 Report.Report "SYNTAX PROBLEM" region [] $
821 Code.toSnippet source region Nothing
827 "Whatever I am running into is confusing me a lot! Normally I can give fairly\
828 \ specific hints, but something is really tripping me up this time."
831 ModuleProblem row col ->
833 region = toRegion row col
835 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
836 Code.toSnippet source region Nothing
839 "I am parsing an `module` declaration, but I got stuck here:"
843 "Here are some examples of valid `module` declarations:"
844 , D.indent 4 $ D.vcat $
845 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
846 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
849 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
850 \ of files when the public interface of a module stays the same, so exposing fewer\
851 \ values can help improve compile times!"
855 ModuleName row col ->
857 region = toRegion row col
859 Report.Report "EXPECTING MODULE NAME" region [] $
860 Code.toSnippet source region Nothing
863 "I was parsing an `module` declaration until I got stuck here:"
867 "I was expecting to see the module name next, like in these examples:"
868 , D.indent 4 $ D.vcat $
869 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
870 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
871 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
872 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
875 "Notice that the module names all start with capital letters. That is required!"
879 ModuleExposing exposing row col ->
880 toExposingReport source exposing row col
882 PortModuleProblem row col ->
884 region = toRegion row col
886 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
887 Code.toSnippet source region Nothing
890 "I am parsing an `port module` declaration, but I got stuck here:"
894 "Here are some examples of valid `port module` declarations:"
895 , D.indent 4 $ D.vcat $
896 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
897 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
899 , D.link "Note" "Read" "ports" "for more help."
903 PortModuleName row col ->
905 region = toRegion row col
907 Report.Report "EXPECTING MODULE NAME" region [] $
908 Code.toSnippet source region Nothing
911 "I was parsing an `module` declaration until I got stuck here:"
915 "I was expecting to see the module name next, like in these examples:"
916 , D.indent 4 $ D.vcat $
917 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
918 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
921 "Notice that the module names start with capital letters. That is required!"
925 PortModuleExposing exposing row col ->
926 toExposingReport source exposing row col
930 region = toRegion row col
932 Report.Report "BAD MODULE DECLARATION" region [] $
933 Code.toSnippet source region Nothing
936 "I cannot parse this module declaration:"
939 "This type of module is reserved for the @elm organization. It is used to\
940 \ define certain effects, avoiding building them into the compiler."
945 region = toRegion row col
947 toBadFirstLineReport keyword =
948 Report.Report "TOO MUCH INDENTATION" region [] $
949 Code.toSnippet source region Nothing
952 "This `" ++ keyword ++ "` should not have any spaces before it:"
955 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
959 case Code.whatIsNext source row col of
960 Code.Keyword "module" -> toBadFirstLineReport "module"
961 Code.Keyword "import" -> toBadFirstLineReport "import"
962 Code.Keyword "type" -> toBadFirstLineReport "type"
963 Code.Keyword "port" -> toBadFirstLineReport "port"
965 Report.Report "SYNTAX PROBLEM" region [] $
966 Code.toSnippet source region Nothing
973 "I am not sure what is going on, but I recommend starting an Elm\
974 \ file with the following lines:"
975 , D.indent 4 $ D.vcat $
976 [ D.fillSep [D.cyan "import","Html"]
979 , " Html.text " <> D.dullyellow "\"Hello!\""
982 "You should be able to copy those lines directly into your file. Check out the\
983 \ examples at <https://elm-lang.org/examples> for more help getting started!"
985 "This can also happen when something is indented too much!"
989 ImportStart row col ->
990 toImportReport source row col
992 ImportName row col ->
994 region = toRegion row col
996 Report.Report "EXPECTING IMPORT NAME" region [] $
997 Code.toSnippet source region Nothing
1000 "I was parsing an `import` until I got stuck here:"
1004 "I was expecting to see a module name next, like in these examples:"
1005 , D.indent 4 $ D.vcat $
1006 [ D.fillSep [D.cyan "import","Dict"]
1007 , D.fillSep [D.cyan "import","Maybe"]
1008 , D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","A"]
1009 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "exposing","(..)"]
1012 "Notice that the module names all start with capital letters. That is required!"
1017 toImportReport source row col
1019 ImportAlias row col ->
1021 region = toRegion row col
1023 Report.Report "EXPECTING IMPORT ALIAS" region [] $
1024 Code.toSnippet source region Nothing
1027 "I was parsing an `import` until I got stuck here:"
1031 "I was expecting to see an alias next, like in these examples:"
1032 , D.indent 4 $ D.vcat $
1033 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
1034 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
1035 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
1038 "Notice that the alias always starts with a capital letter. That is required!"
1042 ImportExposing row col ->
1043 toImportReport source row col
1045 ImportExposingList exposing row col ->
1046 toExposingReport source exposing row col
1048 ImportEnd row col ->
1049 toImportReport source row col
1051 ImportIndentName row col ->
1052 toImportReport source row col
1054 ImportIndentAlias row col ->
1055 toImportReport source row col
1057 ImportIndentExposingList row col ->
1059 region = toRegion row col
1061 Report.Report "UNFINISHED IMPORT" region [] $
1062 Code.toSnippet source region Nothing
1065 "I was parsing an `import` until I got stuck here:"
1069 "I was expecting to see the list of exposed values next. For example, here\
1070 \ are two ways to expose values from the `Html` module:"
1071 , D.indent 4 $ D.vcat $
1072 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1073 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
1076 "I generally recommend the second style. It is more explicit, making it\
1077 \ much easier to figure out where values are coming from in large projects!"
1083 region = toRegion row col
1085 Report.Report "BAD INFIX" region [] $
1086 Code.toSnippet source region Nothing
1089 "Something went wrong in this infix operator declaration:"
1092 "This feature is used by the @elm organization to define the\
1093 \ languages built-in operators."
1096 Declarations decl _ _ ->
1097 toDeclarationsReport source decl
1104toImportReport :: Code.Source -> Row -> Col -> Report.Report
1105toImportReport source row col =
1107 region = toRegion row col
1109 Report.Report "UNFINISHED IMPORT" region [] $
1110 Code.toSnippet source region Nothing
1113 "I am partway through parsing an import, but I got stuck here:"
1117 "Here are some examples of valid `import` declarations:"
1118 , D.indent 4 $ D.vcat $
1119 [ D.fillSep [D.cyan "import","Html"]
1120 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
1121 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
1122 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
1125 "You are probably trying to import a different module, but try to make it look like one of these examples!"
1134toExposingReport :: Code.Source -> Exposing -> Row -> Col -> Report.Report
1135toExposingReport source exposing startRow startCol =
1137 ExposingSpace space row col ->
1138 toSpaceReport source space row col
1140 ExposingStart row col ->
1142 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1143 region = toRegion row col
1145 Report.Report "PROBLEM IN EXPOSING" region [] $
1146 Code.toSnippet source surroundings (Just region)
1149 "I want to parse exposed values, but I am getting stuck here:"
1153 ["Exposed","values","are","always","surrounded","by","parentheses."
1154 ,"So","try","adding","a",D.green "(","here?"
1156 , D.toSimpleNote "Here are some valid examples of `exposing` for reference:"
1157 , D.indent 4 $ D.vcat $
1158 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1159 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
1162 "If you are getting tripped up, you can just expose everything for now. It should\
1163 \ get easier to make an explicit exposing list as you see more examples in the wild."
1167 ExposingValue row col ->
1168 case Code.whatIsNext source row col of
1169 Code.Keyword keyword ->
1171 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1172 region = toKeywordRegion row col keyword
1174 Report.Report "RESERVED WORD" region [] $
1175 Code.toSnippet source surroundings (Just region)
1178 "I got stuck on this reserved word:"
1181 "It looks like you are trying to expose `" ++ keyword ++ "` but that is a reserved word. Is there a typo?"
1186 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1187 region = toKeywordRegion row col op
1189 Report.Report "UNEXPECTED SYMBOL" region [] $
1190 Code.toSnippet source surroundings (Just region)
1193 "I got stuck on this symbol:"
1197 "If you are trying to expose an operator, add parentheses around it like this:"
1198 , D.indent 4 $ D.dullyellow (D.fromChars op) <> " -> " <> D.green ("(" <> D.fromChars op <> ")")
1204 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1205 region = toRegion row col
1207 Report.Report "PROBLEM IN EXPOSING" region [] $
1208 Code.toSnippet source surroundings (Just region)
1211 "I got stuck while parsing these exposed values:"
1215 "I do not have an exact recommendation, so here are some valid examples\
1216 \ of `exposing` for reference:"
1217 , D.indent 4 $ D.vcat $
1218 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1219 , D.fillSep [D.cyan "import","Basics",D.cyan "exposing","(Int, Float, Bool(..), (+), not, sqrt)"]
1222 "These examples show how to expose types, variants, operators, and functions. Everything\
1223 \ should be some permutation of these examples, just with different names."
1227 ExposingOperator row col ->
1229 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1230 region = toRegion row col
1232 Report.Report "PROBLEM IN EXPOSING" region [] $
1233 Code.toSnippet source surroundings (Just region)
1236 "I just saw an open parenthesis, so I was expecting an operator next:"
1239 ["It","is","possible","to","expose","operators,","so","I","was","expecting"
1240 ,"to","see","something","like",D.dullyellow "(+)","or",D.dullyellow "(|=)"
1241 ,"or",D.dullyellow "(||)","after","I","saw","that","open","parenthesis."
1245 ExposingOperatorReserved op row col ->
1247 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1248 region = toRegion row col
1250 Report.Report "RESERVED SYMBOL" region [] $
1251 Code.toSnippet source surroundings (Just region)
1254 "I cannot expose this as an operator:"
1257 BadDot -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1258 BadPipe -> D.fillSep ["Maybe","you","want",D.dullyellow "(||)","instead?"]
1259 BadArrow -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1260 BadEquals -> D.fillSep ["Maybe","you","want",D.dullyellow "(==)","instead?"]
1261 BadHasType -> D.fillSep ["Maybe","you","want",D.dullyellow "(::)","instead?"]
1264 ExposingOperatorRightParen row col ->
1266 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1267 region = toRegion row col
1269 Report.Report "PROBLEM IN EXPOSING" region [] $
1270 Code.toSnippet source surroundings (Just region)
1273 "It looks like you are exposing an operator, but I got stuck here:"
1276 ["I","was","expecting","to","see","the","closing","parenthesis","immediately"
1277 ,"after","the","operator.","Try","adding","a",D.green ")","right","here?"
1281 ExposingEnd row col ->
1283 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1284 region = toRegion row col
1286 Report.Report "UNFINISHED EXPOSING" region [] $
1287 Code.toSnippet source surroundings (Just region)
1290 "I was partway through parsing exposed values, but I got stuck here:"
1293 "Maybe there is a comma missing before this?"
1296 ExposingTypePrivacy row col ->
1298 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1299 region = toRegion row col
1301 Report.Report "PROBLEM EXPOSING CUSTOM TYPE VARIANTS" region [] $
1302 Code.toSnippet source surroundings (Just region)
1305 "It looks like you are trying to expose the variants of a custom type:"
1309 ["You","need","to","write","something","like"
1310 ,D.dullyellow "Status(..)","or",D.dullyellow "Entity(..)"
1311 ,"though.","It","is","all","or","nothing,","otherwise","`case`"
1312 ,"expressions","could","miss","a","variant","and","crash!"
1315 "It is often best to keep the variants hidden! If someone pattern matches on\
1316 \ the variants, it is a MAJOR change if any new variants are added. Suddenly\
1317 \ their `case` expressions do not cover all variants! So if you do not need\
1318 \ people to pattern match, keep the variants hidden and expose functions to\
1319 \ construct values of this type. This way you can add new variants as a MINOR change!"
1323 ExposingIndentEnd row col ->
1325 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1326 region = toRegion row col
1328 Report.Report "UNFINISHED EXPOSING" region [] $
1329 Code.toSnippet source surroundings (Just region)
1332 "I was partway through parsing exposed values, but I got stuck here:"
1336 ["I","was","expecting","a","closing","parenthesis."
1337 ,"Try","adding","a",D.green ")","right","here?"
1340 "I can get confused when there is not enough indentation, so if you already\
1341 \ have a closing parenthesis, it probably just needs some spaces in front of it."
1345 ExposingIndentValue row col ->
1347 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1348 region = toRegion row col
1350 Report.Report "UNFINISHED EXPOSING" region [] $
1351 Code.toSnippet source surroundings (Just region)
1354 "I was partway through parsing exposed values, but I got stuck here:"
1357 "I was expecting another value to expose."
1365toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
1366toSpaceReport source space row col =
1370 region = toRegion row col
1372 Report.Report "NO TABS" region [] $
1373 Code.toSnippet source region Nothing
1376 "I ran into a tab, but tabs are not allowed in Elm files."
1379 "Replace the tab with spaces."
1382 EndlessMultiComment ->
1384 region = toWiderRegion row col 2
1386 Report.Report "ENDLESS COMMENT" region [] $
1387 Code.toSnippet source region Nothing
1390 "I cannot find the end of this multi-line comment:"
1393 [ D.reflow "Add a -} somewhere after this to end the comment."
1395 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
1396 \ that happens to contain another comment. Like parentheses and curly braces,\
1397 \ the start and end markers must always be balanced. Maybe that is the problem?"
1406toRegion :: Row -> Col -> A.Region
1409 pos = A.Position row col
1414toWiderRegion :: Row -> Col -> Word16 -> A.Region
1415toWiderRegion row col extra =
1417 (A.Position row col)
1418 (A.Position row (col + extra))
1421toKeywordRegion :: Row -> Col -> [Char.Char] -> A.Region
1422toKeywordRegion row col keyword =
1424 (A.Position row col)
1425 (A.Position row (col + fromIntegral (length keyword)))
1428toDeclarationsReport :: Code.Source -> Decl -> Report.Report
1429toDeclarationsReport source decl =
1431 DeclStart row col ->
1432 case Code.whatIsNext source row col of
1433 Code.Close term bracket ->
1435 region = toRegion row col
1437 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1438 Code.toSnippet source region Nothing
1441 "I was not expecting to see a " ++ term ++ " here:"
1443 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1446 Code.Keyword keyword ->
1448 region = toKeywordRegion row col keyword
1450 Report.Report "RESERVED WORD" region [] $
1451 Code.toSnippet source region Nothing
1454 "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1459 "It is reserved for declaring imports at the top of your module. If you want\
1460 \ another import, try moving it up top with the other imports. If you want to\
1461 \ define a value or function, try changing the name to something else!"
1466 "It is reserved for writing `case` expressions. Try using a different name?"
1468 "If you are trying to write a `case` expression, it needs to be part of a\
1469 \ definition. So you could write something like this instead:"
1470 , D.indent 4 $ D.vcat $
1471 [ D.indent 0 $ D.fillSep ["getWidth","maybeWidth","="]
1472 , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1473 , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1474 , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1476 , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1477 , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1480 "This defines a `getWidth` function that you can use elsewhere in your program."
1486 "It is reserved for writing `if` expressions. Try using a different name?"
1488 "If you are trying to write an `if` expression, it needs to be part of a\
1489 \ definition. So you could write something like this instead:"
1490 , D.indent 4 $ D.vcat $
1494 ,D.cyan "if","name","==",D.dullyellow "\"Abraham Lincoln\""
1495 ,D.cyan "then",D.dullyellow "\"Greetings Mr. President.\""
1496 ,D.cyan "else",D.dullyellow "\"Hey!\""
1500 "This defines a `reviewPowerLevel` function that you can use elsewhere in your program."
1505 "It is a reserved word. Try changing the name to something else?"
1510 region = toRegion row col
1512 Report.Report "UNEXPECTED CAPITAL LETTER" region [] $
1513 Code.toSnippet source region Nothing
1516 "Declarations always start with a lower-case letter, so I am getting stuck here:"
1520 ["Try","a","name","like"
1521 ,D.green (D.fromChars (Char.toLower c : cs))
1525 "Here are a couple valid declarations for reference:"
1526 , D.indent 4 $ D.vcat $
1527 [ "greet : String -> String"
1529 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1531 , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1534 "Notice that they always start with a lower-case letter. Capitalization matters!"
1538 Code.Other (Just char) | elem char ['(', '{', '[', '+', '-', '*', '/', '^', '&', '|', '"', '\'', '!', '@', '#', '$', '%'] ->
1540 region = toRegion row col
1542 Report.Report "UNEXPECTED SYMBOL" region [] $
1543 Code.toSnippet source region Nothing
1546 "I am getting stuck because this line starts with the " ++ [char] ++ " symbol:"
1550 "When a line has no spaces at the beginning, I expect it to be a declaration like one of these:"
1551 , D.indent 4 $ D.vcat $
1552 [ "greet : String -> String"
1554 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1556 , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1559 "If this is not supposed to be a declaration, try adding some spaces before it?"
1565 region = toRegion row col
1567 Report.Report "WEIRD DECLARATION" region [] $
1568 Code.toSnippet source region Nothing
1571 "I am trying to parse a declaration, but I am getting stuck here:"
1575 "I am not sure what is going wrong, so here are a couple valid declarations for reference:"
1576 , D.indent 4 $ D.vcat $
1577 [ "greet : String -> String"
1579 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1581 , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1584 "Try to make your declaration look like one of those?"
1588 DeclSpace space row col ->
1589 toSpaceReport source space row col
1591 Port port_ row col ->
1592 toPortReport source port_ row col
1594 DeclType declType row col ->
1595 toDeclTypeReport source declType row col
1597 DeclDef name declDef row col ->
1598 toDeclDefReport source name declDef row col
1600 DeclFreshLineAfterDocComment row col ->
1602 region = toRegion row col
1604 Report.Report "EXPECTING DECLARATION" region [] $
1605 Code.toSnippet source region Nothing
1608 "I just saw a doc comment, but then I got stuck here:"
1611 "I was expecting to see the corresponding declaration next, starting on a fresh\
1612 \ line with no indentation."
1620toPortReport :: Code.Source -> Port -> Row -> Col -> Report.Report
1621toPortReport source port_ startRow startCol =
1623 PortSpace space row col ->
1624 toSpaceReport source space row col
1627 case Code.whatIsNext source row col of
1628 Code.Keyword keyword ->
1630 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1631 region = toKeywordRegion row col keyword
1633 Report.Report "RESERVED WORD" region [] $
1634 Code.toSnippet source surroundings (Just region)
1637 "I cannot handle ports with names like this:"
1640 "You are trying to make a port named `" ++ keyword
1641 ++ "` but that is a reserved word. Try using some other name?"
1646 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1647 region = toRegion row col
1649 Report.Report "PORT PROBLEM" region [] $
1650 Code.toSnippet source surroundings (Just region)
1653 "I just saw the start of a `port` declaration, but then I got stuck here:"
1657 ["I","was","expecting","to","see","a","name","like"
1658 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1659 ,"Something","that","starts","with","a","lower-case","letter."
1665 PortColon row col ->
1667 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1668 region = toRegion row col
1670 Report.Report "PORT PROBLEM" region [] $
1671 Code.toSnippet source surroundings (Just region)
1674 "I just saw the start of a `port` declaration, but then I got stuck here:"
1678 "I was expecting to see a colon next. And then a type that tells me\
1679 \ what type of values are going to flow through."
1684 PortType tipe row col ->
1685 toTypeReport source TC_Port tipe row col
1687 PortIndentName row col ->
1689 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1690 region = toRegion row col
1692 Report.Report "UNFINISHED PORT" region [] $
1693 Code.toSnippet source surroundings (Just region)
1696 "I just saw the start of a `port` declaration, but then I got stuck here:"
1700 ["I","was","expecting","to","see","a","name","like"
1701 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1702 ,"Something","that","starts","with","a","lower-case","letter."
1708 PortIndentColon row col ->
1710 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1711 region = toRegion row col
1713 Report.Report "UNFINISHED PORT" region [] $
1714 Code.toSnippet source surroundings (Just region)
1717 "I just saw the start of a `port` declaration, but then I got stuck here:"
1721 "I was expecting to see a colon next. And then a type that tells me\
1722 \ what type of values are going to flow through."
1727 PortIndentType 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 type next. Here are examples of outgoing and\
1741 \ incoming ports for reference:"
1742 , D.indent 4 $ D.vcat $
1743 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1744 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1747 "The first line defines a `send` port so you can send strings out to JavaScript.\
1748 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1749 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1750 \ get receive messages when new WebSocket messages come in or when an entry in\
1751 \ IndexedDB changes for some external reason."
1760 "Here are some example `port` declarations 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 the IndexedDB\
1770 \ is changed for some external reason."
1778toDeclTypeReport :: Code.Source -> DeclType -> Row -> Col -> Report.Report
1779toDeclTypeReport source declType startRow startCol =
1781 DT_Space space row col ->
1782 toSpaceReport source space row col
1786 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1787 region = toRegion row col
1789 Report.Report "EXPECTING TYPE NAME" region [] $
1790 Code.toSnippet source surroundings (Just region)
1793 "I think I am parsing a type declaration, but I got stuck here:"
1797 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1798 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1804 DT_Alias typeAlias row col ->
1805 toTypeAliasReport source typeAlias row col
1807 DT_Union customType row col ->
1808 toCustomTypeReport source customType row col
1810 DT_IndentName row col ->
1812 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1813 region = toRegion row col
1815 Report.Report "EXPECTING TYPE NAME" region [] $
1816 Code.toSnippet source surroundings (Just region)
1819 "I think I am parsing a type declaration, but I got stuck here:"
1823 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1824 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1831toTypeAliasReport :: Code.Source -> TypeAlias -> Row -> Col -> Report.Report
1832toTypeAliasReport source typeAlias startRow startCol =
1834 AliasSpace space row col ->
1835 toSpaceReport source space row col
1837 AliasName row col ->
1839 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1840 region = toRegion row col
1842 Report.Report "EXPECTING TYPE ALIAS NAME" region [] $
1843 Code.toSnippet source surroundings (Just region)
1846 "I am partway through parsing a type alias, but I got stuck here:"
1850 ["I","was","expecting","a","name","like",D.dullyellow "Person","or",D.dullyellow "Point"
1851 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1857 AliasEquals row col ->
1858 case Code.whatIsNext source row col of
1859 Code.Keyword keyword ->
1861 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1862 region = toKeywordRegion row col keyword
1864 Report.Report "RESERVED WORD" region [] $
1865 Code.toSnippet source surroundings (Just region)
1868 "I ran into a reserved word unexpectedly while parsing this type alias:"
1872 "It looks like you are trying use `" ++ keyword
1873 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1880 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1881 region = toRegion row col
1883 Report.Report "PROBLEM IN TYPE ALIAS" region [] $
1884 Code.toSnippet source surroundings (Just region)
1887 "I am partway through parsing a type alias, but I got stuck here:"
1891 "I was expecting to see a type variable or an equals sign next."
1896 AliasBody tipe row col ->
1897 toTypeReport source TC_TypeAlias tipe row col
1899 AliasIndentEquals row col ->
1901 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1902 region = toRegion row col
1904 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1905 Code.toSnippet source surroundings (Just region)
1908 "I am partway through parsing a type alias, but I got stuck here:"
1912 "I was expecting to see a type variable or an equals sign next."
1917 AliasIndentBody row col ->
1919 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1920 region = toRegion row col
1922 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1923 Code.toSnippet source surroundings (Just region)
1926 "I am partway through parsing a type alias, but I got stuck here:"
1930 ["I","was","expecting","to","see","a","type","next.","Something","as","simple"
1931 ,"as",D.dullyellow "Int","or",D.dullyellow "Float","would","work!"
1938typeAliasNote :: D.Doc
1942 "Here is an example of a valid `type alias` for reference:"
1944 [ D.indent 4 $ D.fillSep [D.cyan "type",D.cyan "alias","Person","="]
1945 , D.indent 6 $ D.vcat $
1953 "This would let us use `Person` as a shorthand for that record type. Using this\
1954 \ shorthand makes type annotations much easier to read, and makes changing code\
1955 \ easier if you decide later that there is more to a person than age and height!"
1959toCustomTypeReport :: Code.Source -> CustomType -> Row -> Col -> Report.Report
1960toCustomTypeReport source customType startRow startCol =
1962 CT_Space space row col ->
1963 toSpaceReport source space row col
1967 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1968 region = toRegion row col
1970 Report.Report "EXPECTING TYPE NAME" region [] $
1971 Code.toSnippet source surroundings (Just region)
1974 "I think I am parsing a type declaration, but I got stuck here:"
1978 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1979 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1985 CT_Equals row col ->
1986 case Code.whatIsNext source row col of
1987 Code.Keyword keyword ->
1989 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1990 region = toKeywordRegion row col keyword
1992 Report.Report "RESERVED WORD" region [] $
1993 Code.toSnippet source surroundings (Just region)
1996 "I ran into a reserved word unexpectedly while parsing this custom type:"
2000 "It looks like you are trying use `" ++ keyword
2001 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
2008 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2009 region = toRegion row col
2011 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
2012 Code.toSnippet source surroundings (Just region)
2015 "I am partway through parsing a custom type, but I got stuck here:"
2019 "I was expecting to see a type variable or an equals sign next."
2026 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2027 region = toRegion row col
2029 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
2030 Code.toSnippet source surroundings (Just region)
2033 "I am partway through parsing a custom type, but I got stuck here:"
2037 "I was expecting to see a vertical bar like | next."
2042 CT_Variant row col ->
2044 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2045 region = toRegion row col
2047 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
2048 Code.toSnippet source surroundings (Just region)
2051 "I am partway through parsing a custom type, but I got stuck here:"
2055 ["I","was","expecting","to","see","a","variant","name","next."
2056 ,"Something","like",D.dullyellow "Success","or",D.dullyellow "Sandwich" <> "."
2057 ,"Any","name","that","starts","with","a","capital","letter","really!"
2063 CT_VariantArg tipe row col ->
2064 toTypeReport source TC_CustomType tipe row col
2066 CT_IndentEquals row col ->
2068 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2069 region = toRegion row col
2071 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2072 Code.toSnippet source surroundings (Just region)
2075 "I am partway through parsing a custom type, but I got stuck here:"
2079 "I was expecting to see a type variable or an equals sign next."
2084 CT_IndentBar row col ->
2086 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2087 region = toRegion row col
2089 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2090 Code.toSnippet source surroundings (Just region)
2093 "I am partway through parsing a custom type, but I got stuck here:"
2097 "I was expecting to see a vertical bar like | next."
2102 CT_IndentAfterBar row col ->
2104 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2105 region = toRegion row col
2107 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2108 Code.toSnippet source surroundings (Just region)
2111 "I am partway through parsing a custom type, but I got stuck here:"
2115 "I just saw a vertical bar, so I was expecting to see another variant defined next."
2120 CT_IndentAfterEquals row col ->
2122 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2123 region = toRegion row col
2125 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
2126 Code.toSnippet source surroundings (Just region)
2129 "I am partway through parsing a custom type, but I got stuck here:"
2133 "I just saw an equals sign, so I was expecting to see the first variant defined next."
2139customTypeNote :: D.Doc
2143 "Here is an example of a valid `type` declaration for reference:"
2145 [ D.indent 4 $ D.fillSep [D.cyan "type","Status"]
2146 , D.indent 6 $ D.fillSep ["=","Failure"]
2147 , D.indent 6 $ D.fillSep ["|","Waiting"]
2148 , D.indent 6 $ D.fillSep ["|","Success","String"]
2151 "This defines a new `Status` type with three variants. This could be useful if\
2152 \ we are waiting for an HTTP request. Maybe we start with `Waiting` and then\
2153 \ switch to `Failure` or `Success \"message from server\"` depending on how\
2154 \ things go. Notice that the Success variant has some associated data, allowing\
2155 \ us to store a String if the request goes well!"
2163toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
2164toDeclDefReport source name declDef startRow startCol =
2166 DeclDefSpace space row col ->
2167 toSpaceReport source space row col
2169 DeclDefEquals row col ->
2170 case Code.whatIsNext source row col of
2171 Code.Keyword keyword ->
2173 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2174 region = toKeywordRegion row col keyword
2176 Report.Report "RESERVED WORD" region [] $
2177 Code.toSnippet source surroundings (Just region)
2181 ,"`" <> D.cyan (D.fromChars keyword) <> "`"
2182 ,"is","reserved","in","Elm,","so","it","cannot"
2183 ,"be","used","as","an","argument","here:"
2188 "Try renaming it to something else."
2192 ["This","keyword","is","reserved","for","pattern","matches","like"
2193 ,"((x,y)",D.cyan "as","point)","where","you","want","to","name","a","tuple","and"
2194 ,"the","values","it","contains."
2199 "The `" ++ keyword ++ "` keyword has a special meaning in Elm, so it can only be used in certain situations."
2203 Code.Operator "->" ->
2205 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2206 region = toWiderRegion row col 2
2208 Report.Report "MISSING COLON?" region [] $
2209 Code.toSnippet source surroundings (Just region)
2212 "I was not expecting to see an arrow here:"
2216 ["This","usually","means","a",D.green ":","is","missing","a","bit","earlier","in"
2217 ,"a","type","annotation.","It","could","be","something","else","though,","so"
2218 ,"here","is","a","valid","definition","for","reference:"
2220 , D.indent 4 $ D.vcat $
2221 [ "greet : String -> String"
2223 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2226 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
2232 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2233 region = toKeywordRegion row col op
2235 Report.Report "UNEXPECTED SYMBOL" region [] $
2236 Code.toSnippet source surroundings (Just region)
2239 "I was not expecting to see this symbol here:"
2243 "I am not sure what is going wrong exactly, so here is a valid\
2244 \ definition (with an optional type annotation) for reference:"
2245 , D.indent 4 $ D.vcat $
2246 [ "greet : String -> String"
2248 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2251 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
2257 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2258 region = toRegion row col
2260 Report.Report "PROBLEM IN DEFINITION" region [] $
2261 Code.toSnippet source surroundings (Just region)
2264 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2268 "I am not sure what is going wrong exactly, so here is a valid\
2269 \ definition (with an optional type annotation) for reference:"
2270 , D.indent 4 $ D.vcat $
2271 [ "greet : String -> String"
2273 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2276 "Try to use that format!"
2280 DeclDefType tipe row col ->
2281 toTypeReport source (TC_Annotation name) tipe row col
2283 DeclDefArg pattern row col ->
2284 toPatternReport source PArg pattern row col
2286 DeclDefBody expr row col ->
2287 toExprReport source (InDef name startRow startCol) expr row col
2289 DeclDefNameRepeat row col ->
2291 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2292 region = toRegion row col
2294 Report.Report "EXPECTING DEFINITION" region [] $
2295 Code.toSnippet source surroundings (Just region)
2298 "I just saw the type annotation for `" ++ Name.toChars name
2299 ++ "` so I was expecting to see its definition here:"
2303 "Type annotations always appear directly above the relevant\
2304 \ definition, without anything else in between. (Not even doc comments!)"
2309 DeclDefNameMatch defName row col ->
2311 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2312 region = toRegion row col
2314 Report.Report "NAME MISMATCH" region [] $
2315 Code.toSnippet source surroundings (Just region)
2318 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
2322 "These names do not match! Is there a typo?"
2323 , D.indent 4 $ D.fillSep $
2324 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
2328 DeclDefIndentType row col ->
2330 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2331 region = toRegion row col
2333 Report.Report "UNFINISHED DEFINITION" region [] $
2334 Code.toSnippet source surroundings (Just region)
2337 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
2341 "I just saw a colon, so I am expecting to see a type next."
2346 DeclDefIndentEquals row col ->
2348 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2349 region = toRegion row col
2351 Report.Report "UNFINISHED DEFINITION" region [] $
2352 Code.toSnippet source surroundings (Just region)
2355 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2359 "I was expecting to see an argument or an equals sign next."
2364 DeclDefIndentBody row col ->
2366 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2367 region = toRegion row col
2369 Report.Report "UNFINISHED DEFINITION" region [] $
2370 Code.toSnippet source surroundings (Just region)
2373 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2377 "I was expecting to see an expression next. What is it equal to?"
2387 "Here is a valid definition (with a type annotation) for reference:"
2388 , D.indent 4 $ D.vcat $
2389 [ "greet : String -> String"
2391 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
2394 "The top line (called a \"type annotation\") is optional. You can leave it off\
2395 \ if you want. As you get more comfortable with Elm and as your project grows,\
2396 \ it becomes more and more valuable to add them though! They work great as\
2397 \ compiler-verified documentation, and they often improve error messages!"
2406 = InNode Node Row Col Context
2407 | InDef Name.Name Row Col
2408 | InDestruct Row Col
2424getDefName :: Context -> Maybe Name.Name
2427 InDestruct _ _ -> Nothing
2428 InDef name _ _ -> Just name
2429 InNode _ _ _ c -> getDefName c
2432isWithin :: Node -> Context -> Bool
2433isWithin desiredNode context =
2435 InDestruct _ _ -> False
2436 InDef _ _ _ -> False
2437 InNode actualNode _ _ _ -> desiredNode == actualNode
2444toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
2445toExprReport source context expr startRow startCol =
2448 toLetReport source context let_ row col
2450 Case case_ row col ->
2451 toCaseReport source context case_ row col
2454 toIfReport source context if_ row col
2456 List list row col ->
2457 toListReport source context list row col
2459 Record record row col ->
2460 toRecordReport source context record row col
2462 Tuple tuple row col ->
2463 toTupleReport source context tuple row col
2465 Func func row col ->
2466 toFuncReport source context func row col
2469 let region = toRegion row col in
2470 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2471 Code.toSnippet source region Nothing
2474 "I was expecting to see a record accessor here:"
2477 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2478 ,"that","accesses","a","value","from","a","record."
2483 let region = toRegion row col in
2484 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2485 Code.toSnippet source region Nothing
2488 "I am trying to parse a record accessor here:"
2493 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2494 ,"that","accesses","a","value","from","a","record."
2498 "Record field names must start with a lower case letter!"
2502 OperatorRight op row col ->
2504 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2505 region = toRegion row col
2506 isMath = elem op ["-","+","*","/","^"]
2508 Report.Report "MISSING EXPRESSION" region [] $
2509 Code.toSnippet source surroundings (Just region)
2512 "I just saw a " ++ Name.toChars op ++ " "
2513 ++ (if isMath then "sign" else "operator")
2514 ++ ", so I am getting stuck here:"
2518 ["I","was","expecting","to","see","an","expression","next."
2519 ,"Something","like",D.dullyellow "42","or",D.dullyellow "1000"
2520 ,"that","makes","sense","with","a",D.fromName op,"sign."
2522 else if op == "&&" || op == "||" then
2524 ["I","was","expecting","to","see","an","expression","next."
2525 ,"Something","like",D.dullyellow "True","or",D.dullyellow "False"
2526 ,"that","makes","sense","with","boolean","logic."
2528 else if op == "|>" then
2530 "I was expecting to see a function next."
2531 else if op == "<|" then
2533 "I was expecting to see an argument next."
2536 "I was expecting to see an expression next."
2539 OperatorReserved operator row col ->
2540 toOperatorReport source context operator row col
2544 (contextRow, contextCol, aThing) =
2546 InDestruct r c -> (r, c, "a definition")
2547 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
2548 InNode NRecord r c _ -> (r, c, "a record")
2549 InNode NParens r c _ -> (r, c, "some parentheses")
2550 InNode NList r c _ -> (r, c, "a list")
2551 InNode NFunc r c _ -> (r, c, "an anonymous function")
2552 InNode NCond r c _ -> (r, c, "an `if` expression")
2553 InNode NThen r c _ -> (r, c, "an `if` expression")
2554 InNode NElse r c _ -> (r, c, "an `if` expression")
2555 InNode NCase r c _ -> (r, c, "a `case` expression")
2556 InNode NBranch r c _ -> (r, c, "a `case` expression")
2558 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
2559 region = toRegion row col
2561 Report.Report "MISSING EXPRESSION" region [] $
2562 Code.toSnippet source surroundings (Just region)
2565 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
2569 ["I","was","expecting","to","see","an","expression","like"
2570 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2571 ,"Once","there","is","something","there,","I","can","probably"
2572 ,"give","a","more","specific","hint!"
2575 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
2576 \ Or if I run into operators in unexpected spots. Point is, there are a\
2577 \ couple ways I can get confused and give sort of weird advice!"
2581 Char char row col ->
2582 toCharReport source char row col
2584 String string row col ->
2585 toStringReport source string row col
2587 Number number row col ->
2588 toNumberReport source number row col
2590 Space space row col ->
2591 toSpaceReport source space row col
2593 EndlessShader row col ->
2595 region = toWiderRegion row col 6
2597 Report.Report "ENDLESS SHADER" region [] $
2598 Code.toSnippet source region Nothing
2600 D.reflow "I cannot find the end of this shader:"
2602 D.reflow "Add a |] somewhere after this to end the shader."
2605 ShaderProblem problem row col ->
2607 region = toRegion row col
2609 Report.Report "SHADER PROBLEM" region [] $
2610 Code.toSnippet source region Nothing
2613 "I ran into a problem while parsing this GLSL block."
2617 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
2618 , D.indent 4 $ D.vcat $
2619 map D.fromChars (filter (/="") (lines problem))
2623 IndentOperatorRight op row col ->
2625 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2626 region = toRegion row col
2628 Report.Report "MISSING EXPRESSION" region [] $
2629 Code.toSnippet source surroundings (Just region)
2632 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
2637 ["You","can","just","put","anything","for","now,","like"
2638 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2639 ,"Once","there","is","something","there,","I","can","probably"
2640 ,"give","a","more","specific","hint!"
2644 "I may be getting confused by your indentation? The easiest way to make sure\
2645 \ this is not an indentation problem is to put the expression on the right of\
2646 \ the " ++ Name.toChars op ++ " operator on the same line."
2655toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
2656toCharReport source char row col =
2660 region = toRegion row col
2662 Report.Report "MISSING SINGLE QUOTE" region [] $
2663 Code.toSnippet source region Nothing
2666 "I thought I was parsing a character, but I got to the end of\
2667 \ the line without seeing the closing single quote:"
2670 "Add a closing single quote here!"
2673 CharEscape escape ->
2674 toEscapeReport source escape row col
2676 CharNotString width ->
2678 region = toWiderRegion row col width
2680 Report.Report "NEEDS DOUBLE QUOTES" region [] $
2681 Code.toSnippet source region Nothing
2683 "The following string uses single quotes:"
2686 [ "Please switch to double quotes instead:"
2688 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
2690 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
2691 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
2692 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
2693 \ individual characters."
2702toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
2703toStringReport source string row col =
2705 StringEndless_Single ->
2707 region = toRegion row col
2709 Report.Report "ENDLESS STRING" region [] $
2710 Code.toSnippet source region Nothing
2713 "I got to the end of the line without seeing the closing double quote:"
2717 ["Strings","look","like",D.green "\"this\"","with","double"
2718 ,"quotes","on","each","end.","Is","the","closing","double"
2719 ,"quote","missing","in","your","code?"
2722 "For a string that spans multiple lines, you can use the multi-line string\
2723 \ syntax like this:"
2724 , D.dullyellow $ D.indent 4 $ D.vcat $
2726 , "# Multi-line Strings"
2728 , "- start with triple double quotes"
2729 , "- write whatever you want"
2730 , "- no need to escape newlines or double quotes"
2731 , "- end with triple double quotes"
2737 StringEndless_Multi ->
2739 region = toWiderRegion row col 3
2741 Report.Report "ENDLESS STRING" region [] $
2742 Code.toSnippet source region Nothing
2745 "I cannot find the end of this multi-line string:"
2748 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
2750 "Here is a valid multi-line string for reference:"
2751 , D.dullyellow $ D.indent 4 $ D.vcat $
2753 , "# Multi-line Strings"
2755 , "- start with triple double quotes"
2756 , "- write whatever you want"
2757 , "- no need to escape newlines or double quotes"
2758 , "- end with triple double quotes"
2764 StringEscape escape ->
2765 toEscapeReport source escape row col
2772toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
2773toEscapeReport source escape row col =
2777 region = toWiderRegion row col 2
2779 Report.Report "UNKNOWN ESCAPE" region [] $
2780 Code.toSnippet source region Nothing
2783 "Backslashes always start escaped characters, but I do not recognize this one:"
2787 "Valid escape characters include:"
2788 , D.dullyellow $ D.indent 4 $ D.vcat $
2798 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
2800 "The last style lets encode ANY character by its Unicode code\
2801 \ point. That means \\u{0009} and \\t are the same. You can use\
2802 \ that style for anything not covered by the other six escapes!"
2806 BadUnicodeFormat width ->
2808 region = toWiderRegion row col width
2810 Report.Report "BAD UNICODE ESCAPE" region [] $
2811 Code.toSnippet source region Nothing
2814 "I ran into an invalid Unicode escape:"
2818 "Here are some examples of valid Unicode escapes:"
2819 , D.dullyellow $ D.indent 4 $ D.vcat $
2826 "Notice that the code point is always surrounded by curly braces.\
2827 \ Maybe you are missing the opening or closing curly brace?"
2830 BadUnicodeCode width ->
2832 region = toWiderRegion row col width
2834 Report.Report "BAD UNICODE ESCAPE" region [] $
2835 Code.toSnippet source region Nothing
2838 "This is not a valid code point:"
2841 "The valid code points are between 0 and 10FFFF inclusive."
2844 BadUnicodeLength width numDigits badCode ->
2846 region = toWiderRegion row col width
2848 Report.Report "BAD UNICODE ESCAPE" region [] $
2849 Code.toSnippet source region Nothing $
2850 if numDigits < 4 then
2853 "Every code point needs at least four digits:"
2856 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
2857 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
2859 D.fillSep ["Try",D.green suggestion,"instead?"]
2865 "This code point has too many digits:"
2868 ["Valid","code","points","are","between"
2869 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
2870 ,"so","try","trimming","any","leading","zeros","until"
2871 ,"you","have","between","four","and","six","digits."
2880toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
2881toNumberReport source number row col =
2883 region = toRegion row col
2887 Report.Report "WEIRD NUMBER" region [] $
2888 Code.toSnippet source region Nothing
2891 "I thought I was reading a number, but I ran into some weird stuff here:"
2895 "I recognize numbers in the following formats:"
2896 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
2898 "So is there a way to write it like one of those?"
2903 Report.Report "WEIRD NUMBER" region [] $
2904 Code.toSnippet source region Nothing
2907 "Numbers cannot end with a dot like this:"
2910 ["Switching","to",D.green (D.fromChars (show int))
2911 ,"or",D.green (D.fromChars (show int ++ ".0"))
2912 ,"will","work","though!"
2917 Report.Report "WEIRD HEXIDECIMAL" region [] $
2918 Code.toSnippet source region Nothing
2921 "I thought I was reading a hexidecimal number until I got here:"
2925 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
2926 \ only recognize things like this:"
2927 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
2931 NumberNoLeadingZero ->
2932 Report.Report "LEADING ZEROS" region [] $
2933 Code.toSnippet source region Nothing
2936 "I do not accept numbers with leading zeros:"
2940 "Just delete the leading zeros and it should work!"
2942 "Some languages let you to specify octal numbers by adding a leading zero.\
2943 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
2944 \ that, but others probably want it to equal 111. Either path is going to\
2945 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
2955toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
2956toOperatorReport source context operator row col =
2960 region = toRegion row col
2962 Report.Report "UNEXPECTED SYMBOL" region [] $
2963 Code.toSnippet source region Nothing
2965 "I was not expecting this dot:"
2968 "Dots are for record access and decimal points, so\
2969 \ they cannot float around on their own. Maybe\
2970 \ there is some extra whitespace?"
2975 region = toRegion row col
2977 Report.Report "UNEXPECTED SYMBOL" region [] $
2978 Code.toSnippet source region Nothing
2981 "I was not expecting this vertical bar:"
2984 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
2989 region = toWiderRegion row col 2
2991 Report.Report "UNEXPECTED ARROW" region [] $
2992 Code.toSnippet source region Nothing $
2993 if isWithin NCase context then
2996 "I am parsing a `case` expression right now, but this arrow is confusing me:"
2999 [ D.reflow "Maybe the `of` keyword is missing on a previous line?"
3004 else if isWithin NBranch context then
3007 "I am parsing a `case` expression right now, but this arrow is confusing me:"
3011 "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?"
3012 , noteForCaseIndentError
3019 "I was partway through parsing an expression when I got stuck on this arrow:"
3022 [ "Arrows should only appear in `case` expressions and anonymous functions.\n\
3023 \Maybe it was supposed to be a > sign instead?"
3025 "The syntax for anonymous functions is (\\x -> x + 1) so the arguments all appear\
3026 \ after the backslash and before the arrow. Maybe a backslash is missing earlier?"
3032 region = toRegion row col
3034 Report.Report "UNEXPECTED EQUALS" region [] $
3035 Code.toSnippet source region Nothing
3038 "I was not expecting to see this equals sign:"
3042 D.reflow "Maybe you want == instead? To check if two values are equal?"
3045 if isWithin NRecord context then
3046 "Records look like { x = 3, y = 4 } with the equals sign right\
3047 \ after the field name. So maybe you forgot a comma?"
3049 case getDefName context of
3051 "I may be getting confused by your indentation. I need all definitions to be indented\
3052 \ exactly the same amount, so if this is meant to be a new definition, it may have too\
3053 \ many spaces in front of it."
3056 "I may be getting confused by your indentation. I think I am still parsing the `"
3057 ++ Name.toChars name ++ "` definition. Is this supposed to be part of a definition\
3058 \ after that? If so, the problem may be a bit before the equals sign. I need all\
3059 \ definitions to be indented exactly the same amount, so the problem may be that\
3060 \ this new definition has too many spaces in front of it."
3066 region = toRegion row col
3068 Report.Report "UNEXPECTED SYMBOL" region [] $
3069 Code.toSnippet source region Nothing $
3072 "I was not expecting to run into the \"has type\" symbol here:"
3074 case getDefName context of
3077 ["Maybe","you","want",D.green "::","instead?"
3078 ,"To","put","something","on","the","front","of","a","list?"
3085 ["Maybe","you","want",D.green "::","instead?"
3086 ,"To","put","something","on","the","front","of","a","list?"
3089 "The single colon is reserved for type annotations and record types, but I think\
3090 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
3093 "I may be getting confused by your indentation. Is this supposed to be part of\
3094 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
3095 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
3096 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
3097 \ this new definition is indented a bit too much."
3106toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
3107toLetReport source context let_ startRow startCol =
3109 LetSpace space row col ->
3110 toSpaceReport source space row col
3114 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3115 region = toRegion row col
3117 Report.Report "LET PROBLEM" region [] $
3118 Code.toSnippet source surroundings (Just region)
3121 "I was partway through parsing a `let` expression, but I got stuck here:"
3125 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
3126 ,"keyword","next.","Is","there","a","typo?"
3129 "This can also happen if you are trying to define another value within the `let` but\
3130 \ it is not indented enough. Make sure each definition has exactly the same amount of\
3131 \ spaces before it. They should line up exactly!"
3135 LetDefAlignment _ row col ->
3137 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3138 region = toRegion row col
3140 Report.Report "LET PROBLEM" region [] $
3141 Code.toSnippet source surroundings (Just region)
3144 "I was partway through parsing a `let` expression, but I got stuck here:"
3148 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
3149 ,"keyword","next.","Is","there","a","typo?"
3152 "This can also happen if you are trying to define another value within the `let` but\
3153 \ it is not indented enough. Make sure each definition has exactly the same amount of\
3154 \ spaces before it. They should line up exactly!"
3158 LetDefName row col ->
3159 case Code.whatIsNext source row col of
3160 Code.Keyword keyword ->
3162 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3163 region = toKeywordRegion row col keyword
3165 Report.Report "RESERVED WORD" region [] $
3166 Code.toSnippet source surroundings (Just region)
3169 "I was partway through parsing a `let` expression, but I got stuck here:"
3172 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
3173 \ it is a reserved word! Try using a different name instead."
3177 toUnfinishLetReport source row col startRow startCol $
3179 "I was expecting the name of a definition next."
3181 LetDef name def row col ->
3182 toLetDefReport source name def row col
3184 LetDestruct destruct row col ->
3185 toLetDestructReport source destruct row col
3187 LetBody expr row col ->
3188 toExprReport source context expr row col
3190 LetIndentDef row col ->
3191 toUnfinishLetReport source row col startRow startCol $
3193 "I was expecting a value to be defined here."
3195 LetIndentIn row col ->
3196 toUnfinishLetReport source row col startRow startCol $
3198 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
3199 ,"Or","maybe","more","of","that","expression?"
3202 LetIndentBody row col ->
3203 toUnfinishLetReport source row col startRow startCol $
3205 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
3208toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3209toUnfinishLetReport source row col startRow startCol message =
3211 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3212 region = toRegion row col
3214 Report.Report "UNFINISHED LET" region [] $
3215 Code.toSnippet source surroundings (Just region)
3218 "I was partway through parsing a `let` expression, but I got stuck here:"
3223 "Here is an example with a valid `let` expression for reference:"
3224 , D.indent 4 $ D.vcat $
3225 [ D.indent 0 $ D.fillSep ["viewPerson","person","="]
3226 , D.indent 2 $ D.fillSep [D.cyan "let"]
3227 , D.indent 4 $ D.fillSep ["fullName","="]
3228 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
3229 , D.indent 2 $ D.fillSep [D.cyan "in"]
3230 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
3233 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
3234 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
3235 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
3236 \ indented a bit more than that. That is important!"
3241toLetDefReport :: Code.Source -> Name.Name -> Def -> Row -> Col -> Report.Report
3242toLetDefReport source name def startRow startCol =
3244 DefSpace space row col ->
3245 toSpaceReport source space row col
3247 DefType tipe row col ->
3248 toTypeReport source (TC_Annotation name) tipe row col
3250 DefNameRepeat row col ->
3252 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3253 region = toRegion row col
3255 Report.Report "EXPECTING DEFINITION" region [] $
3256 Code.toSnippet source surroundings (Just region)
3259 "I just saw the type annotation for `" ++ Name.toChars name
3260 ++ "` so I was expecting to see its definition here:"
3264 "Type annotations always appear directly above the relevant\
3265 \ definition, without anything else in between."
3270 DefNameMatch defName row col ->
3272 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3273 region = toRegion row col
3275 Report.Report "NAME MISMATCH" region [] $
3276 Code.toSnippet source surroundings (Just region)
3279 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
3283 "These names do not match! Is there a typo?"
3284 , D.indent 4 $ D.fillSep $
3285 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
3289 DefArg pattern row col ->
3290 toPatternReport source PArg pattern row col
3292 DefEquals row col ->
3293 case Code.whatIsNext source row col of
3294 Code.Keyword keyword ->
3296 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3297 region = toKeywordRegion row col keyword
3299 Report.Report "RESERVED WORD" region [] $
3300 Code.toSnippet source surroundings (Just region)
3304 ,"`" <> D.cyan (D.fromChars keyword) <> "`"
3305 ,"is","reserved","in","Elm,","so","it","cannot"
3306 ,"be","used","as","an","argument","here:"
3311 "Try renaming it to something else."
3315 ["This","keyword","is","reserved","for","pattern","matches","like"
3316 ,"((x,y)",D.cyan "as","point)","where","you","want","to","name","a","tuple","and"
3317 ,"the","values","it","contains."
3322 "The `" ++ keyword ++ "` keyword has a special meaning in Elm, so it can only be used in certain situations."
3326 Code.Operator "->" ->
3328 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3329 region = toWiderRegion row col 2
3331 Report.Report "MISSING COLON?" region [] $
3332 Code.toSnippet source surroundings (Just region)
3335 "I was not expecting to see an arrow here:"
3339 ["This","usually","means","a",D.green ":","is","missing","a","bit","earlier","in"
3340 ,"a","type","annotation.","It","could","be","something","else","though,","so"
3341 ,"here","is","a","valid","definition","for","reference:"
3343 , D.indent 4 $ D.vcat $
3344 [ "greet : String -> String"
3346 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3349 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
3355 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3356 region = toKeywordRegion row col op
3358 Report.Report "UNEXPECTED SYMBOL" region [] $
3359 Code.toSnippet source surroundings (Just region)
3362 "I was not expecting to see this symbol here:"
3366 "I am not sure what is going wrong exactly, so here is a valid\
3367 \ definition (with an optional type annotation) for reference:"
3368 , D.indent 4 $ D.vcat $
3369 [ "greet : String -> String"
3371 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3374 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
3380 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3381 region = toRegion row col
3383 Report.Report "PROBLEM IN DEFINITION" region [] $
3384 Code.toSnippet source surroundings (Just region)
3387 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3391 "I am not sure what is going wrong exactly, so here is a valid\
3392 \ definition (with an optional type annotation) for reference:"
3393 , D.indent 4 $ D.vcat $
3394 [ "greet : String -> String"
3396 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3399 "Try to use that format!"
3403 DefBody expr row col ->
3404 toExprReport source (InDef name startRow startCol) expr row col
3406 DefIndentEquals row col ->
3408 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3409 region = toRegion row col
3411 Report.Report "UNFINISHED DEFINITION" region [] $
3412 Code.toSnippet source surroundings (Just region)
3415 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3419 "I was expecting to see an argument or an equals sign next."
3424 DefIndentType row col ->
3426 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3427 region = toRegion row col
3429 Report.Report "UNFINISHED DEFINITION" region [] $
3430 Code.toSnippet source surroundings (Just region)
3433 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
3437 "I just saw a colon, so I am expecting to see a type next."
3442 DefIndentBody row col ->
3444 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3445 region = toRegion row col
3447 Report.Report "UNFINISHED DEFINITION" region [] $
3448 Code.toSnippet source surroundings (Just region)
3451 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3455 "I was expecting to see an expression next. What is it equal to?"
3460 DefAlignment indent row col ->
3462 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3463 region = toRegion row col
3464 offset = indent - col
3466 Report.Report "PROBLEM IN DEFINITION" region [] $
3467 Code.toSnippet source surroundings (Just region)
3470 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3473 "I just saw a type annotation indented " ++ show indent ++ " spaces, so I was\
3474 \ expecting to see the corresponding definition next with the exact same amount\
3475 \ of indentation. It looks like this line needs "
3476 ++ show offset ++ " more " ++ (if offset == 1 then "space" else "spaces") ++ "?"
3485 "Here is a valid definition (with a type annotation) for reference:"
3486 , D.indent 4 $ D.vcat $
3487 [ "greet : String -> String"
3489 , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
3492 "The top line (called a \"type annotation\") is optional. You can leave it off\
3493 \ if you want. As you get more comfortable with Elm and as your project grows,\
3494 \ it becomes more and more valuable to add them though! They work great as\
3495 \ compiler-verified documentation, and they often improve error messages!"
3499toLetDestructReport :: Code.Source -> Destruct -> Row -> Col -> Report.Report
3500toLetDestructReport source destruct startRow startCol =
3502 DestructSpace space row col ->
3503 toSpaceReport source space row col
3505 DestructPattern pattern row col ->
3506 toPatternReport source PLet pattern row col
3508 DestructEquals row col ->
3510 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3511 region = toRegion row col
3513 Report.Report "PROBLEM IN DEFINITION" region [] $
3514 Code.toSnippet source surroundings (Just region)
3517 "I got stuck trying to parse this definition:"
3519 case Code.whatIsNext source row col of
3520 Code.Operator ":" ->
3523 "I was expecting to see an equals sign next, followed by an expression\
3524 \ telling me what to compute."
3526 "It looks like you may be trying to write a type annotation? It is not\
3527 \ possible to add type annotations on destructuring definitions like this.\
3528 \ You can assign a name to the overall structure, put a type annotation on\
3529 \ that, and then destructure separately though."
3534 "I was expecting to see an equals sign next, followed by an expression\
3535 \ telling me what to compute."
3538 DestructBody expr row col ->
3539 toExprReport source (InDestruct startRow startCol) expr row col
3541 DestructIndentEquals row col ->
3543 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3544 region = toRegion row col
3546 Report.Report "UNFINISHED DEFINITION" region [] $
3547 Code.toSnippet source surroundings (Just region)
3550 "I got stuck trying to parse this definition:"
3553 "I was expecting to see an equals sign next, followed by an expression\
3554 \ telling me what to compute."
3557 DestructIndentBody row col ->
3559 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3560 region = toRegion row col
3562 Report.Report "UNFINISHED DEFINITION" region [] $
3563 Code.toSnippet source surroundings (Just region)
3566 "I got stuck while parsing this definition:"
3569 "I was expecting to see an expression next. What is it equal to?"
3577toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
3578toCaseReport source context case_ startRow startCol =
3580 CaseSpace space row col ->
3581 toSpaceReport source space row col
3584 toUnfinishCaseReport source row col startRow startCol $
3585 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3587 CasePattern pattern row col ->
3588 toPatternReport source PCase pattern row col
3590 CaseArrow row col ->
3591 case Code.whatIsNext source row col of
3592 Code.Keyword keyword ->
3594 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3595 region = toKeywordRegion row col keyword
3597 Report.Report "RESERVED WORD" region [] $
3598 Code.toSnippet source surroundings (Just region)
3601 "I am partway through parsing a `case` expression, but I got stuck here:"
3604 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
3605 \ patterns, but it is a reserved word. Try using a different name?"
3608 Code.Operator ":" ->
3610 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3611 region = toRegion row col
3613 Report.Report "UNEXPECTED OPERATOR" region [] $
3614 Code.toSnippet source surroundings (Just region)
3617 "I am partway through parsing a `case` expression, but I got stuck here:"
3620 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
3621 ,"For","pattern","matching","on","lists?"
3625 Code.Operator "=" ->
3627 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3628 region = toRegion row col
3630 Report.Report "UNEXPECTED OPERATOR" region [] $
3631 Code.toSnippet source surroundings (Just region)
3634 "I am partway through parsing a `case` expression, but I got stuck here:"
3637 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
3643 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3644 region = toRegion row col
3646 Report.Report "MISSING ARROW" region [] $
3647 Code.toSnippet source surroundings (Just region)
3650 "I am partway through parsing a `case` expression, but I got stuck here:"
3653 [ D.reflow "I was expecting to see an arrow next."
3654 , noteForCaseIndentError
3658 CaseExpr expr row col ->
3659 toExprReport source (InNode NCase startRow startCol context) expr row col
3661 CaseBranch expr row col ->
3662 toExprReport source (InNode NBranch startRow startCol context) expr row col
3664 CaseIndentOf row col ->
3665 toUnfinishCaseReport source row col startRow startCol $
3666 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3668 CaseIndentExpr row col ->
3669 toUnfinishCaseReport source row col startRow startCol $
3670 D.reflow "I was expecting to see a expression next."
3672 CaseIndentPattern row col ->
3673 toUnfinishCaseReport source row col startRow startCol $
3674 D.reflow "I was expecting to see a pattern next."
3676 CaseIndentArrow row col ->
3677 toUnfinishCaseReport source row col startRow startCol $
3679 ["I","just","saw","a","pattern,","so","I","was","expecting"
3680 ,"to","see","a",D.dullyellow "->","next."
3683 CaseIndentBranch row col ->
3684 toUnfinishCaseReport source row col startRow startCol $
3686 "I was expecting to see an expression next. What should I do when\
3687 \ I run into this particular pattern?"
3689 CasePatternAlignment indent row col ->
3690 toUnfinishCaseReport source row col startRow startCol $
3692 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
3695toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3696toUnfinishCaseReport source row col startRow startCol message =
3698 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3699 region = toRegion row col
3701 Report.Report "UNFINISHED CASE" region [] $
3702 Code.toSnippet source surroundings (Just region)
3705 "I was partway through parsing a `case` expression, but I got stuck here:"
3714noteForCaseError :: D.Doc
3718 "Here is an example of a valid `case` expression for reference."
3720 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3721 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3722 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3724 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3725 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3728 "Notice the indentation. Each pattern is aligned, and each branch is indented\
3729 \ a bit more than the corresponding pattern. That is important!"
3733noteForCaseIndentError :: D.Doc
3734noteForCaseIndentError =
3737 "Sometimes I get confused by indentation, so try to make your `case` look\
3738 \ something like this:"
3740 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3741 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3742 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3744 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3745 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3748 "Notice the indentation! Patterns are aligned with each other. Same indentation.\
3749 \ The expressions after each arrow are all indented a bit more than the patterns.\
3750 \ That is important!"
3758toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
3759toIfReport source context if_ startRow startCol =
3761 IfSpace space row col ->
3762 toSpaceReport source space row col
3766 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3767 region = toRegion row col
3769 Report.Report "UNFINISHED IF" region [] $
3770 Code.toSnippet source surroundings (Just region)
3773 "I was expecting to see more of this `if` expression, but I got stuck here:"
3776 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3782 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3783 region = toRegion row col
3785 Report.Report "UNFINISHED IF" region [] $
3786 Code.toSnippet source surroundings (Just region)
3789 "I was expecting to see more of this `if` expression, but I got stuck here:"
3792 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
3796 IfElseBranchStart row col ->
3798 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3799 region = toRegion row col
3801 Report.Report "UNFINISHED IF" region [] $
3802 Code.toSnippet source surroundings (Just region)
3805 "I just saw the start of an `else` branch, but then I got stuck here:"
3808 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3811 IfCondition expr row col ->
3812 toExprReport source (InNode NCond startRow startCol context) expr row col
3814 IfThenBranch expr row col ->
3815 toExprReport source (InNode NThen startRow startCol context) expr row col
3817 IfElseBranch expr row col ->
3818 toExprReport source (InNode NElse startRow startCol context) expr row col
3820 IfIndentCondition row col ->
3822 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3823 region = toRegion row col
3825 Report.Report "UNFINISHED IF" region [] $
3826 Code.toSnippet source surroundings (Just region)
3829 "I was expecting to see more of this `if` expression, but I got stuck here:"
3833 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
3834 ,"that","evaluates","to","True","or","False."
3837 "I can be confused by indentation. Maybe something is not indented enough?"
3841 IfIndentThen row col ->
3843 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3844 region = toRegion row col
3846 Report.Report "UNFINISHED IF" region [] $
3847 Code.toSnippet source surroundings (Just region)
3850 "I was expecting to see more of this `if` expression, but I got stuck here:"
3854 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3857 "I can be confused by indentation. Maybe something is not indented enough?"
3861 IfIndentThenBranch row col ->
3863 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3864 region = toRegion row col
3866 Report.Report "UNFINISHED IF" region [] $
3867 Code.toSnippet source surroundings (Just region)
3870 "I got stuck after the start of this `then` branch:"
3874 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3876 "I can be confused by indentation, so if the `then` branch is already\
3877 \ present, it may not be indented enough for me to recognize it."
3881 IfIndentElseBranch row col ->
3883 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3884 region = toRegion row col
3886 Report.Report "UNFINISHED IF" region [] $
3887 Code.toSnippet source surroundings (Just region)
3890 "I got stuck after the start of this `else` branch:"
3894 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3896 "I can be confused by indentation, so if the `else` branch is already\
3897 \ present, it may not be indented enough for me to recognize it."
3901 IfIndentElse row col ->
3902 case Code.nextLineStartsWithKeyword "else" source row of
3903 Just (elseRow, elseCol) ->
3905 surroundings = A.Region (A.Position startRow startCol) (A.Position elseRow elseCol)
3906 region = toWiderRegion elseRow elseCol 4
3908 Report.Report "WEIRD ELSE BRANCH" region [] $
3909 Code.toSnippet source surroundings (Just region)
3912 "I was partway through an `if` expression when I got stuck here:"
3915 ["I","think","this",D.cyan "else","keyword","needs","to","be","indented","more."
3916 ,"Try","adding","some","spaces","before","it."
3922 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3923 region = toRegion row col
3925 Report.Report "UNFINISHED IF" region [] $
3926 Code.toSnippet source surroundings (Just region)
3929 "I was expecting to see an `else` branch after this:"
3933 ["I","know","what","to","do","when","the","condition","is","True,"
3934 ,"but","what","happens","when","it","is","False?"
3935 ,"Add","an",D.cyan "else","branch","to","handle","that","scenario!"
3945toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
3946toRecordReport source context record startRow startCol =
3948 RecordOpen row col ->
3949 case Code.whatIsNext source row col of
3950 Code.Keyword keyword ->
3952 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3953 region = toKeywordRegion row col keyword
3955 Report.Report "RESERVED WORD" region [] $
3956 Code.toSnippet source surroundings (Just region)
3959 "I just started parsing a record, but I got stuck on this field name:"
3962 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3963 \ that is a reserved word. Try using a different name!"
3968 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3969 region = toRegion row col
3971 Report.Report "PROBLEM IN RECORD" region [] $
3972 Code.toSnippet source surroundings (Just region)
3975 "I just started parsing a record, but I got stuck here:"
3979 ["I","was","expecting","to","see","a","record","field","defined","next,"
3980 ,"so","I","am","looking","for","a","name","like"
3981 ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
3984 "Field names must start with a lower-case letter. After that, you can use\
3985 \ any sequence of letters, numbers, and underscores."
3986 , noteForRecordError
3990 RecordEnd row col ->
3992 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3993 region = toRegion row col
3995 Report.Report "PROBLEM IN RECORD" region [] $
3996 Code.toSnippet source surroundings (Just region)
3999 "I am partway through parsing a record, but I got stuck here:"
4003 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
4004 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
4007 "When I get stuck like this, it usually means that there is a missing parenthesis\
4008 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4012 RecordField row col ->
4013 case Code.whatIsNext source row col of
4014 Code.Keyword keyword ->
4016 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4017 region = toKeywordRegion row col keyword
4019 Report.Report "RESERVED WORD" region [] $
4020 Code.toSnippet source surroundings (Just region)
4023 "I am partway through parsing a record, but I got stuck on this field name:"
4026 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
4027 \ that is a reserved word. Try using a different name!"
4030 Code.Other (Just ',') ->
4032 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4033 region = toRegion row col
4035 Report.Report "EXTRA COMMA" region [] $
4036 Code.toSnippet source surroundings (Just region)
4039 "I am partway through parsing a record, but I got stuck here:"
4043 "I am seeing two commas in a row. This is the second one!"
4045 "Just delete one of the commas and you should be all set!"
4046 , noteForRecordError
4052 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4053 region = toRegion row col
4055 Report.Report "EXTRA COMMA" region [] $
4056 Code.toSnippet source surroundings (Just region)
4059 "I am partway through parsing a record, but I got stuck here:"
4063 "Trailing commas are not allowed in records. Try deleting the comma that appears\
4064 \ before this closing curly brace."
4065 , noteForRecordError
4071 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4072 region = toRegion row col
4074 Report.Report "PROBLEM IN RECORD" region [] $
4075 Code.toSnippet source surroundings (Just region)
4078 "I am partway through parsing a record, but I got stuck here:"
4082 ["I","was","expecting","to","see","another","record","field","defined","next,"
4083 ,"so","I","am","looking","for","a","name","like"
4084 ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
4087 "Field names must start with a lower-case letter. After that, you can use\
4088 \ any sequence of letters, numbers, and underscores."
4089 , noteForRecordError
4093 RecordEquals row col ->
4095 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4096 region = toRegion row col
4098 Report.Report "PROBLEM IN RECORD" region [] $
4099 Code.toSnippet source surroundings (Just region)
4102 "I am partway through parsing a record, but I got stuck here:"
4106 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
4107 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
4109 , noteForRecordError
4113 RecordExpr expr row col ->
4114 toExprReport source (InNode NRecord startRow startCol context) expr row col
4116 RecordSpace space row col ->
4117 toSpaceReport source space row col
4119 RecordIndentOpen row col ->
4121 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4122 region = toRegion row col
4124 Report.Report "UNFINISHED RECORD" region [] $
4125 Code.toSnippet source surroundings (Just region)
4128 "I just saw the opening curly brace of a record, but then I got stuck here:"
4130 addNoteForRecordIndentError $
4132 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
4133 ,"Try","defining","some","fields","of","your","own?"
4137 RecordIndentEnd row col ->
4138 case Code.nextLineStartsWithCloseCurly source row of
4139 Just (curlyRow, curlyCol) ->
4141 surroundings = A.Region (A.Position startRow startCol) (A.Position curlyRow curlyCol)
4142 region = toRegion curlyRow curlyCol
4144 Report.Report "NEED MORE INDENTATION" region [] $
4145 Code.toSnippet source surroundings (Just region)
4148 "I was partway through parsing a record, but I got stuck here:"
4152 "I need this curly brace to be indented more. Try adding some spaces before it!"
4153 , noteForRecordError
4159 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4160 region = toRegion row col
4162 Report.Report "UNFINISHED RECORD" region [] $
4163 Code.toSnippet source surroundings (Just region)
4166 "I was partway through parsing a record, but I got stuck here:"
4168 addNoteForRecordIndentError $
4170 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4171 ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
4175 RecordIndentField row col ->
4177 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4178 region = toRegion row col
4180 Report.Report "UNFINISHED RECORD" region [] $
4181 Code.toSnippet source surroundings (Just region)
4184 "I am partway through parsing a record, but I got stuck after that last comma:"
4188 "Trailing commas are not allowed in records, so the fix may be to\
4189 \ delete that last comma? Or maybe you were in the middle of defining\
4190 \ an additional field?"
4191 , noteForRecordError
4195 RecordIndentEquals row col ->
4197 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4198 region = toRegion row col
4200 Report.Report "UNFINISHED RECORD" region [] $
4201 Code.toSnippet source surroundings (Just region)
4204 "I am partway through parsing a record. I just saw a record\
4205 \ field, so I was expecting to see an equals sign next:"
4207 addNoteForRecordIndentError $
4209 ["Try","putting","an",D.green "=","followed","by","an","expression?"
4213 RecordIndentExpr row col ->
4215 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4216 region = toRegion row col
4218 Report.Report "UNFINISHED RECORD" region [] $
4219 Code.toSnippet source surroundings (Just region)
4222 "I am partway through parsing a record, and I was expecting to run into an expression next:"
4224 addNoteForRecordIndentError $
4226 ["Try","putting","something","like"
4227 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
4232noteForRecordError :: D.Doc
4236 "If you are trying to define a record across multiple lines, I recommend using this format:"
4237 , D.indent 4 $ D.vcat $
4238 [ "{ name = " <> D.dullyellow "\"Alice\""
4239 , ", age = " <> D.dullyellow "42"
4240 , ", height = " <> D.dullyellow "1.75"
4244 "Notice that each line starts with some indentation. Usually two or four spaces.\
4245 \ This is the stylistic convention in the Elm ecosystem."
4249addNoteForRecordIndentError :: D.Doc -> D.Doc
4250addNoteForRecordIndentError normalRecommendation =
4252 normalRecommendation
4255 "I may be confused by indentation. For example, if you are trying to define\
4256 \ a record across multiple lines, I recommend using this format:"
4257 , D.indent 4 $ D.vcat $
4258 [ "{ name = " <> D.dullyellow "\"Alice\""
4259 , ", age = " <> D.dullyellow "42"
4260 , ", height = " <> D.dullyellow "1.75"
4264 "Notice that each line starts with some indentation. Usually two or four spaces.\
4265 \ This is the stylistic convention in the Elm ecosystem!"
4273toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
4274toTupleReport source context tuple startRow startCol =
4276 TupleExpr expr row col ->
4277 toExprReport source (InNode NParens startRow startCol context) expr row col
4279 TupleSpace space row col ->
4280 toSpaceReport source space row col
4284 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4285 region = toRegion row col
4287 Report.Report "UNFINISHED PARENTHESES" region [] $
4288 Code.toSnippet source surroundings (Just region)
4291 "I was expecting to see a closing parentheses next, but I got stuck here:"
4294 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
4296 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
4297 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
4298 \ or missing brackets) that is confusing me."
4302 TupleOperatorClose row col ->
4304 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4305 region = toRegion row col
4307 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
4308 Code.toSnippet source surroundings (Just region)
4310 D.reflow "I was expecting a closing parenthesis here:"
4313 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4315 "I think I am parsing an operator function right now, so I am expecting to see\
4316 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
4321 TupleOperatorReserved operator row col ->
4323 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4324 region = toRegion row col
4326 Report.Report "UNEXPECTED SYMBOL" region [] $
4327 Code.toSnippet source surroundings (Just region)
4330 "I ran into an unexpected symbol here:"
4334 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
4335 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
4336 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
4337 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
4338 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
4341 TupleIndentExpr1 row col ->
4343 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4344 region = toRegion row col
4346 Report.Report "UNFINISHED PARENTHESES" region [] $
4347 Code.toSnippet source surroundings (Just region)
4350 "I just saw an open parenthesis, so I was expecting to see an expression next."
4354 ["Something","like",D.dullyellow "(4 + 5)","or"
4355 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
4356 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
4359 "I can get confused by indentation in cases like this, so\
4360 \ maybe you have an expression but it is not indented enough?"
4364 TupleIndentExprN row col ->
4366 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4367 region = toRegion row col
4369 Report.Report "UNFINISHED TUPLE" region [] $
4370 Code.toSnippet source surroundings (Just region)
4373 "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."
4377 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
4378 ,D.dullyellow "(\"Tom\",42)" <> ","
4379 ,"so","I","think","there","is","an","expression","missing","here?"
4382 "I can get confused by indentation in cases like this, so\
4383 \ maybe you have an expression but it is not indented enough?"
4387 TupleIndentEnd row col ->
4389 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4390 region = toRegion row col
4392 Report.Report "UNFINISHED PARENTHESES" region [] $
4393 Code.toSnippet source surroundings (Just region)
4396 "I was expecting to see a closing parenthesis next:"
4399 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4401 "I can get confused by indentation in cases like this, so\
4402 \ maybe you have a closing parenthesis but it is not indented enough?"
4407toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
4408toListReport source context list startRow startCol =
4410 ListSpace space row col ->
4411 toSpaceReport source space row col
4415 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4416 region = toRegion row col
4418 Report.Report "UNFINISHED LIST" region [] $
4419 Code.toSnippet source surroundings (Just region)
4422 "I am partway through parsing a list, but I got stuck here:"
4426 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
4427 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4430 "When I get stuck like this, it usually means that there is a missing parenthesis\
4431 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4435 ListExpr expr row col ->
4439 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
4440 region = toRegion r c
4442 Report.Report "UNFINISHED LIST" region [] $
4443 Code.toSnippet source surroundings (Just region)
4446 "I was expecting to see another list entry after that last comma:"
4450 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4452 "I recommend using the following format for lists that span multiple lines:"
4453 , D.indent 4 $ D.vcat $
4454 [ "[ " <> D.dullyellow "\"Alice\""
4455 , ", " <> D.dullyellow "\"Bob\""
4456 , ", " <> D.dullyellow "\"Chuck\""
4460 "Notice that each line starts with some indentation. Usually two or four spaces.\
4461 \ This is the stylistic convention in the Elm ecosystem."
4466 toExprReport source (InNode NList startRow startCol context) expr row col
4470 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4471 region = toRegion row col
4473 Report.Report "UNFINISHED LIST" region [] $
4474 Code.toSnippet source surroundings (Just region)
4477 "I am partway through parsing a list, but I got stuck here:"
4481 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
4482 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4485 "When I get stuck like this, it usually means that there is a missing parenthesis\
4486 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4490 ListIndentOpen row col ->
4492 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4493 region = toRegion row col
4495 Report.Report "UNFINISHED LIST" region [] $
4496 Code.toSnippet source surroundings (Just region)
4499 "I cannot find the end of this list:"
4503 ["You","could","change","it","to","something","like"
4504 ,D.dullyellow "[3,4,5]"
4506 ,D.dullyellow "[]" <> "."
4507 ,"Anything","where","there","is","an","open","and","close","square","brace,"
4508 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
4511 "I may be confused by indentation. For example, if you are trying to define\
4512 \ a list across multiple lines, I recommend using this format:"
4513 , D.indent 4 $ D.vcat $
4514 [ "[ " <> D.dullyellow "\"Alice\""
4515 , ", " <> D.dullyellow "\"Bob\""
4516 , ", " <> D.dullyellow "\"Chuck\""
4520 "Notice that each line starts with some indentation. Usually two or four spaces.\
4521 \ This is the stylistic convention in the Elm ecosystem."
4525 ListIndentEnd row col ->
4527 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4528 region = toRegion row col
4530 Report.Report "UNFINISHED LIST" region [] $
4531 Code.toSnippet source surroundings (Just region)
4534 "I cannot find the end of this list:"
4538 ["You","can","just","add","a","closing",D.dullyellow "]"
4539 ,"right","here,","and","I","will","be","all","set!"
4542 "I may be confused by indentation. For example, if you are trying to define\
4543 \ a list across multiple lines, I recommend using this format:"
4544 , D.indent 4 $ D.vcat $
4545 [ "[ " <> D.dullyellow "\"Alice\""
4546 , ", " <> D.dullyellow "\"Bob\""
4547 , ", " <> D.dullyellow "\"Chuck\""
4551 "Notice that each line starts with some indentation. Usually two or four spaces.\
4552 \ This is the stylistic convention in the Elm ecosystem."
4556 ListIndentExpr row col ->
4558 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4559 region = toRegion row col
4561 Report.Report "UNFINISHED LIST" region [] $
4562 Code.toSnippet source surroundings (Just region)
4565 "I was expecting to see another list entry after this comma:"
4569 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4571 "I recommend using the following format for lists that span multiple lines:"
4572 , D.indent 4 $ D.vcat $
4573 [ "[ " <> D.dullyellow "\"Alice\""
4574 , ", " <> D.dullyellow "\"Bob\""
4575 , ", " <> D.dullyellow "\"Chuck\""
4579 "Notice that each line starts with some indentation. Usually two or four spaces.\
4580 \ This is the stylistic convention in the Elm ecosystem."
4585toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
4586toFuncReport source context func startRow startCol =
4588 FuncSpace space row col ->
4589 toSpaceReport source space row col
4591 FuncArg pattern row col ->
4592 toPatternReport source PArg pattern row col
4594 FuncBody expr row col ->
4595 toExprReport source (InNode NFunc startRow startCol context) expr row col
4597 FuncArrow row col ->
4598 case Code.whatIsNext source row col of
4599 Code.Keyword keyword ->
4601 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4602 region = toKeywordRegion row col keyword
4604 Report.Report "RESERVED WORD" region [] $
4605 Code.toSnippet source surroundings (Just region)
4608 "I was parsing an anonymous function, but I got stuck here:"
4611 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
4612 \ it is a reserved word in this language. Try using a different argument name!"
4617 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4618 region = toRegion row col
4620 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4621 Code.toSnippet source surroundings (Just region)
4624 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4627 ["The","syntax","for","anonymous","functions","is"
4628 ,D.dullyellow "(\\x -> x + 1)"
4629 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4633 FuncIndentArg row col ->
4635 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4636 region = toRegion row col
4638 Report.Report "MISSING ARGUMENT" region [] $
4639 Code.toSnippet source surroundings (Just region)
4642 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
4646 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
4647 ,"Anything","that","starts","with","a","lower","case","letter!"
4650 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
4651 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
4652 \ like a better idea at the time!"
4656 FuncIndentArrow row col ->
4658 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4659 region = toRegion row col
4661 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4662 Code.toSnippet source surroundings (Just region)
4665 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4669 ["The","syntax","for","anonymous","functions","is"
4670 ,D.dullyellow "(\\x -> x + 1)"
4671 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4674 "It is possible that I am confused about indetation! I generally recommend\
4675 \ switching to named functions if the definition cannot fit inline nicely, so\
4676 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4677 \ the whole thing out into a named function. Things tend to be clearer that way!"
4681 FuncIndentBody 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 was expecting to see the body of your anonymous function next:"
4694 ["The","syntax","for","anonymous","functions","is"
4695 ,D.dullyellow "(\\x -> x + 1)"
4696 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
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!"
4717toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
4718toPatternReport source context pattern startRow startCol =
4720 PRecord record row col ->
4721 toPRecordReport source record row col
4723 PTuple tuple row col ->
4724 toPTupleReport source context tuple row col
4726 PList list row col ->
4727 toPListReport source context list row col
4730 case Code.whatIsNext source row col of
4731 Code.Keyword keyword ->
4733 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4734 region = toKeywordRegion row col keyword
4737 PArg -> "as an argument"
4738 PCase -> "in this pattern"
4739 PLet -> "in this pattern"
4741 Report.Report "RESERVED WORD" region [] $
4742 Code.toSnippet source surroundings (Just region)
4745 "It looks like you are trying to use `" ++ keyword ++ "` " ++ inThisThing ++ ":"
4748 "This is a reserved word! Try using some other name?"
4751 Code.Operator "-" ->
4753 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4754 region = toRegion row col
4756 Report.Report "UNEXPECTED SYMBOL" region [] $
4757 Code.toSnippet source surroundings (Just region)
4760 "I ran into a minus sign unexpectedly in this pattern:"
4763 "It is not possible to pattern match on negative numbers at this\
4764 \ time. Try using an `if` expression for that sort of thing for now."
4769 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4770 region = toRegion row col
4772 Report.Report "PROBLEM IN PATTERN" region [] $
4773 Code.toSnippet source surroundings (Just region)
4776 "I wanted to parse a pattern next, but I got stuck here:"
4779 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4780 ,"I","just","know","that","I","want","a","pattern","next."
4781 ,"Something","as","simple","as"
4782 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4787 PChar char row col ->
4788 toCharReport source char row col
4790 PString string row col ->
4791 toStringReport source string row col
4793 PNumber number row col ->
4794 toNumberReport source number row col
4796 PFloat width row col ->
4798 region = toWiderRegion row col width
4800 Report.Report "UNEXPECTED PATTERN" region [] $
4801 Code.toSnippet source region Nothing
4804 "I cannot pattern match with floating point numbers:"
4807 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
4808 ,"to","check","that","they","are","nearby","with","some","sort","of"
4809 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
4815 region = toRegion row col
4817 Report.Report "UNFINISHED PATTERN" region [] $
4818 Code.toSnippet source region Nothing $
4821 "I was expecting to see a variable name after the `as` keyword:"
4825 ["The","`as`","keyword","lets","you","write","patterns","like"
4826 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4827 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4828 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4829 ,"thing","with",D.dullyellow "point" <> "."
4832 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4833 \ people just want to use `as` as a variable name though. Try using a different name\
4838 PWildcardNotVar name width row col ->
4840 region = toWiderRegion row col (fromIntegral width)
4842 case dropWhile (=='_') (Name.toChars name) of
4843 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
4844 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
4846 Report.Report "UNEXPECTED NAME" region [] $
4847 Code.toSnippet source region Nothing $
4850 "Variable names cannot start with underscores like this:"
4853 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
4854 ,"ignore","the","value,","or","you","can","have","a","name","like"
4855 ] ++ examples ++ ["to","use","the","matched","value." ]
4858 PSpace space row col ->
4859 toSpaceReport source space row col
4861 PIndentStart row col ->
4863 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4864 region = toRegion row col
4866 Report.Report "UNFINISHED PATTERN" region [] $
4867 Code.toSnippet source surroundings (Just region)
4870 "I wanted to parse a pattern next, but I got stuck here:"
4874 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4875 ,"I","just","know","that","I","want","a","pattern","next."
4876 ,"Something","as","simple","as"
4877 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4881 "I can get confused by indentation. If you think there is a pattern next, maybe\
4882 \ it needs to be indented a bit more?"
4886 PIndentAlias row col ->
4888 region = toRegion row col
4890 Report.Report "UNFINISHED PATTERN" region [] $
4891 Code.toSnippet source region Nothing $
4894 "I was expecting to see a variable name after the `as` keyword:"
4898 ["The","`as`","keyword","lets","you","write","patterns","like"
4899 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4900 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4901 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4902 ,"thing","with",D.dullyellow "point."
4905 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4906 \ people just want to use `as` as a variable name though. Try using a different name\
4912toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
4913toPRecordReport source record startRow startCol =
4915 PRecordOpen row col ->
4916 toUnfinishRecordPatternReport source row col startRow startCol $
4917 D.reflow "I was expecting to see a field name next."
4919 PRecordEnd row col ->
4920 toUnfinishRecordPatternReport source row col startRow startCol $
4922 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4923 ,"Try","adding","a",D.dullyellow "}","here?"
4926 PRecordField row col ->
4927 case Code.whatIsNext source row col of
4928 Code.Keyword keyword ->
4930 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4931 region = toKeywordRegion row col keyword
4933 Report.Report "RESERVED WORD" region [] $
4934 Code.toSnippet source surroundings (Just region)
4937 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
4940 "This is a reserved word, not available for variable names. Try another name!"
4944 toUnfinishRecordPatternReport source row col startRow startCol $
4945 D.reflow "I was expecting to see a field name next."
4947 PRecordSpace space row col ->
4948 toSpaceReport source space row col
4950 PRecordIndentOpen row col ->
4951 toUnfinishRecordPatternReport source row col startRow startCol $
4952 D.reflow "I was expecting to see a field name next."
4954 PRecordIndentEnd row col ->
4955 toUnfinishRecordPatternReport source row col startRow startCol $
4957 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4958 ,"Try","adding","a",D.dullyellow "}","here?"
4961 PRecordIndentField row col ->
4962 toUnfinishRecordPatternReport source row col startRow startCol $
4963 D.reflow "I was expecting to see a field name next."
4966toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
4967toUnfinishRecordPatternReport source row col startRow startCol message =
4969 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4970 region = toRegion row col
4972 Report.Report "UNFINISHED RECORD PATTERN" region [] $
4973 Code.toSnippet source surroundings (Just region)
4976 "I was partway through parsing a record pattern, but I got stuck here:"
4981 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
4982 ,"where","you","list","the","field","names","you","want","to","access."
4989toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
4990toPTupleReport source context tuple startRow startCol =
4992 PTupleOpen row col ->
4993 case Code.whatIsNext source row col of
4994 Code.Keyword keyword ->
4996 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4997 region = toKeywordRegion row col keyword
4999 Report.Report "RESERVED WORD" region [] $
5000 Code.toSnippet source surroundings (Just region)
5003 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
5006 "This is a reserved word! Try using some other name?"
5011 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5012 region = toRegion row col
5014 Report.Report "UNFINISHED PARENTHESES" region [] $
5015 Code.toSnippet source surroundings (Just region)
5018 "I just saw an open parenthesis, but I got stuck here:"
5021 ["I","was","expecting","to","see","a","pattern","next."
5022 ,"Maybe","it","will","end","up","being","something"
5023 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
5027 PTupleEnd row col ->
5028 case Code.whatIsNext source row col of
5029 Code.Keyword keyword ->
5031 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5032 region = toKeywordRegion row col keyword
5034 Report.Report "RESERVED WORD" region [] $
5035 Code.toSnippet source surroundings (Just region) $
5038 "I ran into a reserved word in this pattern:"
5041 "The `" ++ keyword ++ "` keyword is reserved. Try using a different name instead!"
5046 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5047 region = toKeywordRegion row col op
5049 Report.Report "UNEXPECTED SYMBOL" region [] $
5050 Code.toSnippet source surroundings (Just region) $
5053 "I ran into the " ++ op ++ " symbol unexpectedly in this pattern:"
5056 "Only the :: symbol that works in patterns. It is useful if you\
5057 \ are pattern matching on lists, trying to get the first element\
5058 \ off the front. Did you want that instead?"
5061 Code.Close term bracket ->
5063 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5064 region = toRegion row col
5066 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
5067 Code.toSnippet source surroundings (Just region) $
5070 "I ran into a an unexpected " ++ term ++ " in this pattern:"
5073 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
5078 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5079 region = toRegion row col
5081 Report.Report "UNFINISHED PARENTHESES" region [] $
5082 Code.toSnippet source surroundings (Just region) $
5085 "I was partway through parsing a pattern, but I got stuck here:"
5088 ["I","was","expecting","a","closing","parenthesis","next,","so"
5089 ,"try","adding","a",D.dullyellow ")","to","see","if","that","helps?"
5093 PTupleExpr pattern row col ->
5094 toPatternReport source context pattern row col
5096 PTupleSpace space row col ->
5097 toSpaceReport source space row col
5099 PTupleIndentEnd row col ->
5101 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5102 region = toRegion row col
5104 Report.Report "UNFINISHED PARENTHESES" region [] $
5105 Code.toSnippet source surroundings (Just region) $
5108 "I was expecting a closing parenthesis next:"
5111 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
5113 "I can get confused by indentation in cases like this, so\
5114 \ maybe you have a closing parenthesis but it is not indented enough?"
5118 PTupleIndentExpr1 row col ->
5120 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5121 region = toRegion row col
5123 Report.Report "UNFINISHED PARENTHESES" region [] $
5124 Code.toSnippet source surroundings (Just region) $
5127 "I just saw an open parenthesis, but then I got stuck here:"
5130 ["I","was","expecting","to","see","a","pattern","next."
5131 ,"Maybe","it","will","end","up","being","something"
5132 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
5136 PTupleIndentExprN row col ->
5138 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5139 region = toRegion row col
5141 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
5142 Code.toSnippet source surroundings (Just region) $
5145 "I am partway through parsing a tuple pattern, but I got stuck here:"
5149 ["I","was","expecting","to","see","a","pattern","next."
5150 ,"I","am","expecting","the","final","result","to","be","something"
5151 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
5154 "I can get confused by indentation in cases like this, so the problem\
5155 \ may be that the next part is not indented enough?"
5160toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
5161toPListReport source context list startRow startCol =
5163 PListOpen row col ->
5164 case Code.whatIsNext source row col of
5165 Code.Keyword keyword ->
5167 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5168 region = toKeywordRegion row col keyword
5170 Report.Report "RESERVED WORD" region [] $
5171 Code.toSnippet source surroundings (Just region)
5174 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
5177 "This is a reserved word though! Try using some other name?"
5182 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5183 region = toRegion row col
5185 Report.Report "UNFINISHED LIST PATTERN" region [] $
5186 Code.toSnippet source surroundings (Just region) $
5189 "I just saw an open square bracket, but then I got stuck here:"
5191 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5196 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5197 region = toRegion row col
5199 Report.Report "UNFINISHED LIST PATTERN" region [] $
5200 Code.toSnippet source surroundings (Just region) $
5203 "I was expecting a closing square bracket to end this list pattern:"
5205 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5208 PListExpr pattern row col ->
5209 toPatternReport source context pattern row col
5211 PListSpace space row col ->
5212 toSpaceReport source space row col
5214 PListIndentOpen row col ->
5216 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5217 region = toRegion row col
5219 Report.Report "UNFINISHED LIST PATTERN" region [] $
5220 Code.toSnippet source surroundings (Just region) $
5223 "I just saw an open square bracket, but then I got stuck here:"
5226 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5228 "I can get confused by indentation in cases like this, so\
5229 \ maybe there is something next, but it is not indented enough?"
5233 PListIndentEnd row col ->
5235 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5236 region = toRegion row col
5238 Report.Report "UNFINISHED LIST PATTERN" region [] $
5239 Code.toSnippet source surroundings (Just region) $
5242 "I was expecting a closing square bracket to end this list pattern:"
5245 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
5247 "I can get confused by indentation in cases like this, so\
5248 \ maybe you have a closing square bracket but it is not indented enough?"
5252 PListIndentExpr row col ->
5254 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5255 region = toRegion row col
5257 Report.Report "UNFINISHED LIST PATTERN" region [] $
5258 Code.toSnippet source surroundings (Just region) $
5261 "I am partway through parsing a list pattern, but I got stuck here:"
5265 "I was expecting to see another pattern next. Maybe a variable name."
5267 "I can get confused by indentation in cases like this, so\
5268 \ maybe there is more to this pattern but it is not indented enough?"
5278 = TC_Annotation Name.Name
5284toTypeReport :: Code.Source -> TContext -> Type -> Row -> Col -> Report.Report
5285toTypeReport source context tipe startRow startCol =
5287 TRecord record row col ->
5288 toTRecordReport source context record row col
5290 TTuple tuple row col ->
5291 toTTupleReport source context tuple row col
5294 case Code.whatIsNext source row col of
5295 Code.Keyword keyword ->
5297 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5298 region = toKeywordRegion row col keyword
5300 Report.Report "RESERVED WORD" region [] $
5301 Code.toSnippet source surroundings (Just region)
5304 "I was expecting to see a type next, but I got stuck on this reserved word:"
5307 "It looks like you are trying to use `" ++ keyword ++ "` as a type variable, but \
5308 \ it is a reserved word. Try using a different name!"
5313 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5314 region = toRegion row col
5318 TC_Annotation _ -> "type annotation"
5319 TC_CustomType -> "custom type"
5320 TC_TypeAlias -> "type alias"
5325 TC_Annotation name -> "the `" ++ Name.toChars name ++ "` type annotation"
5326 TC_CustomType -> "a custom type"
5327 TC_TypeAlias -> "a type alias"
5330 Report.Report ("PROBLEM IN " ++ map Char.toUpper thing) region [] $
5331 Code.toSnippet source surroundings (Just region)
5334 "I was partway through parsing " ++ something ++ ", but I got stuck here:"
5337 ["I","was","expecting","to","see","a","type","next."
5338 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5342 TSpace space row col ->
5343 toSpaceReport source space row col
5345 TIndentStart row col ->
5347 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5348 region = toRegion row col
5352 TC_Annotation _ -> "type annotation"
5353 TC_CustomType -> "custom type"
5354 TC_TypeAlias -> "type alias"
5357 Report.Report ("UNFINISHED " ++ map Char.toUpper thing) region [] $
5358 Code.toSnippet source surroundings (Just region)
5361 "I was partway through parsing a " ++ thing ++ ", but I got stuck here:"
5365 ["I","was","expecting","to","see","a","type","next."
5366 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5369 "I can get confused by indentation. If you think there is already a type\
5370 \ next, maybe it is not indented enough?"
5375toTRecordReport :: Code.Source -> TContext -> TRecord -> Row -> Col -> Report.Report
5376toTRecordReport source context record startRow startCol =
5378 TRecordOpen row col ->
5379 case Code.whatIsNext source row col of
5380 Code.Keyword keyword ->
5382 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5383 region = toKeywordRegion row col keyword
5385 Report.Report "RESERVED WORD" region [] $
5386 Code.toSnippet source surroundings (Just region)
5389 "I just started parsing a record type, but I got stuck on this field name:"
5392 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
5393 \ that is a reserved word. Try using a different name!"
5398 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5399 region = toRegion row col
5401 Report.Report "UNFINISHED RECORD TYPE" region [] $
5402 Code.toSnippet source surroundings (Just region)
5405 "I just started parsing a record type, but I got stuck here:"
5408 ["Record","types","look","like",D.dullyellow "{ name : String, age : Int },"
5409 ,"so","I","was","expecting","to","see","a","field","name","next."
5413 TRecordEnd row col ->
5415 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5416 region = toRegion row col
5418 Report.Report "UNFINISHED RECORD TYPE" region [] $
5419 Code.toSnippet source surroundings (Just region)
5422 "I am partway through parsing a record type, but I got stuck here:"
5426 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
5427 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
5430 "When I get stuck like this, it usually means that there is a missing parenthesis\
5431 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
5435 TRecordField row col ->
5436 case Code.whatIsNext source row col of
5437 Code.Keyword keyword ->
5439 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5440 region = toKeywordRegion row col keyword
5442 Report.Report "RESERVED WORD" region [] $
5443 Code.toSnippet source surroundings (Just region)
5446 "I am partway through parsing a record type, but I got stuck on this field name:"
5449 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
5450 \ that is a reserved word. Try using a different name!"
5453 Code.Other (Just ',') ->
5455 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5456 region = toRegion row col
5458 Report.Report "EXTRA COMMA" region [] $
5459 Code.toSnippet source surroundings (Just region)
5462 "I am partway through parsing a record type, but I got stuck here:"
5466 "I am seeing two commas in a row. This is the second one!"
5468 "Just delete one of the commas and you should be all set!"
5469 , noteForRecordTypeError
5475 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5476 region = toRegion row col
5478 Report.Report "EXTRA COMMA" region [] $
5479 Code.toSnippet source surroundings (Just region)
5482 "I am partway through parsing a record type, but I got stuck here:"
5486 "Trailing commas are not allowed in record types. Try deleting the comma that\
5487 \ appears before this closing curly brace."
5488 , noteForRecordTypeError
5494 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5495 region = toRegion row col
5497 Report.Report "PROBLEM IN RECORD TYPE" region [] $
5498 Code.toSnippet source surroundings (Just region)
5501 "I am partway through parsing a record type, but I got stuck here:"
5505 ["I","was","expecting","to","see","another","record","field","defined","next,"
5506 ,"so","I","am","looking","for","a","name","like"
5507 ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
5509 , noteForRecordTypeError
5513 TRecordColon row col ->
5515 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5516 region = toRegion row col
5518 Report.Report "UNFINISHED RECORD TYPE" region [] $
5519 Code.toSnippet source surroundings (Just region)
5522 "I am partway through parsing a record type, but I got stuck here:"
5526 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
5527 ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
5529 , noteForRecordTypeError
5533 TRecordType tipe row col ->
5534 toTypeReport source context tipe row col
5536 TRecordSpace space row col ->
5537 toSpaceReport source space row col
5539 TRecordIndentOpen row col ->
5541 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5542 region = toRegion row col
5544 Report.Report "UNFINISHED RECORD TYPE" region [] $
5545 Code.toSnippet source surroundings (Just region)
5548 "I just saw the opening curly brace of a record type, but then I got stuck here:"
5552 ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
5553 ,"Try","defining","some","fields","of","your","own?"
5555 , noteForRecordTypeIndentError
5559 TRecordIndentEnd row col ->
5560 case Code.nextLineStartsWithCloseCurly source row of
5561 Just (curlyRow, curlyCol) ->
5563 surroundings = A.Region (A.Position startRow startCol) (A.Position curlyRow curlyCol)
5564 region = toRegion curlyRow curlyCol
5566 Report.Report "NEED MORE INDENTATION" region [] $
5567 Code.toSnippet source surroundings (Just region)
5570 "I was partway through parsing a record type, but I got stuck here:"
5574 "I need this curly brace to be indented more. Try adding some spaces before it!"
5575 , noteForRecordTypeError
5581 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5582 region = toRegion row col
5584 Report.Report "UNFINISHED RECORD TYPE" region [] $
5585 Code.toSnippet source surroundings (Just region)
5588 "I was partway through parsing a record type, but I got stuck here:"
5592 ["I","was","expecting","to","see","a","closing","curly","brace","next."
5593 ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
5595 , noteForRecordTypeIndentError
5599 TRecordIndentField row col ->
5601 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5602 region = toRegion row col
5604 Report.Report "UNFINISHED RECORD TYPE" region [] $
5605 Code.toSnippet source surroundings (Just region)
5608 "I am partway through parsing a record type, but I got stuck after that last comma:"
5612 "Trailing commas are not allowed in record types, so the fix may be to\
5613 \ delete that last comma? Or maybe you were in the middle of defining\
5614 \ an additional field?"
5615 , noteForRecordTypeIndentError
5619 TRecordIndentColon row col ->
5621 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5622 region = toRegion row col
5624 Report.Report "UNFINISHED RECORD TYPE" region [] $
5625 Code.toSnippet source surroundings (Just region)
5628 "I am partway through parsing a record type. I just saw a record\
5629 \ field, so I was expecting to see a colon next:"
5633 ["Try","putting","an",D.green ":","followed","by","a","type?"
5635 , noteForRecordTypeIndentError
5639 TRecordIndentType row col ->
5641 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5642 region = toRegion row col
5644 Report.Report "UNFINISHED RECORD TYPE" region [] $
5645 Code.toSnippet source surroundings (Just region)
5648 "I am partway through parsing a record type, and I was expecting to run into a type next:"
5652 ["Try","putting","something","like"
5653 ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5655 , noteForRecordTypeIndentError
5660noteForRecordTypeError :: D.Doc
5661noteForRecordTypeError =
5664 "If you are trying to define a record type across multiple lines, I recommend using this format:"
5665 , D.indent 4 $ D.vcat $
5668 , ", height : Float"
5672 "Notice that each line starts with some indentation. Usually two or four spaces.\
5673 \ This is the stylistic convention in the Elm ecosystem."
5677noteForRecordTypeIndentError :: D.Doc
5678noteForRecordTypeIndentError =
5681 "I may be confused by indentation. For example, if you are trying to define\
5682 \ a record type across multiple lines, I recommend using this format:"
5683 , D.indent 4 $ D.vcat $
5686 , ", height : Float"
5690 "Notice that each line starts with some indentation. Usually two or four spaces.\
5691 \ This is the stylistic convention in the Elm ecosystem."
5695toTTupleReport :: Code.Source -> TContext -> TTuple -> Row -> Col -> Report.Report
5696toTTupleReport source context tuple startRow startCol =
5698 TTupleOpen row col ->
5699 case Code.whatIsNext source row col of
5700 Code.Keyword keyword ->
5702 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5703 region = toKeywordRegion row col keyword
5705 Report.Report "RESERVED WORD" region [] $
5706 Code.toSnippet source surroundings (Just region)
5709 "I ran into a reserved word unexpectedly:"
5712 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but \
5713 \ it is a reserved word. Try using a different name!"
5718 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5719 region = toRegion row col
5721 Report.Report "UNFINISHED PARENTHESES" region [] $
5722 Code.toSnippet source surroundings (Just region)
5725 "I just saw an open parenthesis, so I was expecting to see a type next."
5728 ["Something","like",D.dullyellow "(Maybe Int)","or"
5729 ,D.dullyellow "(List Person)" <> "."
5730 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5734 TTupleEnd row col ->
5736 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5737 region = toRegion row col
5739 Report.Report "UNFINISHED PARENTHESES" region [] $
5740 Code.toSnippet source surroundings (Just region)
5743 "I was expecting to see a closing parenthesis next, but I got stuck here:"
5746 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
5748 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
5749 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
5750 \ or missing brackets) that is confusing me."
5754 TTupleType tipe row col ->
5755 toTypeReport source context tipe row col
5757 TTupleSpace space row col ->
5758 toSpaceReport source space row col
5760 TTupleIndentType1 row col ->
5762 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5763 region = toRegion row col
5765 Report.Report "UNFINISHED PARENTHESES" region [] $
5766 Code.toSnippet source surroundings (Just region)
5769 "I just saw an open parenthesis, so I was expecting to see a type next."
5773 ["Something","like",D.dullyellow "(Maybe Int)","or"
5774 ,D.dullyellow "(List Person)" <> "."
5775 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5778 "I can get confused by indentation in cases like this, so\
5779 \ maybe you have a type but it is not indented enough?"
5783 TTupleIndentTypeN row col ->
5785 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5786 region = toRegion row col
5788 Report.Report "UNFINISHED TUPLE TYPE" region [] $
5789 Code.toSnippet source surroundings (Just region)
5792 "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."
5796 ["A","tuple","type","looks","like",D.dullyellow "(Float,Float)","or"
5797 ,D.dullyellow "(String,Int)" <> ","
5798 ,"so","I","think","there","is","a","type","missing","here?"
5801 "I can get confused by indentation in cases like this, so\
5802 \ maybe you have an expression but it is not indented enough?"
5806 TTupleIndentEnd row col ->
5808 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5809 region = toRegion row col
5811 Report.Report "UNFINISHED PARENTHESES" region [] $
5812 Code.toSnippet source surroundings (Just region)
5815 "I was expecting to see a closing parenthesis next:"
5818 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
5820 "I can get confused by indentation in cases like this, so\
5821 \ 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