1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Syntax
47import Prelude hiding (Char, String)
48import qualified Data.Char as Char
49import qualified Data.Name as Name
50import Data.Word (Word16)
51import Numeric (showHex)
53import qualified Elm.ModuleName as ModuleName
54import Parse.Primitives (Row, Col)
55import Parse.Symbol (BadOperator(..))
56import qualified Reporting.Annotation as A
57import qualified Reporting.Doc as D
58import qualified Reporting.Report as Report
59import qualified Reporting.Render.Code as Code
67 = ModuleNameUnspecified ModuleName.Raw
68 | ModuleNameMismatch ModuleName.Raw (A.Located ModuleName.Raw)
69 | UnexpectedPort A.Region
79 = ModuleSpace Space Row Col
80 | ModuleBadEnd Row Col
82 | ModuleProblem Row Col
84 | ModuleExposing Exposing Row Col
86 | PortModuleProblem Row Col
87 | PortModuleName Row Col
88 | PortModuleExposing Exposing Row Col
98 | ImportExposing Row Col
99 | ImportExposingList Exposing Row Col
100 | ImportEnd Row Col -- different based on col=1 or if greater
102 | ImportIndentName Row Col
103 | ImportIndentAlias Row Col
104 | ImportIndentExposingList Row Col
108 | Declarations Decl Row Col
112 = ExposingSpace Space Row Col
113 | ExposingStart Row Col
114 | ExposingValue Row Col
115 | ExposingOperator Row Col
116 | ExposingOperatorReserved BadOperator Row Col
117 | ExposingOperatorRightParen Row Col
118 | ExposingTypePrivacy Row Col
119 | ExposingEnd Row Col
121 | ExposingIndentEnd Row Col
122 | ExposingIndentValue Row Col
131 | DeclSpace Space Row Col
134 | DeclType DeclType Row Col
135 | DeclDef Name.Name DeclDef Row Col
137 | DeclFreshLineAfterDocComment Row Col
141 = DeclDefSpace Space Row Col
142 | DeclDefEquals Row Col
143 | DeclDefType Type Row Col
144 | DeclDefArg Pattern Row Col
145 | DeclDefBody Expr Row Col
146 | DeclDefNameRepeat Row Col
147 | DeclDefNameMatch Name.Name Row Col
149 | DeclDefIndentType Row Col
150 | DeclDefIndentEquals Row Col
151 | DeclDefIndentBody Row Col
155 = PortSpace Space Row Col
158 | PortType Type Row Col
159 | PortIndentName Row Col
160 | PortIndentColon Row Col
161 | PortIndentType Row Col
169 = DT_Space Space Row Col
171 | DT_Alias TypeAlias Row Col
172 | DT_Union CustomType Row Col
174 | DT_IndentName Row Col
178 = AliasSpace Space Row Col
180 | AliasEquals Row Col
181 | AliasBody Type Row Col
183 | AliasIndentEquals Row Col
184 | AliasIndentBody Row Col
188 = CT_Space Space Row Col
193 | CT_VariantArg Type Row Col
195 | CT_IndentEquals Row Col
196 | CT_IndentBar Row Col
197 | CT_IndentAfterBar Row Col
198 | CT_IndentAfterEquals Row Col
210 | Record Record Row Col
211 | Tuple Tuple Row Col
216 | OperatorRight Name.Name Row Col
217 | OperatorReserved BadOperator Row Col
221 | String String Row Col
222 | Number Number Row Col
223 | Space Space Row Col
224 | EndlessShader Row Col
225 | ShaderProblem [Char.Char] Row Col
226 | IndentOperatorRight Name.Name Row Col
232 | RecordField Row Col
233 | RecordEquals Row Col
234 | RecordExpr Expr Row Col
235 | RecordSpace Space Row Col
237 | RecordIndentOpen Row Col
238 | RecordIndentEnd Row Col
239 | RecordIndentField Row Col
240 | RecordIndentEquals Row Col
241 | RecordIndentExpr Row Col
245 = TupleExpr Expr Row Col
246 | TupleSpace Space Row Col
248 | TupleOperatorClose Row Col
249 | TupleOperatorReserved BadOperator Row Col
251 | TupleIndentExpr1 Row Col
252 | TupleIndentExprN Row Col
253 | TupleIndentEnd Row Col
257 = ListSpace Space Row Col
259 | ListExpr Expr Row Col
262 | ListIndentOpen Row Col
263 | ListIndentEnd Row Col
264 | ListIndentExpr Row Col
268 = FuncSpace Space Row Col
269 | FuncArg Pattern Row Col
270 | FuncBody Expr Row Col
273 | FuncIndentArg Row Col
274 | FuncIndentArrow Row Col
275 | FuncIndentBody Row Col
279 = CaseSpace Space Row Col
281 | CasePattern Pattern Row Col
283 | CaseExpr Expr Row Col
284 | CaseBranch Expr Row Col
286 | CaseIndentOf Row Col
287 | CaseIndentExpr Row Col
288 | CaseIndentPattern Row Col
289 | CaseIndentArrow Row Col
290 | CaseIndentBranch Row Col
291 | CasePatternAlignment Word16 Row Col
295 = IfSpace Space Row Col
298 | IfElseBranchStart Row Col
300 | IfCondition Expr Row Col
301 | IfThenBranch Expr Row Col
302 | IfElseBranch Expr Row Col
304 | IfIndentCondition Row Col
305 | IfIndentThen Row Col
306 | IfIndentThenBranch Row Col
307 | IfIndentElseBranch Row Col
308 | IfIndentElse Row Col
312 = LetSpace Space Row Col
314 | LetDefAlignment Word16 Row Col
316 | LetDef Name.Name Def Row Col
317 | LetDestruct Destruct Row Col
318 | LetBody Expr Row Col
319 | LetIndentDef Row Col
320 | LetIndentIn Row Col
321 | LetIndentBody Row Col
325 = DefSpace Space Row Col
326 | DefType Type Row Col
327 | DefNameRepeat Row Col
328 | DefNameMatch Name.Name Row Col
329 | DefArg Pattern Row Col
331 | DefBody Expr Row Col
332 | DefIndentEquals Row Col
333 | DefIndentType Row Col
334 | DefIndentBody Row Col
335 | DefAlignment Word16 Row Col
339 = DestructSpace Space Row Col
340 | DestructPattern Pattern Row Col
341 | DestructEquals Row Col
342 | DestructBody Expr Row Col
343 | DestructIndentEquals Row Col
344 | DestructIndentBody Row Col
352 = PRecord PRecord Row Col
353 | PTuple PTuple Row Col
354 | PList PList Row Col
358 | PString String Row Col
359 | PNumber Number Row Col
360 | PFloat Word16 Row Col
362 | PWildcardNotVar Name.Name Int Row Col
363 | PSpace Space Row Col
365 | PIndentStart Row Col
366 | PIndentAlias Row Col
370 = PRecordOpen Row Col
372 | PRecordField Row Col
373 | PRecordSpace Space Row Col
375 | PRecordIndentOpen Row Col
376 | PRecordIndentEnd Row Col
377 | PRecordIndentField Row Col
383 | PTupleExpr Pattern Row Col
384 | PTupleSpace Space Row Col
386 | PTupleIndentEnd Row Col
387 | PTupleIndentExpr1 Row Col
388 | PTupleIndentExprN Row Col
394 | PListExpr Pattern Row Col
395 | PListSpace Space Row Col
397 | PListIndentOpen Row Col
398 | PListIndentEnd Row Col
399 | PListIndentExpr Row Col
407 = TRecord TRecord Row Col
408 | TTuple TTuple Row Col
411 | TSpace Space Row Col
413 | TIndentStart Row Col
417 = TRecordOpen Row Col
420 | TRecordField Row Col
421 | TRecordColon Row Col
422 | TRecordType Type Row Col
424 | TRecordSpace Space Row Col
426 | TRecordIndentOpen Row Col
427 | TRecordIndentField Row Col
428 | TRecordIndentColon Row Col
429 | TRecordIndentType Row Col
430 | TRecordIndentEnd Row Col
436 | TTupleType Type Row Col
437 | TTupleSpace Space Row Col
439 | TTupleIndentType1 Row Col
440 | TTupleIndentTypeN Row Col
441 | TTupleIndentEnd Row Col
451 | CharNotString Word16
455 = StringEndless_Single
456 | StringEndless_Multi
457 | StringEscape Escape
462 | BadUnicodeFormat Word16
463 | BadUnicodeCode Word16
464 | BadUnicodeLength Word16 Int Int
471 | NumberNoLeadingZero
480 | EndlessMultiComment
487toReport :: Code.Source -> Error -> Report.Report
490 ModuleNameUnspecified name ->
492 region = toRegion 1 1
494 Report.Report "MODULE NAME MISSING" region [] $
497 "I need the module name to be declared at the top of this file, like this:"
498 , D.indent 4 $ D.fillSep $
499 [ D.cyan "module", D.fromName name, D.cyan "exposing", "(..)" ]
501 "Try adding that as the first line of your file!"
503 "It is best to replace (..) with an explicit list of types and\
504 \ functions you want to expose. When you know a value is only used\
505 \ within this module, you can refactor without worrying about uses\
506 \ elsewhere. Limiting exposed values can also speed up compilation\
507 \ because I can skip a bunch of work if I see that the exposed API\
511 ModuleNameMismatch expectedName (A.At region actualName) ->
512 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
513 Code.toSnippet source region Nothing
515 "It looks like this module name is out of sync:"
519 "I need it to match the file path, so I was expecting it to see `"
520 ++ ModuleName.toChars expectedName
521 ++ "` here. Make the following change, and you should be all set!"
523 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
525 "I require that module names correspond to file paths. This makes it much\
526 \ easier to explore unfamiliar codebases! So if you want to keep the current\
527 \ module name, try renaming the file instead."
531 UnexpectedPort region ->
532 Report.Report "UNEXPECTED PORTS" region [] $
533 Code.toSnippet source region Nothing
536 "You are declaring ports in a normal module."
540 ["Switch","this","to","say",D.cyan "port module","instead,"
541 ,"marking","that","this","module","contains","port","declarations."
544 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
546 "to learn the syntax and how to use it effectively."
551 Report.Report "NO PORTS" region [] $
552 Code.toSnippet source region Nothing
555 "This module does not declare any ports, but it says it will:"
558 ["Switch","this","to",D.cyan "module"
559 ,"and","you","should","be","all","set!"
564 toParseErrorReport source modul
567toParseErrorReport :: Code.Source -> Module -> Report.Report
568toParseErrorReport source modul =
570 ModuleSpace space row col ->
571 toSpaceReport source space row col
573 ModuleBadEnd row col ->
574 case Code.whatIsNext source row col of
575 Code.Keyword keyword ->
577 region = toKeywordRegion row col keyword
579 Report.Report "RESERVED WORD" region [] $
580 Code.toSnippet source region Nothing
583 "I got stuck on this reserved word:"
586 "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
591 region = toKeywordRegion row col op
593 Report.Report "UNEXPECTED SYMBOL" region [] $
594 Code.toSnippet source region Nothing
597 "I ran into an unexpected symbol:"
600 "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
601 \ I can give a better hint from there?"
604 Code.Close term bracket ->
606 region = toRegion row col
608 Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
609 Code.toSnippet source region Nothing
612 "I ran into an unexpected " ++ term ++ ":"
615 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
620 region = toRegion row col
622 Report.Report "SYNTAX PROBLEM" region [] $
623 Code.toSnippet source region Nothing
629 "Whatever I am running into is confusing me a lot! Normally I can give fairly\
630 \ specific hints, but something is really tripping me up this time."
633 ModuleProblem row col ->
635 region = toRegion row col
637 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
638 Code.toSnippet source region Nothing
641 "I am parsing an `module` declaration, but I got stuck here:"
645 "Here are some examples of valid `module` declarations:"
646 , D.indent 4 $ D.vcat $
647 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
648 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
651 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
652 \ of files when the public interface of a module stays the same, so exposing fewer\
653 \ values can help improve compile times!"
657 ModuleName row col ->
659 region = toRegion row col
661 Report.Report "EXPECTING MODULE NAME" region [] $
662 Code.toSnippet source region Nothing
665 "I was parsing an `module` declaration until I got stuck here:"
669 "I was expecting to see the module name next, like in these examples:"
670 , D.indent 4 $ D.vcat $
671 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
672 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
673 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
674 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
677 "Notice that the module names all start with capital letters. That is required!"
681 ModuleExposing exposing row col ->
682 toExposingReport source exposing row col
684 PortModuleProblem row col ->
686 region = toRegion row col
688 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
689 Code.toSnippet source region Nothing
692 "I am parsing an `port module` declaration, but I got stuck here:"
696 "Here are some examples of valid `port module` declarations:"
697 , D.indent 4 $ D.vcat $
698 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
699 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
701 , D.link "Note" "Read" "ports" "for more help."
705 PortModuleName row col ->
707 region = toRegion row col
709 Report.Report "EXPECTING MODULE NAME" region [] $
710 Code.toSnippet source region Nothing
713 "I was parsing an `module` declaration until I got stuck here:"
717 "I was expecting to see the module name next, like in these examples:"
718 , D.indent 4 $ D.vcat $
719 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
720 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
723 "Notice that the module names start with capital letters. That is required!"
727 PortModuleExposing exposing row col ->
728 toExposingReport source exposing row col
732 region = toRegion row col
734 Report.Report "BAD MODULE DECLARATION" region [] $
735 Code.toSnippet source region Nothing
738 "I cannot parse this module declaration:"
741 "This type of module is reserved for the @elm organization. It is used to\
742 \ define certain effects, avoiding building them into the compiler."
747 region = toRegion row col
749 toBadFirstLineReport keyword =
750 Report.Report "TOO MUCH INDENTATION" region [] $
751 Code.toSnippet source region Nothing
754 "This `" ++ keyword ++ "` should not have any spaces before it:"
757 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
761 case Code.whatIsNext source row col of
762 Code.Keyword "module" -> toBadFirstLineReport "module"
763 Code.Keyword "import" -> toBadFirstLineReport "import"
764 Code.Keyword "type" -> toBadFirstLineReport "type"
765 Code.Keyword "port" -> toBadFirstLineReport "port"
767 Report.Report "SYNTAX PROBLEM" region [] $
768 Code.toSnippet source region Nothing
775 "I am not sure what is going on, but I recommend starting an Elm\
776 \ file with the following lines:"
778 [ D.fillSep [D.cyan "import","Html"]
780 , D.fillSep [D.green "main","="]
781 , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
784 "You should be able to copy those lines directly into your file. Check out\
785 \ some of the examples on https://elm-lang.org for more help getting started!"
787 "This can also happen when something is indented too much!"
791 ImportStart row col ->
792 toImportReport source row col
794 ImportName row col ->
796 region = toRegion row col
798 Report.Report "EXPECTING IMPORT NAME" region [] $
799 Code.toSnippet source region Nothing
802 "I was parsing an `import` until I got stuck here:"
806 "I was expecting to see a module name next, like in these examples:"
807 , D.indent 4 $ D.vcat $
808 [ D.fillSep [D.cyan "import","Dict"]
809 , D.fillSep [D.cyan "import","Maybe"]
810 , D.fillSep [D.cyan "import","Html.Attributes"]
811 , D.fillSep [D.cyan "import","Json.Decode"]
814 "Notice that the module names all start with capital letters. That is required!"
819 toImportReport source row col
821 ImportAlias row col ->
823 region = toRegion row col
825 Report.Report "EXECTING IMPORT ALIAS" region [] $
826 Code.toSnippet source region Nothing
829 "I was parsing an `import` until I got stuck here:"
833 "I was expecting to see an alias next, like in these examples:"
834 , D.indent 4 $ D.vcat $
835 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
836 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
837 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
840 "Notice that the alias always starts with a capital letter. That is required!"
844 ImportExposing row col ->
845 toImportReport source row col
847 ImportExposingList exposing row col ->
848 toExposingReport source exposing row col
851 toImportReport source row col
853 ImportIndentName row col ->
854 toImportReport source row col
856 ImportIndentAlias row col ->
857 toImportReport source row col
859 ImportIndentExposingList row col ->
861 region = toRegion row col
863 Report.Report "UNFINISHED IMPORT" region [] $
864 Code.toSnippet source region Nothing
867 "I was parsing an `import` until I got stuck here:"
871 "I was expecting to see the list of exposed values next. For example, here\
872 \ are two ways to expose values from the `Html` module:"
873 , D.indent 4 $ D.vcat $
874 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
875 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
878 "I generally recommend the second style. It is more explicit, making it\
879 \ much easier to figure out where values are coming from in large projects!"
885 region = toRegion row col
887 Report.Report "BAD INFIX" region [] $
888 Code.toSnippet source region Nothing
891 "Something went wrong in this infix operator declaration:"
894 "This feature is used by the @elm organization to define the\
895 \ languages built-in operators."
898 Declarations decl _ _ ->
899 toDeclarationsReport source decl
906toImportReport :: Code.Source -> Row -> Col -> Report.Report
907toImportReport source row col =
909 region = toRegion row col
911 Report.Report "UNFINISHED IMPORT" region [] $
912 Code.toSnippet source region Nothing
915 "I am partway through parsing an import, but I got stuck here:"
919 "Here are some examples of valid `import` declarations:"
920 , D.indent 4 $ D.vcat $
921 [ D.fillSep [D.cyan "import","Html"]
922 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
923 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
924 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
927 "You are probably trying to import a different module, but try to make it look like one of these examples!"
936toExposingReport :: Code.Source -> Exposing -> Row -> Col -> Report.Report
937toExposingReport source exposing startRow startCol =
939 ExposingSpace space row col ->
940 toSpaceReport source space row col
942 ExposingStart row col ->
944 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
945 region = toRegion row col
947 Report.Report "PROBLEM IN EXPOSING" region [] $
948 Code.toSnippet source surroundings (Just region)
951 "I want to parse exposed values, but I am getting stuck here:"
955 ["Exposed","values","are","always","surrounded","by","parentheses."
956 ,"So","try","adding","a",D.green "(","here?"
958 , D.toSimpleNote "Here are some valid examples of `exposing` for reference:"
959 , D.indent 4 $ D.vcat $
960 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
961 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
964 "If you are getting tripped up, you can just expose everything for now. It should\
965 \ get easier to make an explicit exposing list as you see more examples in the wild."
969 ExposingValue row col ->
970 case Code.whatIsNext source row col of
971 Code.Keyword keyword ->
973 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
974 region = toKeywordRegion row col keyword
976 Report.Report "RESERVED WORD" region [] $
977 Code.toSnippet source surroundings (Just region)
980 "I got stuck on this reserved word:"
983 "It looks like you are trying to expose `" ++ keyword ++ "` but that is a reserved word. Is there a typo?"
988 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
989 region = toKeywordRegion row col op
991 Report.Report "UNEXPECTED SYMBOL" region [] $
992 Code.toSnippet source surroundings (Just region)
995 "I got stuck on this symbol:"
999 "If you are trying to expose an operator, add parentheses around it like this:"
1000 , D.indent 4 $ D.dullyellow (D.fromChars op) <> " -> " <> D.green ("(" <> D.fromChars op <> ")")
1006 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1007 region = toRegion row col
1009 Report.Report "PROBLEM IN EXPOSING" region [] $
1010 Code.toSnippet source surroundings (Just region)
1013 "I got stuck while parsing these exposed values:"
1017 "I do not have an exact recommendation, so here are some valid examples\
1018 \ of `exposing` for reference:"
1019 , D.indent 4 $ D.vcat $
1020 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1021 , D.fillSep [D.cyan "import","Basics",D.cyan "exposing","(Int, Float, Bool(..), (+), not, sqrt)"]
1024 "These examples show how to expose types, variants, operators, and functions. Everything\
1025 \ should be some permutation of these examples, just with different names."
1029 ExposingOperator row col ->
1031 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1032 region = toRegion row col
1034 Report.Report "PROBLEM IN EXPOSING" region [] $
1035 Code.toSnippet source surroundings (Just region)
1038 "I just saw an open parenthesis, so I was expecting an operator next:"
1041 ["It","is","possible","to","expose","operators,","so","I","was","expecting"
1042 ,"to","see","something","like",D.dullyellow "(+)","or",D.dullyellow "(|=)"
1043 ,"or",D.dullyellow "(||)","after","I","saw","that","open","parenthesis."
1047 ExposingOperatorReserved op row col ->
1049 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1050 region = toRegion row col
1052 Report.Report "RESERVED SYMBOL" region [] $
1053 Code.toSnippet source surroundings (Just region)
1056 "I cannot expose this as an operator:"
1059 BadDot -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1060 BadPipe -> D.fillSep ["Maybe","you","want",D.dullyellow "(||)","instead?"]
1061 BadArrow -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1062 BadEquals -> D.fillSep ["Maybe","you","want",D.dullyellow "(==)","instead?"]
1063 BadHasType -> D.fillSep ["Maybe","you","want",D.dullyellow "(::)","instead?"]
1066 ExposingOperatorRightParen row col ->
1068 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1069 region = toRegion row col
1071 Report.Report "PROBLEM IN EXPOSING" region [] $
1072 Code.toSnippet source surroundings (Just region)
1075 "It looks like you are exposing an operator, but I got stuck here:"
1078 ["I","was","expecting","to","see","the","closing","parenthesis","immediately"
1079 ,"after","the","operator.","Try","adding","a",D.green ")","right","here?"
1083 ExposingEnd row col ->
1085 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1086 region = toRegion row col
1088 Report.Report "UNFINISHED EXPOSING" region [] $
1089 Code.toSnippet source surroundings (Just region)
1092 "I was partway through parsing exposed values, but I got stuck here:"
1095 "Maybe there is a comma missing before this?"
1098 ExposingTypePrivacy row col ->
1100 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1101 region = toRegion row col
1103 Report.Report "PROBLEM EXPOSING CUSTOM TYPE VARIANTS" region [] $
1104 Code.toSnippet source surroundings (Just region)
1107 "It looks like you are trying to expose the variants of a custom type:"
1111 ["You","need","to","write","something","like"
1112 ,D.dullyellow "Status(..)","or",D.dullyellow "Entity(..)"
1113 ,"though.","It","is","all","or","nothing,","otherwise","`case`"
1114 ,"expressions","could","miss","a","variant","and","crash!"
1117 "It is often best to keep the variants hidden! If someone pattern matches on\
1118 \ the variants, it is a MAJOR change if any new variants are added. Suddenly\
1119 \ their `case` expressions do not cover all variants! So if you do not need\
1120 \ people to pattern match, keep the variants hidden and expose functions to\
1121 \ construct values of this type. This way you can add new variants as a MINOR change!"
1125 ExposingIndentEnd row col ->
1127 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1128 region = toRegion row col
1130 Report.Report "UNFINISHED EXPOSING" region [] $
1131 Code.toSnippet source surroundings (Just region)
1134 "I was partway through parsing exposed values, but I got stuck here:"
1138 ["I","was","expecting","a","closing","parenthesis."
1139 ,"Try","adding","a",D.green ")","right","here?"
1142 "I can get confused when there is not enough indentation, so if you already\
1143 \ have a closing parenthesis, it probably just needs some spaces in front of it."
1147 ExposingIndentValue row col ->
1149 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1150 region = toRegion row col
1152 Report.Report "UNFINISHED EXPOSING" region [] $
1153 Code.toSnippet source surroundings (Just region)
1156 "I was partway through parsing exposed values, but I got stuck here:"
1159 "I was expecting another value to expose."
1167toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
1168toSpaceReport source space row col =
1172 region = toRegion row col
1174 Report.Report "NO TABS" region [] $
1175 Code.toSnippet source region Nothing
1178 "I ran into a tab, but tabs are not allowed in Elm files."
1181 "Replace the tab with spaces."
1184 EndlessMultiComment ->
1186 region = toWiderRegion row col 2
1188 Report.Report "ENDLESS COMMENT" region [] $
1189 Code.toSnippet source region Nothing
1192 "I cannot find the end of this multi-line comment:"
1195 [ D.reflow "Add a -} somewhere after this to end the comment."
1197 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
1198 \ that happens to contain another comment. Like parentheses and curly braces,\
1199 \ the start and end markers must always be balanced. Maybe that is the problem?"
1208toRegion :: Row -> Col -> A.Region
1211 pos = A.Position row col
1216toWiderRegion :: Row -> Col -> Word16 -> A.Region
1217toWiderRegion row col extra =
1219 (A.Position row col)
1220 (A.Position row (col + extra))
1223toKeywordRegion :: Row -> Col -> [Char.Char] -> A.Region
1224toKeywordRegion row col keyword =
1226 (A.Position row col)
1227 (A.Position row (col + fromIntegral (length keyword)))
1230toDeclarationsReport :: Code.Source -> Decl -> Report.Report
1231toDeclarationsReport source decl =
1233 DeclStart row col ->
1234 case Code.whatIsNext source row col of
1235 Code.Close term bracket ->
1237 region = toRegion row col
1239 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1240 Code.toSnippet source region Nothing
1243 "I was not expecting to see a " ++ term ++ " here:"
1245 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1248 Code.Keyword keyword ->
1250 region = toKeywordRegion row col keyword
1252 Report.Report "RESERVED WORD" region [] $
1253 Code.toSnippet source region Nothing
1256 "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1261 "It is reserved for declaring imports at the top of your module. If you want\
1262 \ another import, try moving it up top with the other imports. If you want to\
1263 \ define a value or function, try changing the name to something else!"
1268 "It is reserved for writing `case` expressions. Try using a different name?"
1270 "If you are trying to write a `case` expression, it needs to be part of a\
1271 \ definition. So you could write something like this instead:"
1273 [ D.indent 0 $ D.fillSep [D.green "getWidth","maybeWidth","="]
1274 , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1275 , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1276 , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1278 , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1279 , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1282 "This defines a `getWidth` function that we can use elsewhere in our program."
1288 "It is reserved for writing `if` expressions. Try using a different name?"
1290 "If you are trying to write an `if` expression, it needs to be part of a\
1291 \ definition. So you could write something like this instead:"
1293 [ D.indent 0 $ D.fillSep [D.green "reviewPowerLevel","powerLevel","="]
1294 , D.indent 2 $ D.fillSep $
1295 [D.cyan "if","powerLevel",">",D.dullyellow "9000"
1296 ,D.cyan "then",D.dullyellow "\"OVER 9000!!!\""
1297 ,D.cyan "else",D.dullyellow "\"not bad\""
1301 "This defines a `reviewPowerLevel` function that we can use elsewhere in our program."
1306 "It is a reserved word. Try changing the name to something else?"
1311 region = toRegion row col
1313 Report.Report "SYNTAX PROBLEM" region [] $
1314 Code.toSnippet source region Nothing
1317 "I was expecting to see a new declaration here:"
1321 "I am not sure what is going wrong exactly, but here are a couple valid\
1322 \ declarations for reference:"
1324 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1325 , D.fillSep [D.green "add","x","y","="]
1326 , D.fillSep [" ","x","+","y"]
1328 , D.fillSep [D.cyan "type",D.green "User","=","Anonymous","|","LoggedIn String"]
1330 "Note that all declarations start with lower-case letters in Elm. Capitalization\
1331 \ makes a difference, so be consious of that if you are working from examples!"
1335 DeclSpace space row col ->
1336 toSpaceReport source space row col
1338 Port port_ row col ->
1339 toPortReport source port_ row col
1341 DeclType declType row col ->
1342 toDeclTypeReport source declType row col
1344 DeclDef name declDef row col ->
1345 toDeclDefReport source name declDef row col
1347 DeclFreshLineAfterDocComment row col ->
1349 region = toRegion row col
1351 Report.Report "EXPECTING DECLARATION" region [] $
1352 Code.toSnippet source region Nothing
1355 "I just saw a doc comment, but then I got stuck here:"
1358 "I was expecting to see the corresponding declaration next, starting on a fresh\
1359 \ line with no indentation."
1367toPortReport :: Code.Source -> Port -> Row -> Col -> Report.Report
1368toPortReport source port_ startRow startCol =
1370 PortSpace space row col ->
1371 toSpaceReport source space row col
1374 case Code.whatIsNext source row col of
1375 Code.Keyword keyword ->
1377 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1378 region = toKeywordRegion row col keyword
1380 Report.Report "RESERVED WORD" region [] $
1381 Code.toSnippet source surroundings (Just region)
1384 "I cannot handle ports with names like this:"
1387 "You are trying to make a port named `" ++ keyword
1388 ++ "` but that is a reserved word. Try using some other name?"
1393 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1394 region = toRegion row col
1396 Report.Report "PORT PROBLEM" region [] $
1397 Code.toSnippet source surroundings (Just region)
1400 "I just saw the start of a `port` declaration, but then I got stuck here:"
1404 ["I","was","expecting","to","see","a","name","like"
1405 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1406 ,"Something","that","starts","with","a","lower-case","letter."
1412 PortColon row col ->
1414 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1415 region = toRegion row col
1417 Report.Report "PORT PROBLEM" region [] $
1418 Code.toSnippet source surroundings (Just region)
1421 "I just saw the start of a `port` declaration, but then I got stuck here:"
1425 "I was expecting to see a colon next. And then a type that tells me\
1426 \ what type of values are going to flow through."
1431 PortType tipe row col ->
1432 toTypeReport source TC_Port tipe row col
1434 PortIndentName row col ->
1436 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1437 region = toRegion row col
1439 Report.Report "UNFINISHED PORT" region [] $
1440 Code.toSnippet source surroundings (Just region)
1443 "I just saw the start of a `port` declaration, but then I got stuck here:"
1447 ["I","was","expecting","to","see","a","name","like"
1448 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1449 ,"Something","that","starts","with","a","lower-case","letter."
1455 PortIndentColon row col ->
1457 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1458 region = toRegion row col
1460 Report.Report "UNFINISHED PORT" region [] $
1461 Code.toSnippet source surroundings (Just region)
1464 "I just saw the start of a `port` declaration, but then I got stuck here:"
1468 "I was expecting to see a colon next. And then a type that tells me\
1469 \ what type of values are going to flow through."
1474 PortIndentType row col ->
1476 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1477 region = toRegion row col
1479 Report.Report "UNFINISHED PORT" region [] $
1480 Code.toSnippet source surroundings (Just region)
1483 "I just saw the start of a `port` declaration, but then I got stuck here:"
1487 "I was expecting to see a type next. Here are examples of outgoing and\
1488 \ incoming ports for reference:"
1490 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1491 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1494 "The first line defines a `send` port so you can send strings out to JavaScript.\
1495 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1496 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1497 \ get receive messages when new WebSocket messages come in or when an entry in\
1498 \ IndexedDB changes for some external reason."
1507 "Here are some example `port` declarations for reference:"
1509 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1510 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1513 "The first line defines a `send` port so you can send strings out to JavaScript.\
1514 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1515 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1516 \ get receive messages when new WebSocket messages come in or when the IndexedDB\
1517 \ is changed for some external reason."
1525toDeclTypeReport :: Code.Source -> DeclType -> Row -> Col -> Report.Report
1526toDeclTypeReport source declType startRow startCol =
1528 DT_Space space row col ->
1529 toSpaceReport source space row col
1533 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1534 region = toRegion row col
1536 Report.Report "EXPECTING TYPE NAME" region [] $
1537 Code.toSnippet source surroundings (Just region)
1540 "I think I am parsing a type declaration, but I got stuck here:"
1544 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1545 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1551 DT_Alias typeAlias row col ->
1552 toTypeAliasReport source typeAlias row col
1554 DT_Union customType row col ->
1555 toCustomTypeReport source customType row col
1557 DT_IndentName row col ->
1559 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1560 region = toRegion row col
1562 Report.Report "EXPECTING TYPE NAME" region [] $
1563 Code.toSnippet source surroundings (Just region)
1566 "I think I am parsing a type declaration, but I got stuck here:"
1570 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1571 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1578toTypeAliasReport :: Code.Source -> TypeAlias -> Row -> Col -> Report.Report
1579toTypeAliasReport source typeAlias startRow startCol =
1581 AliasSpace space row col ->
1582 toSpaceReport source space row col
1584 AliasName row col ->
1586 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1587 region = toRegion row col
1589 Report.Report "EXPECTING TYPE ALIAS NAME" region [] $
1590 Code.toSnippet source surroundings (Just region)
1593 "I am partway through parsing a type alias, but I got stuck here:"
1597 ["I","was","expecting","a","name","like",D.dullyellow "Person","or",D.dullyellow "Point"
1598 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1604 AliasEquals row col ->
1605 case Code.whatIsNext source row col of
1606 Code.Keyword keyword ->
1608 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1609 region = toKeywordRegion row col keyword
1611 Report.Report "RESERVED WORD" region [] $
1612 Code.toSnippet source surroundings (Just region)
1615 "I ran into a reserved word unexpectedly while parsing this type alias:"
1619 "It looks like you are trying use `" ++ keyword
1620 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1627 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1628 region = toRegion row col
1630 Report.Report "PROBLEM IN TYPE ALIAS" region [] $
1631 Code.toSnippet source surroundings (Just region)
1634 "I am partway through parsing a type alias, but I got stuck here:"
1638 "I was expecting to see a type variable or an an equals sign next."
1643 AliasBody tipe row col ->
1644 toTypeReport source TC_TypeAlias tipe row col
1646 AliasIndentEquals row col ->
1648 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1649 region = toRegion row col
1651 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1652 Code.toSnippet source surroundings (Just region)
1655 "I am partway through parsing a type alias, but I got stuck here:"
1659 "I was expecting to see a type variable or an an equals sign next."
1664 AliasIndentBody row col ->
1666 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1667 region = toRegion row col
1669 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1670 Code.toSnippet source surroundings (Just region)
1673 "I am partway through parsing a type alias, but I got stuck here:"
1677 ["I","was","expecting","to","see","a","type","next.","Something","as","simple"
1678 ,"as",D.dullyellow "Int","or",D.dullyellow "Float","would","work!"
1685typeAliasNote :: D.Doc
1689 "Here is an example of a valid `type alias` for reference:"
1691 [ D.indent 0 $ D.fillSep [D.cyan "type",D.cyan "alias",D.green "Person","="]
1692 , D.indent 2 $ D.vcat $
1700 "This would let us use `Person` as a shorthand for that record type. Using this\
1701 \ shorthand makes type annotations much easier to read, and makes changing code\
1702 \ easier if you decide later that there is more to a person than age and height!"
1706toCustomTypeReport :: Code.Source -> CustomType -> Row -> Col -> Report.Report
1707toCustomTypeReport source customType startRow startCol =
1709 CT_Space space row col ->
1710 toSpaceReport source space row col
1714 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1715 region = toRegion row col
1717 Report.Report "EXPECTING TYPE NAME" region [] $
1718 Code.toSnippet source surroundings (Just region)
1721 "I think I am parsing a type declaration, but I got stuck here:"
1725 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1726 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1732 CT_Equals row col ->
1733 case Code.whatIsNext source row col of
1734 Code.Keyword keyword ->
1736 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1737 region = toKeywordRegion row col keyword
1739 Report.Report "RESERVED WORD" region [] $
1740 Code.toSnippet source surroundings (Just region)
1743 "I ran into a reserved word unexpectedly while parsing this custom type:"
1747 "It looks like you are trying use `" ++ keyword
1748 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1755 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1756 region = toRegion row col
1758 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1759 Code.toSnippet source surroundings (Just region)
1762 "I am partway through parsing a custom type, but I got stuck here:"
1766 "I was expecting to see a type variable or an an equals sign next."
1773 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1774 region = toRegion row col
1776 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1777 Code.toSnippet source surroundings (Just region)
1780 "I am partway through parsing a custom type, but I got stuck here:"
1784 "I was expecting to see a vertical bar like | next."
1789 CT_Variant row col ->
1791 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1792 region = toRegion row col
1794 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1795 Code.toSnippet source surroundings (Just region)
1798 "I am partway through parsing a custom type, but I got stuck here:"
1802 ["I","was","expecting","to","see","a","variant","name","next."
1803 ,"Something","like",D.dullyellow "Success","or",D.dullyellow "Sandwich" <> "."
1804 ,"Any","name","that","starts","with","a","capital","letter","really!"
1810 CT_VariantArg tipe row col ->
1811 toTypeReport source TC_CustomType tipe row col
1813 CT_IndentEquals row col ->
1815 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1816 region = toRegion row col
1818 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1819 Code.toSnippet source surroundings (Just region)
1822 "I am partway through parsing a custom type, but I got stuck here:"
1826 "I was expecting to see a type variable or an an equals sign next."
1831 CT_IndentBar row col ->
1833 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1834 region = toRegion row col
1836 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1837 Code.toSnippet source surroundings (Just region)
1840 "I am partway through parsing a custom type, but I got stuck here:"
1844 "I was expecting to see a vertical bar like | next."
1849 CT_IndentAfterBar row col ->
1851 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1852 region = toRegion row col
1854 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1855 Code.toSnippet source surroundings (Just region)
1858 "I am partway through parsing a custom type, but I got stuck here:"
1862 "I just saw a vertical bar, so I was expecting to see another variant defined next."
1867 CT_IndentAfterEquals row col ->
1869 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1870 region = toRegion row col
1872 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1873 Code.toSnippet source surroundings (Just region)
1876 "I am partway through parsing a custom type, but I got stuck here:"
1880 "I just saw an equals sign, so I was expecting to see the first variant defined next."
1886customTypeNote :: D.Doc
1890 "Here is an example of a valid `type` declaration for reference:"
1892 [ D.indent 0 $ D.fillSep [D.cyan "type",D.green "Status"]
1893 , D.indent 2 $ D.fillSep ["=","Failure"]
1894 , D.indent 2 $ D.fillSep ["|","Waiting"]
1895 , D.indent 2 $ D.fillSep ["|","Success","String"]
1898 "This defines a new `Status` type with three variants. This could be useful if\
1899 \ we are waiting for an HTTP request. Maybe we start with `Waiting` and then\
1900 \ switch to `Failure` or `Success \"message from server\"` depending on how\
1901 \ things go. Notice that the Success variant has some associated data, allowing\
1902 \ us to store a String if the request goes well!"
1910toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
1911toDeclDefReport source name declDef startRow startCol =
1913 DeclDefSpace space row col ->
1914 toSpaceReport source space row col
1916 DeclDefEquals row col ->
1917 case Code.whatIsNext source row col of
1918 Code.Keyword keyword ->
1920 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1921 region = toKeywordRegion row col keyword
1923 Report.Report "RESERVED WORD" region [] $
1924 Code.toSnippet source surroundings (Just region)
1927 "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
1930 "This is a reserved word! Try using some other name?"
1935 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1936 region = toKeywordRegion row col op
1938 Report.Report "UNEXPECTED SYMBOL" region [] $
1939 Code.toSnippet source surroundings (Just region)
1942 "I was not expecting to see this symbol here:"
1946 "I am not sure what is going wrong exactly, so here is a valid\
1947 \ definition (with an optional type annotation) for reference:"
1949 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1950 , D.fillSep [D.green "add","x","y","="]
1951 , D.fillSep [" ","x","+","y"]
1954 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
1960 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1961 region = toRegion row col
1963 Report.Report "PROBLEM IN DEFINITION" region [] $
1964 Code.toSnippet source surroundings (Just region)
1967 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
1971 "I am not sure what is going wrong exactly, so here is a valid\
1972 \ definition (with an optional type annotation) for reference:"
1974 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1975 , D.fillSep [D.green "add","x","y","="]
1976 , D.fillSep [" ","x","+","y"]
1979 "Try to use that format!"
1983 DeclDefType tipe row col ->
1984 toTypeReport source (TC_Annotation name) tipe row col
1986 DeclDefArg pattern row col ->
1987 toPatternReport source PArg pattern row col
1989 DeclDefBody expr row col ->
1990 toExprReport source (InDef name startRow startCol) expr row col
1992 DeclDefNameRepeat row col ->
1994 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1995 region = toRegion row col
1997 Report.Report "EXPECTING DEFINITION" region [] $
1998 Code.toSnippet source surroundings (Just region)
2001 "I just saw the type annotation for `" ++ Name.toChars name
2002 ++ "` so I was expecting to see its definition here:"
2006 "Type annotations always appear directly above the relevant\
2007 \ definition, without anything else in between. (Not even doc comments!)"
2012 DeclDefNameMatch defName row col ->
2014 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2015 region = toRegion row col
2017 Report.Report "NAME MISMATCH" region [] $
2018 Code.toSnippet source surroundings (Just region)
2021 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
2025 "These names do not match! Is there a typo?"
2026 , D.indent 4 $ D.fillSep $
2027 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
2031 DeclDefIndentType row col ->
2033 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2034 region = toRegion row col
2036 Report.Report "UNFINISHED DEFINITION" region [] $
2037 Code.toSnippet source surroundings (Just region)
2040 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
2044 "I just saw a colon, so I am expecting to see a type next."
2049 DeclDefIndentEquals row col ->
2051 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2052 region = toRegion row col
2054 Report.Report "UNFINISHED DEFINITION" region [] $
2055 Code.toSnippet source surroundings (Just region)
2058 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2062 "I was expecting to see an argument or an equals sign next."
2067 DeclDefIndentBody row col ->
2069 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2070 region = toRegion row col
2072 Report.Report "UNFINISHED DEFINITION" region [] $
2073 Code.toSnippet source surroundings (Just region)
2076 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2080 "I was expecting to see an expression next. What is it equal to?"
2090 "Here is a valid definition (with a type annotation) for reference:"
2092 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2093 , D.fillSep [D.green "add","x","y","="]
2094 , D.fillSep [" ","x","+","y"]
2097 "The top line (called a \"type annotation\") is optional. You can leave it off\
2098 \ if you want. As you get more comfortable with Elm and as your project grows,\
2099 \ it becomes more and more valuable to add them though! They work great as\
2100 \ compiler-verified documentation, and they often improve error messages!"
2109 = InNode Node Row Col Context
2110 | InDef Name.Name Row Col
2111 | InDestruct Row Col
2127getDefName :: Context -> Maybe Name.Name
2130 InDestruct _ _ -> Nothing
2131 InDef name _ _ -> Just name
2132 InNode _ _ _ c -> getDefName c
2135isWithin :: Node -> Context -> Bool
2136isWithin desiredNode context =
2138 InDestruct _ _ -> False
2139 InDef _ _ _ -> False
2140 InNode actualNode _ _ _ -> desiredNode == actualNode
2147toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
2148toExprReport source context expr startRow startCol =
2151 toLetReport source context let_ row col
2153 Case case_ row col ->
2154 toCaseReport source context case_ row col
2157 toIfReport source context if_ row col
2159 List list row col ->
2160 toListReport source context list row col
2162 Record record row col ->
2163 toRecordReport source context record row col
2165 Tuple tuple row col ->
2166 toTupleReport source context tuple row col
2168 Func func row col ->
2169 toFuncReport source context func row col
2172 let region = toRegion row col in
2173 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2174 Code.toSnippet source region Nothing
2177 "I was expecting to see a record accessor here:"
2180 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2181 ,"that","accesses","a","value","from","a","record."
2186 let region = toRegion row col in
2187 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2188 Code.toSnippet source region Nothing
2191 "I am trying to parse a record accessor here:"
2196 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2197 ,"that","accesses","a","value","from","a","record."
2201 "Record field names must start with a lower case letter!"
2205 OperatorRight op row col ->
2206 let region = toRegion row col in
2207 Report.Report "MISSING EXPRESSION" region [] $
2208 Code.toSnippet source region Nothing
2211 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
2215 ["You","can","just","put","anything","for","now,","like"
2216 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2217 ,"Once","there","is","something","there,","I","can","probably"
2218 ,"give","a","more","specific","hint!"
2221 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
2222 \ Or if I run into operators in unexpected spots. Point is, there are a\
2223 \ couple ways I can get confused and give sort of weird advice!"
2227 OperatorReserved operator row col ->
2228 toOperatorReport source context operator row col
2232 (contextRow, contextCol, aThing) =
2234 InDestruct r c -> (r, c, "a definition")
2235 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
2236 InNode NRecord r c _ -> (r, c, "a record")
2237 InNode NParens r c _ -> (r, c, "some parentheses")
2238 InNode NList r c _ -> (r, c, "a list")
2239 InNode NFunc r c _ -> (r, c, "an anonymous function")
2240 InNode NCond r c _ -> (r, c, "an `if` expression")
2241 InNode NThen r c _ -> (r, c, "an `if` expression")
2242 InNode NElse r c _ -> (r, c, "an `if` expression")
2243 InNode NCase r c _ -> (r, c, "a `case` expression")
2244 InNode NBranch r c _ -> (r, c, "a `case` expression")
2245 -- TODO check if this is actually the best way to get error messages here
2247 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
2248 region = toRegion row col
2250 Report.Report "MISSING EXPRESSION" region [] $
2251 Code.toSnippet source surroundings (Just region)
2254 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
2258 ["I","was","expecting","to","see","an","expression","like"
2259 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2260 ,"Once","there","is","something","there,","I","can","probably"
2261 ,"give","a","more","specific","hint!"
2264 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
2265 \ Or if I run into operators in unexpected spots. Point is, there are a\
2266 \ couple ways I can get confused and give sort of weird advice!"
2270 Char char row col ->
2271 toCharReport source char row col
2273 String string row col ->
2274 toStringReport source string row col
2276 Number number row col ->
2277 toNumberReport source number row col
2279 Space space row col ->
2280 toSpaceReport source space row col
2282 EndlessShader row col ->
2284 region = toWiderRegion row col 6
2286 Report.Report "ENDLESS SHADER" region [] $
2287 Code.toSnippet source region Nothing
2289 D.reflow "I cannot find the end of this shader:"
2291 D.reflow "Add a |] somewhere after this to end the shader."
2294 ShaderProblem problem row col ->
2296 region = toRegion row col
2298 Report.Report "SHADER PROBLEM" region [] $
2299 Code.toSnippet source region Nothing
2302 "I ran into a problem while parsing this GLSL block."
2306 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
2307 , D.indent 4 $ D.vcat $
2308 map D.fromChars (filter (/="") (lines problem))
2312 IndentOperatorRight op row col ->
2314 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2315 region = toRegion row col
2317 Report.Report "MISSING EXPRESSION" region [] $
2318 Code.toSnippet source surroundings (Just region)
2321 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
2326 ["You","can","just","put","anything","for","now,","like"
2327 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2328 ,"Once","there","is","something","there,","I","can","probably"
2329 ,"give","a","more","specific","hint!"
2333 "I may be getting confused by your indentation? The easiest way to make sure\
2334 \ this is not an indentation problem is to put the expression on the right of\
2335 \ the " ++ Name.toChars op ++ " operator on the same line."
2344toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
2345toCharReport source char row col =
2349 region = toRegion row col
2351 Report.Report "MISSING SINGLE QUOTE" region [] $
2352 Code.toSnippet source region Nothing
2355 "I thought I was parsing a character, but I got to the end of\
2356 \ the line without seeing the closing single quote:"
2359 "Add a closing single quote here!"
2362 CharEscape escape ->
2363 toEscapeReport source escape row col
2365 CharNotString width ->
2367 region = toWiderRegion row col width
2369 Report.Report "NEEDS DOUBLE QUOTES" region [] $
2370 Code.toSnippet source region Nothing
2372 "The following string uses single quotes:"
2375 [ "Please switch to double quotes instead:"
2377 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
2379 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
2380 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
2381 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
2382 \ individual characters."
2391toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
2392toStringReport source string row col =
2394 StringEndless_Single ->
2396 region = toRegion row col
2398 Report.Report "ENDLESS STRING" region [] $
2399 Code.toSnippet source region Nothing
2402 "I got to the end of the line without seeing the closing double quote:"
2406 ["Strings","look","like",D.green "\"this\"","with","double"
2407 ,"quotes","on","each","end.","Is","the","closing","double"
2408 ,"quote","missing","in","your","code?"
2410 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
2414 StringEndless_Multi ->
2416 region = toWiderRegion row col 3
2418 Report.Report "ENDLESS STRING" region [] $
2419 Code.toSnippet source region Nothing
2422 "I cannot find the end of this multi-line string:"
2425 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
2426 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
2430 StringEscape escape ->
2431 toEscapeReport source escape row col
2438toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
2439toEscapeReport source escape row col =
2443 region = toWiderRegion row col 2
2445 Report.Report "UNKNOWN ESCAPE" region [] $
2446 Code.toSnippet source region Nothing
2449 "Backslashes always start escaped characters, but I do not recognize this one:"
2453 "Valid escape characters include:"
2454 , D.dullyellow $ D.indent 4 $ D.vcat $
2464 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
2466 "The last style lets encode ANY character by its Unicode code\
2467 \ point. That means \\u{0009} and \\t are the same. You can use\
2468 \ that style for anything not covered by the other six escapes!"
2472 BadUnicodeFormat width ->
2474 region = toWiderRegion row col width
2476 Report.Report "BAD UNICODE ESCAPE" region [] $
2477 Code.toSnippet source region Nothing
2480 "I ran into an invalid Unicode escape:"
2484 "Here are some examples of valid Unicode escapes:"
2485 , D.dullyellow $ D.indent 4 $ D.vcat $
2492 "Notice that the code point is always surrounded by curly braces.\
2493 \ Maybe you are missing the opening or closing curly brace?"
2496 BadUnicodeCode width ->
2498 region = toWiderRegion row col width
2500 Report.Report "BAD UNICODE ESCAPE" region [] $
2501 Code.toSnippet source region Nothing
2504 "This is not a valid code point:"
2507 "The valid code points are between 0 and 10FFFF inclusive."
2510 BadUnicodeLength width numDigits badCode ->
2512 region = toWiderRegion row col width
2514 Report.Report "BAD UNICODE ESCAPE" region [] $
2515 Code.toSnippet source region Nothing $
2516 if numDigits < 4 then
2519 "Every code point needs at least four digits:"
2522 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
2523 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
2525 D.fillSep ["Try",D.green suggestion,"instead?"]
2531 "This code point has too many digits:"
2534 ["Valid","code","points","are","between"
2535 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
2536 ,"so","try","trimming","any","leading","zeros","until"
2537 ,"you","have","between","four","and","six","digits."
2546toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
2547toNumberReport source number row col =
2549 region = toRegion row col
2553 Report.Report "WEIRD NUMBER" region [] $
2554 Code.toSnippet source region Nothing
2557 "I thought I was reading a number, but I ran into some weird stuff here:"
2561 "I recognize numbers in the following formats:"
2562 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
2564 "So is there a way to write it like one of those?"
2569 Report.Report "WEIRD NUMBER" region [] $
2570 Code.toSnippet source region Nothing
2573 "Numbers cannot end with a dot like this:"
2576 ["Switching","to",D.green (D.fromChars (show int))
2577 ,"or",D.green (D.fromChars (show int ++ ".0"))
2578 ,"will","work","though!"
2583 Report.Report "WEIRD HEXIDECIMAL" region [] $
2584 Code.toSnippet source region Nothing
2587 "I thought I was reading a hexidecimal number until I got here:"
2591 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
2592 \ only recognize things like this:"
2593 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
2597 NumberNoLeadingZero ->
2598 Report.Report "LEADING ZEROS" region [] $
2599 Code.toSnippet source region Nothing
2602 "I do not accept numbers with leading zeros:"
2606 "Just delete the leading zeros and it should work!"
2608 "Some languages let you to specify octal numbers by adding a leading zero.\
2609 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
2610 \ that, but others probably want it to equal 111. Either path is going to\
2611 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
2621toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
2622toOperatorReport source context operator row col =
2626 region = toRegion row col
2628 Report.Report "UNEXPECTED SYMBOL" region [] $
2629 Code.toSnippet source region Nothing
2631 "I was not expecting this dot:"
2634 "Dots are for record access and decimal points, so\
2635 \ they cannot float around on their own. Maybe\
2636 \ there is some extra whitespace?"
2641 region = toRegion row col
2643 Report.Report "UNEXPECTED SYMBOL" region [] $
2644 Code.toSnippet source region Nothing
2647 "I was not expecting this vertical bar:"
2650 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
2655 region = toWiderRegion row col 2
2657 Report.Report "UNEXPECTED ARROW" region [] $
2658 Code.toSnippet source region Nothing $
2659 if isWithin NBranch context then
2662 "I was not expecting to see an arrow here:"
2667 "I think I am parsing a `case` expression right now, so it makes sense to\
2668 \ see arrows around here. This one is confusing me though!"
2671 "I may be getting confused by the indentation. Every pattern in a `case` must be\
2672 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
2673 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
2674 \ indented too far?"
2681 "I was not expecting an arrow here:"
2684 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
2685 \ you want > or >= instead?"
2690 region = toRegion row col
2692 Report.Report "UNEXPECTED EQUALS" region [] $
2693 Code.toSnippet source region Nothing
2696 "I was not expecting to see this equals sign:"
2700 D.reflow "Maybe you want == instead? To check if two values are equal?"
2703 if isWithin NRecord context then
2704 "Records look like { x = 3, y = 4 } with the equals sign right\
2705 \ after the field name. So maybe you forgot a comma?"
2707 case getDefName context of
2709 "I may be getting confused by your indentation. I need all definitions to be indented\
2710 \ exactly the same amount, so if this is meant to be a new definition, it may have too\
2711 \ many spaces in front of it."
2714 "I may be getting confused by your indentation. I think I am still parsing the `"
2715 ++ Name.toChars name ++ "` definition. Is this supposed to be part of a definition\
2716 \ after that? If so, the problem may be a bit before the equals sign. I need all\
2717 \ definitions to be indented exactly the same amount, so the problem may be that\
2718 \ this new definition has too many spaces in front of it."
2724 region = toRegion row col
2726 Report.Report "UNEXPECTED SYMBOL" region [] $
2727 Code.toSnippet source region Nothing $
2730 "I was not expecting to run into the \"has type\" symbol here:"
2732 case getDefName context of
2735 ["Maybe","you","want",D.green "::","instead?"
2736 ,"To","put","something","on","the","front","of","a","list?"
2743 ["Maybe","you","want",D.green "::","instead?"
2744 ,"To","put","something","on","the","front","of","a","list?"
2747 "The single colon is reserved for type annotations and record types, but I think\
2748 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
2751 "I may be getting confused by your indentation. Is this supposed to be part of\
2752 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
2753 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
2754 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
2755 \ this new definition is indented a bit too much."
2764toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
2765toLetReport source context let_ startRow startCol =
2767 LetSpace space row col ->
2768 toSpaceReport source space row col
2772 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2773 region = toRegion row col
2775 Report.Report "LET PROBLEM" region [] $
2776 Code.toSnippet source surroundings (Just region)
2779 "I was partway through parsing a `let` expression, but I got stuck here:"
2783 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2784 ,"keyword","next.","Is","there","a","typo?"
2787 "This can also happen if you are trying to define another value within the `let` but\
2788 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2789 \ spaces before it. They should line up exactly!"
2793 LetDefAlignment _ row col ->
2795 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2796 region = toRegion row col
2798 Report.Report "LET PROBLEM" region [] $
2799 Code.toSnippet source surroundings (Just region)
2802 "I was partway through parsing a `let` expression, but I got stuck here:"
2806 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2807 ,"keyword","next.","Is","there","a","typo?"
2810 "This can also happen if you are trying to define another value within the `let` but\
2811 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2812 \ spaces before it. The should line up exactly!"
2816 LetDefName row col ->
2817 case Code.whatIsNext source row col of
2818 Code.Keyword keyword ->
2820 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2821 region = toKeywordRegion row col keyword
2823 Report.Report "RESERVED WORD" region [] $
2824 Code.toSnippet source surroundings (Just region)
2827 "I was partway through parsing a `let` expression, but I got stuck here:"
2830 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
2831 \ it is a reserved word! Try using a different name instead."
2835 toUnfinishLetReport source row col startRow startCol $
2837 "I was expecting the name of a definition next."
2839 LetDef name def row col ->
2840 toLetDefReport source name def row col
2842 LetDestruct destruct row col ->
2843 toLetDestructReport source destruct row col
2845 LetBody expr row col ->
2846 toExprReport source context expr row col
2848 LetIndentDef row col ->
2849 toUnfinishLetReport source row col startRow startCol $
2851 "I was expecting a value to be defined here."
2853 LetIndentIn row col ->
2854 toUnfinishLetReport source row col startRow startCol $
2856 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
2857 ,"Or","maybe","more","of","that","expression?"
2860 LetIndentBody row col ->
2861 toUnfinishLetReport source row col startRow startCol $
2863 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
2866toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
2867toUnfinishLetReport source row col startRow startCol message =
2869 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2870 region = toRegion row col
2872 Report.Report "UNFINISHED LET" region [] $
2873 Code.toSnippet source surroundings (Just region)
2876 "I was partway through parsing a `let` expression, but I got stuck here:"
2881 "Here is an example with a valid `let` expression for reference:"
2883 [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
2884 , D.indent 2 $ D.fillSep [D.cyan "let"]
2885 , D.indent 4 $ D.fillSep ["fullName","="]
2886 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
2887 , D.indent 2 $ D.fillSep [D.cyan "in"]
2888 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
2891 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
2892 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
2893 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
2894 \ indented a bit more than that. That is important!"
2899toLetDefReport :: Code.Source -> Name.Name -> Def -> Row -> Col -> Report.Report
2900toLetDefReport source name def startRow startCol =
2902 DefSpace space row col ->
2903 toSpaceReport source space row col
2905 DefType tipe row col ->
2906 toTypeReport source (TC_Annotation name) tipe row col
2908 DefNameRepeat row col ->
2910 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2911 region = toRegion row col
2913 Report.Report "EXPECTING DEFINITION" region [] $
2914 Code.toSnippet source surroundings (Just region)
2917 "I just saw the type annotation for `" ++ Name.toChars name
2918 ++ "` so I was expecting to see its definition here:"
2922 "Type annotations always appear directly above the relevant\
2923 \ definition, without anything else in between."
2928 DefNameMatch defName row col ->
2930 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2931 region = toRegion row col
2933 Report.Report "NAME MISMATCH" region [] $
2934 Code.toSnippet source surroundings (Just region)
2937 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
2941 "These names do not match! Is there a typo?"
2942 , D.indent 4 $ D.fillSep $
2943 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
2947 DefArg pattern row col ->
2948 toPatternReport source PArg pattern row col
2950 DefEquals row col ->
2951 case Code.whatIsNext source row col of
2952 Code.Keyword keyword ->
2954 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2955 region = toKeywordRegion row col keyword
2957 Report.Report "RESERVED WORD" region [] $
2958 Code.toSnippet source surroundings (Just region)
2961 "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
2964 "This is a reserved word! Try using some other name?"
2969 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2970 region = toKeywordRegion row col op
2972 Report.Report "UNEXPECTED SYMBOL" region [] $
2973 Code.toSnippet source surroundings (Just region)
2976 "I was not expecting to see this symbol here:"
2980 "I am not sure what is going wrong exactly, so here is a valid\
2981 \ definition (with an optional type annotation) for reference:"
2983 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2984 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
2985 , D.indent 6 $ D.fillSep ["x","+","y"]
2988 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
2994 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2995 region = toRegion row col
2997 Report.Report "PROBLEM IN DEFINITION" region [] $
2998 Code.toSnippet source surroundings (Just region)
3001 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3005 "I am not sure what is going wrong exactly, so here is a valid\
3006 \ definition (with an optional type annotation) for reference:"
3008 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3009 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3010 , D.indent 4 $ D.fillSep ["x","+","y"]
3013 "Try to use that format!"
3017 DefBody expr row col ->
3018 toExprReport source (InDef name startRow startCol) expr row col
3020 DefIndentEquals row col ->
3022 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3023 region = toRegion row col
3025 Report.Report "UNFINISHED DEFINITION" region [] $
3026 Code.toSnippet source surroundings (Just region)
3029 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3033 "I was expecting to see an argument or an equals sign next."
3038 DefIndentType row col ->
3040 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3041 region = toRegion row col
3043 Report.Report "UNFINISHED DEFINITION" region [] $
3044 Code.toSnippet source surroundings (Just region)
3047 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
3051 "I just saw a colon, so I am expecting to see a type next."
3056 DefIndentBody row col ->
3058 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3059 region = toRegion row col
3061 Report.Report "UNFINISHED DEFINITION" region [] $
3062 Code.toSnippet source surroundings (Just region)
3065 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3069 "I was expecting to see an expression next. What is it equal to?"
3074 DefAlignment indent row col ->
3076 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3077 region = toRegion row col
3078 offset = indent - col
3080 Report.Report "PROBLEM IN DEFINITION" region [] $
3081 Code.toSnippet source surroundings (Just region)
3084 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3087 "I just saw a type annotation indented " ++ show indent ++ " spaces, so I was\
3088 \ expecting to see the corresponding definition next with the exact same amount\
3089 \ of indentation. It looks like this line needs "
3090 ++ show offset ++ " more " ++ (if offset == 1 then "space" else "spaces") ++ "?"
3099 "Here is a valid definition (with a type annotation) for reference:"
3101 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3102 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3103 , D.indent 6 $ D.fillSep ["x","+","y"]
3106 "The top line (called a \"type annotation\") is optional. You can leave it off\
3107 \ if you want. As you get more comfortable with Elm and as your project grows,\
3108 \ it becomes more and more valuable to add them though! They work great as\
3109 \ compiler-verified documentation, and they often improve error messages!"
3113toLetDestructReport :: Code.Source -> Destruct -> Row -> Col -> Report.Report
3114toLetDestructReport source destruct startRow startCol =
3116 DestructSpace space row col ->
3117 toSpaceReport source space row col
3119 DestructPattern pattern row col ->
3120 toPatternReport source PLet pattern row col
3122 DestructEquals row col ->
3124 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3125 region = toRegion row col
3127 Report.Report "PROBLEM IN DEFINITION" region [] $
3128 Code.toSnippet source surroundings (Just region)
3131 "I got stuck trying to parse this definition:"
3133 case Code.whatIsNext source row col of
3134 Code.Operator ":" ->
3137 "I was expecting to see an equals sign next, followed by an expression\
3138 \ telling me what to compute."
3140 "It looks like you may be trying to write a type annotation? It is not\
3141 \ possible to add type annotations on destructuring definitions like this.\
3142 \ You can assign a name to the overall structure, put a type annotation on\
3143 \ that, and then destructure separately though."
3148 "I was expecting to see an equals sign next, followed by an expression\
3149 \ telling me what to compute."
3152 DestructBody expr row col ->
3153 toExprReport source (InDestruct startRow startCol) expr row col
3155 DestructIndentEquals row col ->
3157 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3158 region = toRegion row col
3160 Report.Report "UNFINISHED DEFINITION" region [] $
3161 Code.toSnippet source surroundings (Just region)
3164 "I got stuck trying to parse this definition:"
3167 "I was expecting to see an equals sign next, followed by an expression\
3168 \ telling me what to compute."
3171 DestructIndentBody row col ->
3173 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3174 region = toRegion row col
3176 Report.Report "UNFINISHED DEFINITION" region [] $
3177 Code.toSnippet source surroundings (Just region)
3180 "I got stuck while parsing this definition:"
3183 "I was expecting to see an expression next. What is it equal to?"
3191toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
3192toCaseReport source context case_ startRow startCol =
3194 CaseSpace space row col ->
3195 toSpaceReport source space row col
3198 toUnfinishCaseReport source row col startRow startCol $
3199 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3201 CasePattern pattern row col ->
3202 toPatternReport source PCase pattern row col
3204 CaseArrow row col ->
3205 case Code.whatIsNext source row col of
3206 Code.Keyword keyword ->
3208 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3209 region = toKeywordRegion row col keyword
3211 Report.Report "RESERVED WORD" region [] $
3212 Code.toSnippet source surroundings (Just region)
3215 "I am partway through parsing a `case` expression, but I got stuck here:"
3218 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
3219 \ patterns, but it is a reserved word. Try using a different name?"
3222 Code.Operator ":" ->
3224 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3225 region = toRegion row col
3227 Report.Report "UNEXPECTED OPERATOR" region [] $
3228 Code.toSnippet source surroundings (Just region)
3231 "I am partway through parsing a `case` expression, but I got stuck here:"
3234 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
3235 ,"For","pattern","matching","on","lists?"
3239 Code.Operator "=" ->
3241 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3242 region = toRegion row col
3244 Report.Report "UNEXPECTED OPERATOR" region [] $
3245 Code.toSnippet source surroundings (Just region)
3248 "I am partway through parsing a `case` expression, but I got stuck here:"
3251 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
3257 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3258 region = toRegion row col
3260 Report.Report "MISSING ARROW" region [] $
3261 Code.toSnippet source surroundings (Just region)
3264 "I am partway through parsing a `case` expression, but I got stuck here:"
3266 addNoteForCaseIndentError $
3268 "I was expecting to see an arrow next."
3271 CaseExpr expr row col ->
3272 toExprReport source (InNode NCase startRow startCol context) expr row col
3274 CaseBranch expr row col ->
3275 toExprReport source (InNode NBranch startRow startCol context) expr row col
3277 CaseIndentOf row col ->
3278 toUnfinishCaseReport source row col startRow startCol $
3279 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3281 CaseIndentExpr row col ->
3282 toUnfinishCaseReport source row col startRow startCol $
3283 D.reflow "I was expecting to see a expression next."
3285 CaseIndentPattern row col ->
3286 toUnfinishCaseReport source row col startRow startCol $
3287 D.reflow "I was expecting to see a pattern next."
3289 CaseIndentArrow row col ->
3290 toUnfinishCaseReport source row col startRow startCol $
3292 ["I","just","saw","a","pattern,","so","I","was","expecting"
3293 ,"to","see","a",D.dullyellow "->","next."
3296 CaseIndentBranch row col ->
3297 toUnfinishCaseReport source row col startRow startCol $
3299 "I was expecting to see an expression next. What should I do when\
3300 \ I run into this particular pattern?"
3302 CasePatternAlignment indent row col ->
3303 toUnfinishCaseReport source row col startRow startCol $
3305 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
3308toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3309toUnfinishCaseReport source row col startRow startCol message =
3311 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3312 region = toRegion row col
3314 Report.Report "UNFINISHED CASE" region [] $
3315 Code.toSnippet source surroundings (Just region)
3318 "I was partway through parsing a `case` expression, but I got stuck here:"
3323 "Here is an example of a valid `case` expression for reference."
3325 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3326 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3327 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3329 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3330 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3333 "Notice the indentation. Each pattern is aligned, and each branch is indented\
3334 \ a bit more than the corresponding pattern. That is important!"
3339addNoteForCaseIndentError :: D.Doc -> D.Doc
3340addNoteForCaseIndentError message =
3345 "Sometimes I get confused by indentation, so try to make your `case` look\
3346 \ something like this:"
3348 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3349 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3350 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3352 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3353 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3356 "Notice the indentation! Each pattern is aligned, and each branch is indented\
3357 \ a bit more than the corresponding pattern. That is important!"
3365toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
3366toIfReport source context if_ startRow startCol =
3368 IfSpace space row col ->
3369 toSpaceReport source space row col
3373 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3374 region = toRegion row col
3376 Report.Report "UNFINISHED IF" region [] $
3377 Code.toSnippet source surroundings (Just region)
3380 "I was expecting to see more of this `if` expression, but I got stuck here:"
3383 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3389 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3390 region = toRegion row col
3392 Report.Report "UNFINISHED IF" region [] $
3393 Code.toSnippet source surroundings (Just region)
3396 "I was expecting to see more of this `if` expression, but I got stuck here:"
3399 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
3403 IfElseBranchStart row col ->
3405 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3406 region = toRegion row col
3408 Report.Report "UNFINISHED IF" region [] $
3409 Code.toSnippet source surroundings (Just region)
3412 "I just saw the start of an `else` branch, but then I got stuck here:"
3415 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3418 IfCondition expr row col ->
3419 toExprReport source (InNode NCond startRow startCol context) expr row col
3421 IfThenBranch expr row col ->
3422 toExprReport source (InNode NThen startRow startCol context) expr row col
3424 IfElseBranch expr row col ->
3425 toExprReport source (InNode NElse startRow startCol context) expr row col
3427 IfIndentCondition row col ->
3429 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3430 region = toRegion row col
3432 Report.Report "UNFINISHED IF" region [] $
3433 Code.toSnippet source surroundings (Just region)
3436 "I was expecting to see more of this `if` expression, but I got stuck here:"
3440 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
3441 ,"that","evaluates","to","True","or","False."
3444 "I can be confused by indentation. Maybe something is not indented enough?"
3448 IfIndentThen row col ->
3450 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3451 region = toRegion row col
3453 Report.Report "UNFINISHED IF" region [] $
3454 Code.toSnippet source surroundings (Just region)
3457 "I was expecting to see more of this `if` expression, but I got stuck here:"
3461 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3464 "I can be confused by indentation. Maybe something is not indented enough?"
3468 IfIndentThenBranch row col ->
3470 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3471 region = toRegion row col
3473 Report.Report "UNFINISHED IF" region [] $
3474 Code.toSnippet source surroundings (Just region)
3477 "I got stuck after the start of this `then` branch:"
3481 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3483 "I can be confused by indentation, so if the `then` branch is already\
3484 \ present, it may not be indented enough for me to recognize it."
3488 IfIndentElseBranch row col ->
3490 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3491 region = toRegion row col
3493 Report.Report "UNFINISHED IF" region [] $
3494 Code.toSnippet source surroundings (Just region)
3497 "I got stuck after the start of this `else` branch:"
3501 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3503 "I can be confused by indentation, so if the `else` branch is already\
3504 \ present, it may not be indented enough for me to recognize it."
3508 IfIndentElse row col ->
3510 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3511 region = toRegion row col
3513 Report.Report "UNFINISHED IF" region [] $
3514 Code.toSnippet source surroundings (Just region)
3517 "I was expecting to see an `else` branch after this:"
3521 "I know what to do when the condition is `True`, but not when it is `False`."
3523 ["Add","an",D.cyan "else","branch","to","handle","that","scenario!"]
3532toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
3533toRecordReport source context record startRow startCol =
3535 RecordOpen row col ->
3536 case Code.whatIsNext source row col of
3537 Code.Keyword keyword ->
3539 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3540 region = toKeywordRegion row col keyword
3542 Report.Report "RESERVED WORD" region [] $
3543 Code.toSnippet source surroundings (Just region)
3546 "I just started parsing a record, but I got stuck on this field name:"
3549 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3550 \ that is a reserved word. Try using a different name!"
3555 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3556 region = toRegion row col
3558 Report.Report "UNFINISHED RECORD" region [] $
3559 Code.toSnippet source surroundings (Just region)
3562 "I just started parsing a record, but I got stuck here:"
3565 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
3566 ,"so","I","was","expecting","to","see","a","field","name","next."
3570 RecordEnd row col ->
3572 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3573 region = toRegion row col
3575 Report.Report "UNFINISHED RECORD" region [] $
3576 Code.toSnippet source surroundings (Just region)
3579 "I am partway through parsing a record, but I got stuck here:"
3583 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
3584 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
3587 "When I get stuck like this, it usually means that there is a missing parenthesis\
3588 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3592 RecordField row col ->
3593 case Code.whatIsNext source row col of
3594 Code.Keyword keyword ->
3596 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3597 region = toKeywordRegion row col keyword
3599 Report.Report "RESERVED WORD" region [] $
3600 Code.toSnippet source surroundings (Just region)
3603 "I am partway through parsing a record, but I got stuck on this field name:"
3606 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3607 \ that is a reserved word. Try using a different name!"
3612 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3613 region = toRegion row col
3615 Report.Report "UNFINISHED RECORD" region [] $
3616 Code.toSnippet source surroundings (Just region)
3619 "I am partway through parsing a record, but I got stuck after that last comma:"
3621 addNoteForRecordError $
3623 "Trailing commas are not allowed in records, so I was expecting to see another\
3624 \ record field defined next. If you are done defining the record, the fix may\
3625 \ be to delete that last comma?"
3628 RecordEquals row col ->
3630 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3631 region = toRegion row col
3633 Report.Report "UNFINISHED RECORD" region [] $
3634 Code.toSnippet source surroundings (Just region)
3637 "I am partway through parsing a record, but I got stuck here:"
3639 addNoteForRecordError $
3641 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
3642 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
3646 RecordExpr expr row col ->
3647 toExprReport source (InNode NRecord startRow startCol context) expr row col
3649 RecordSpace space row col ->
3650 toSpaceReport source space row col
3652 RecordIndentOpen row col ->
3654 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3655 region = toRegion row col
3657 Report.Report "UNFINISHED RECORD" region [] $
3658 Code.toSnippet source surroundings (Just region)
3661 "I just saw the opening curly brace of a record, but then I got stuck here:"
3663 addNoteForRecordIndentError $
3665 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
3666 ,"Try","defining","some","fields","of","your","own?"
3670 RecordIndentEnd row col ->
3672 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3673 region = toRegion row col
3675 Report.Report "UNFINISHED RECORD" region [] $
3676 Code.toSnippet source surroundings (Just region)
3679 "I was expecting to see a closing curly brace next:"
3681 addNoteForRecordIndentError $
3683 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
3687 RecordIndentField row col ->
3689 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3690 region = toRegion row col
3692 Report.Report "UNFINISHED RECORD" region [] $
3693 Code.toSnippet source surroundings (Just region)
3696 "I am partway through parsing a record, but I got stuck after that last comma:"
3698 addNoteForRecordError $
3700 "Trailing commas are not allowed in records, so the fix may be to\
3701 \ delete that last comma? Or maybe you were in the middle of defining\
3702 \ an additional field?"
3705 RecordIndentEquals row col ->
3707 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3708 region = toRegion row col
3710 Report.Report "UNFINISHED RECORD" region [] $
3711 Code.toSnippet source surroundings (Just region)
3714 "I am partway through parsing a record. I just saw a record\
3715 \ field, so I was expecting to see an equals sign next:"
3717 addNoteForRecordIndentError $
3719 ["Try","putting","an",D.green "=","followed","by","an","expression?"
3723 RecordIndentExpr row col ->
3725 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3726 region = toRegion row col
3728 Report.Report "UNFINISHED RECORD" region [] $
3729 Code.toSnippet source surroundings (Just region)
3732 "I am partway through parsing a record, and I was expecting to run into an expression next:"
3734 addNoteForRecordIndentError $
3736 ["Try","putting","something","like"
3737 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
3742addNoteForRecordError :: D.Doc -> D.Doc
3743addNoteForRecordError normalRecommendation =
3745 normalRecommendation
3748 "If you are trying to define a record across multiple lines, I recommend using this format:"
3749 , D.indent 4 $ D.vcat $
3750 [ "{ name = \"Alice\""
3756 "Notice that each line starts with some indentation. Usually two or four spaces. I\
3757 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
3758 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3762addNoteForRecordIndentError :: D.Doc -> D.Doc
3763addNoteForRecordIndentError normalRecommendation =
3765 normalRecommendation
3768 "I may be confused by indentation. For example, if you are trying to define\
3769 \ a record across multiple lines, I recommend using this format:"
3770 , D.indent 4 $ D.vcat $
3771 [ "{ name = \"Alice\""
3777 "Notice that each line starts with some indentation. Usually two or four spaces. I\
3778 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
3779 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3787toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
3788toTupleReport source context tuple startRow startCol =
3790 TupleExpr expr row col ->
3791 toExprReport source (InNode NParens startRow startCol context) expr row col
3793 TupleSpace space row col ->
3794 toSpaceReport source space row col
3798 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3799 region = toRegion row col
3801 Report.Report "UNFINISHED PARENTHESES" region [] $
3802 Code.toSnippet source surroundings (Just region)
3805 "I was expecting to see a closing parentheses next, but I got stuck here:"
3808 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3810 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
3811 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
3812 \ or missing brackets) that is confusing me."
3816 TupleOperatorClose row col ->
3818 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3819 region = toRegion row col
3821 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
3822 Code.toSnippet source surroundings (Just region)
3824 D.reflow "I was expecting a closing parenthesis here:"
3827 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
3829 "I think I am parsing an operator function right now, so I am expecting to see\
3830 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
3835 TupleOperatorReserved operator row col ->
3837 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3838 region = toRegion row col
3840 Report.Report "UNEXPECTED SYMBOL" region [] $
3841 Code.toSnippet source surroundings (Just region)
3844 "I ran into an unexpected symbol here:"
3848 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
3849 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
3850 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
3851 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
3852 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
3855 TupleIndentExpr1 row col ->
3857 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3858 region = toRegion row col
3860 Report.Report "UNFINISHED PARENTHESES" region [] $
3861 Code.toSnippet source surroundings (Just region)
3864 "I just saw an open parenthesis, so I was expecting to see an expression next."
3868 ["Something","like",D.dullyellow "(4 + 5)","or"
3869 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
3870 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
3873 "I can get confused by indentation in cases like this, so\
3874 \ maybe you have an expression but it is not indented enough?"
3878 TupleIndentExprN row col ->
3880 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3881 region = toRegion row col
3883 Report.Report "UNFINISHED TUPLE" region [] $
3884 Code.toSnippet source surroundings (Just region)
3887 "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."
3891 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
3892 ,D.dullyellow "(\"Tom\",42)" <> ","
3893 ,"so","I","think","there","is","an","expression","missing","here?"
3896 "I can get confused by indentation in cases like this, so\
3897 \ maybe you have an expression but it is not indented enough?"
3901 TupleIndentEnd row col ->
3903 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3904 region = toRegion row col
3906 Report.Report "UNFINISHED PARENTHESES" region [] $
3907 Code.toSnippet source surroundings (Just region)
3910 "I was expecting to see a closing parenthesis next:"
3913 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
3915 "I can get confused by indentation in cases like this, so\
3916 \ maybe you have a closing parenthesis but it is not indented enough?"
3921toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
3922toListReport source context list startRow startCol =
3924 ListSpace space row col ->
3925 toSpaceReport source space row col
3929 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3930 region = toRegion row col
3932 Report.Report "UNFINISHED LIST" region [] $
3933 Code.toSnippet source surroundings (Just region)
3936 "I am partway through parsing a list, but I got stuck here:"
3940 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
3941 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
3944 "When I get stuck like this, it usually means that there is a missing parenthesis\
3945 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3949 ListExpr expr row col ->
3953 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
3954 region = toRegion r c
3956 Report.Report "UNFINISHED LIST" region [] $
3957 Code.toSnippet source surroundings (Just region)
3960 "I was expecting to see another list entry after that last comma:"
3964 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
3966 "I recommend using the following format for lists that span multiple lines:"
3967 , D.indent 4 $ D.vcat $
3974 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
3975 \ This style can be jarring for people coming from C-like syntax, but folks generally\
3976 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3981 toExprReport source (InNode NList startRow startCol context) expr row col
3985 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3986 region = toRegion row col
3988 Report.Report "UNFINISHED LIST" region [] $
3989 Code.toSnippet source surroundings (Just region)
3992 "I am partway through parsing a list, but I got stuck here:"
3996 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
3997 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4000 "When I get stuck like this, it usually means that there is a missing parenthesis\
4001 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4005 ListIndentOpen row col ->
4007 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4008 region = toRegion row col
4010 Report.Report "UNFINISHED LIST" region [] $
4011 Code.toSnippet source surroundings (Just region)
4014 "I cannot find the end of this list:"
4018 ["You","could","change","it","to","something","like"
4019 ,D.dullyellow "[3,4,5]"
4021 ,D.dullyellow "[]" <> "."
4022 ,"Anything","where","there","is","an","open","and","close","square","brace,"
4023 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
4026 "I may be confused by indentation. For example, if you are trying to define\
4027 \ a list across multiple lines, I recommend using this format:"
4028 , D.indent 4 $ D.vcat $
4035 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4036 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4037 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4041 ListIndentEnd row col ->
4043 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4044 region = toRegion row col
4046 Report.Report "UNFINISHED LIST" region [] $
4047 Code.toSnippet source surroundings (Just region)
4050 "I cannot find the end of this list:"
4054 ["You","can","just","add","a","closing",D.dullyellow "]"
4055 ,"right","here,","and","I","will","be","all","set!"
4058 "I may be confused by indentation. For example, if you are trying to define\
4059 \ a list across multiple lines, I recommend using this format:"
4060 , D.indent 4 $ D.vcat $
4067 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4068 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4069 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4073 ListIndentExpr row col ->
4075 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4076 region = toRegion row col
4078 Report.Report "UNFINISHED LIST" region [] $
4079 Code.toSnippet source surroundings (Just region)
4082 "I was expecting to see another list entry after this comma:"
4086 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4088 "I recommend using the following format for lists that span multiple lines:"
4089 , D.indent 4 $ D.vcat $
4096 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4097 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4098 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4103toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
4104toFuncReport source context func startRow startCol =
4106 FuncSpace space row col ->
4107 toSpaceReport source space row col
4109 FuncArg pattern row col ->
4110 toPatternReport source PArg pattern row col
4112 FuncBody expr row col ->
4113 toExprReport source (InNode NFunc startRow startCol context) expr row col
4115 FuncArrow row col ->
4116 case Code.whatIsNext source row col of
4117 Code.Keyword keyword ->
4119 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4120 region = toKeywordRegion row col keyword
4122 Report.Report "RESERVED WORD" region [] $
4123 Code.toSnippet source surroundings (Just region)
4126 "I was parsing an anonymous function, but I got stuck here:"
4129 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
4130 \ it is a reserved word in this language. Try using a different argument name!"
4135 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4136 region = toRegion row col
4138 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4139 Code.toSnippet source surroundings (Just region)
4142 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4145 ["The","syntax","for","anonymous","functions","is"
4146 ,D.dullyellow "(\\x -> x + 1)"
4147 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4151 FuncIndentArg row col ->
4153 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4154 region = toRegion row col
4156 Report.Report "MISSING ARGUMENT" region [] $
4157 Code.toSnippet source surroundings (Just region)
4160 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
4164 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
4165 ,"Anything","that","starts","with","a","lower","case","letter!"
4168 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
4169 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
4170 \ like a better idea at the time!"
4174 FuncIndentArrow row col ->
4176 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4177 region = toRegion row col
4179 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4180 Code.toSnippet source surroundings (Just region)
4183 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4187 ["The","syntax","for","anonymous","functions","is"
4188 ,D.dullyellow "(\\x -> x + 1)"
4189 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4192 "It is possible that I am confused about indetation! I generally recommend\
4193 \ switching to named functions if the definition cannot fit inline nicely, so\
4194 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4195 \ the whole thing out into a named function. Things tend to be clearer that way!"
4199 FuncIndentBody row col ->
4201 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4202 region = toRegion row col
4204 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4205 Code.toSnippet source surroundings (Just region)
4208 "I was expecting to see the body of your anonymous function next:"
4212 ["The","syntax","for","anonymous","functions","is"
4213 ,D.dullyellow "(\\x -> x + 1)"
4214 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
4217 "It is possible that I am confused about indetation! I generally recommend\
4218 \ switching to named functions if the definition cannot fit inline nicely, so\
4219 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4220 \ the whole thing out into a named function. Things tend to be clearer that way!"
4235toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
4236toPatternReport source context pattern startRow startCol =
4238 PRecord record row col ->
4239 toPRecordReport source record row col
4241 PTuple tuple row col ->
4242 toPTupleReport source context tuple row col
4244 PList list row col ->
4245 toPListReport source context list row col
4248 case Code.whatIsNext source row col of
4249 Code.Keyword keyword ->
4251 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4252 region = toKeywordRegion row col keyword
4255 PArg -> "as an argument"
4256 PCase -> "in this pattern"
4257 PLet -> "in this pattern"
4259 Report.Report "RESERVED WORD" region [] $
4260 Code.toSnippet source surroundings (Just region)
4263 "It looks like you are trying to use `" ++ keyword ++ "` " ++ inThisThing ++ ":"
4266 "This is a reserved word! Try using some other name?"
4269 Code.Operator "-" ->
4271 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4272 region = toRegion row col
4274 Report.Report "UNEXPECTED SYMBOL" region [] $
4275 Code.toSnippet source surroundings (Just region)
4278 "I ran into a minus sign unexpectedly in this pattern:"
4281 "It is not possible to pattern match on negative numbers at this\
4282 \ time. Try using an `if` expression for that sort of thing for now."
4287 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4288 region = toRegion row col
4290 Report.Report "PROBLEM IN PATTERN" region [] $
4291 Code.toSnippet source surroundings (Just region)
4294 "I wanted to parse a pattern next, but I got stuck here:"
4297 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4298 ,"I","just","know","that","I","want","a","pattern","next."
4299 ,"Something","as","simple","as"
4300 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4305 PChar char row col ->
4306 toCharReport source char row col
4308 PString string row col ->
4309 toStringReport source string row col
4311 PNumber number row col ->
4312 toNumberReport source number row col
4314 PFloat width row col ->
4316 region = toWiderRegion row col width
4318 Report.Report "UNEXPECTED PATTERN" region [] $
4319 Code.toSnippet source region Nothing
4322 "I cannot pattern match with floating point numbers:"
4325 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
4326 ,"to","check","that","they","are","nearby","with","some","sort","of"
4327 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
4333 region = toRegion row col
4335 Report.Report "UNFINISHED PATTERN" region [] $
4336 Code.toSnippet source region Nothing $
4339 "I was expecting to see a variable name after the `as` keyword:"
4343 ["The","`as`","keyword","lets","you","write","patterns","like"
4344 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4345 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4346 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4347 ,"thing","with",D.dullyellow "point."
4350 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4351 \ people just want to use `as` as a variable name though. Try using a different name\
4356 PWildcardNotVar name width row col ->
4358 region = toWiderRegion row col (fromIntegral width)
4360 case dropWhile (=='_') (Name.toChars name) of
4361 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
4362 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
4364 Report.Report "UNEXPECTED NAME" region [] $
4365 Code.toSnippet source region Nothing $
4368 "Variable names cannot start with underscores like this:"
4371 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
4372 ,"ignore","the","value,","or","you","can","have","a","name","like"
4373 ] ++ examples ++ ["to","use","the","matched","value." ]
4376 PSpace space row col ->
4377 toSpaceReport source space row col
4379 PIndentStart row col ->
4381 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4382 region = toRegion row col
4384 Report.Report "UNFINISHED PATTERN" region [] $
4385 Code.toSnippet source surroundings (Just region)
4388 "I wanted to parse a pattern next, but I got stuck here:"
4392 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4393 ,"I","just","know","that","I","want","a","pattern","next."
4394 ,"Something","as","simple","as"
4395 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4399 "I can get confused by indentation. If you think there is a pattern next, maybe\
4400 \ it needs to be indented a bit more?"
4404 PIndentAlias row col ->
4406 region = toRegion row col
4408 Report.Report "UNFINISHED PATTERN" region [] $
4409 Code.toSnippet source region Nothing $
4412 "I was expecting to see a variable name after the `as` keyword:"
4416 ["The","`as`","keyword","lets","you","write","patterns","like"
4417 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4418 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4419 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4420 ,"thing","with",D.dullyellow "point."
4423 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4424 \ people just want to use `as` as a variable name though. Try using a different name\
4430toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
4431toPRecordReport source record startRow startCol =
4433 PRecordOpen row col ->
4434 toUnfinishRecordPatternReport source row col startRow startCol $
4435 D.reflow "I was expecting to see a field name next."
4437 PRecordEnd row col ->
4438 toUnfinishRecordPatternReport source row col startRow startCol $
4440 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4441 ,"Try","adding","a",D.dullyellow "}","here?"
4444 PRecordField row col ->
4445 case Code.whatIsNext source row col of
4446 Code.Keyword keyword ->
4448 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4449 region = toKeywordRegion row col keyword
4451 Report.Report "RESERVED WORD" region [] $
4452 Code.toSnippet source surroundings (Just region)
4455 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
4458 "This is a reserved word, not available for variable names. Try another name!"
4462 toUnfinishRecordPatternReport source row col startRow startCol $
4463 D.reflow "I was expecting to see a field name next."
4465 PRecordSpace space row col ->
4466 toSpaceReport source space row col
4468 PRecordIndentOpen row col ->
4469 toUnfinishRecordPatternReport source row col startRow startCol $
4470 D.reflow "I was expecting to see a field name next."
4472 PRecordIndentEnd row col ->
4473 toUnfinishRecordPatternReport source row col startRow startCol $
4475 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4476 ,"Try","adding","a",D.dullyellow "}","here?"
4479 PRecordIndentField row col ->
4480 toUnfinishRecordPatternReport source row col startRow startCol $
4481 D.reflow "I was expecting to see a field name next."
4484toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
4485toUnfinishRecordPatternReport source row col startRow startCol message =
4487 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4488 region = toRegion row col
4490 Report.Report "UNFINISHED RECORD PATTERN" region [] $
4491 Code.toSnippet source surroundings (Just region)
4494 "I was partway through parsing a record pattern, but I got stuck here:"
4499 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
4500 ,"where","you","list","the","field","names","you","want","to","access."
4507toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
4508toPTupleReport source context tuple startRow startCol =
4510 PTupleOpen row col ->
4511 case Code.whatIsNext source row col of
4512 Code.Keyword keyword ->
4514 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4515 region = toKeywordRegion row col keyword
4517 Report.Report "RESERVED WORD" region [] $
4518 Code.toSnippet source surroundings (Just region)
4521 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
4524 "This is a reserved word! Try using some other name?"
4529 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4530 region = toRegion row col
4532 Report.Report "UNFINISHED PARENTHESES" region [] $
4533 Code.toSnippet source surroundings (Just region)
4536 "I just saw an open parenthesis, but I got stuck here:"
4539 ["I","was","expecting","so","see","a","pattern","next."
4540 ,"Maybe","it","will","end","up","being","something"
4541 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
4545 PTupleEnd row col ->
4546 case Code.whatIsNext source row col of
4547 Code.Keyword keyword ->
4549 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4550 region = toKeywordRegion row col keyword
4552 Report.Report "RESERVED WORD" region [] $
4553 Code.toSnippet source surroundings (Just region) $
4556 "I ran into a reserved word in this pattern:"
4559 "The `" ++ keyword ++ "` keyword is reserved. Try using a different name instead!"
4564 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4565 region = toKeywordRegion row col op
4567 Report.Report "UNEXPECTED SYMBOL" region [] $
4568 Code.toSnippet source surroundings (Just region) $
4571 "I ran into the " ++ op ++ " symbol unexpectedly in this pattern:"
4574 "Only the :: symbol that works in patterns. It is useful if you\
4575 \ are pattern matching on lists, trying to get the first element\
4576 \ off the front. Did you want that instead?"
4579 Code.Close term bracket ->
4581 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4582 region = toRegion row col
4584 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
4585 Code.toSnippet source surroundings (Just region) $
4588 "I ran into a an unexpected " ++ term ++ " in this pattern:"
4591 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
4596 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4597 region = toRegion row col
4599 Report.Report "UNFINISHED PARENTHESES" region [] $
4600 Code.toSnippet source surroundings (Just region) $
4603 "I was partway through parsing a pattern, but I got stuck here:"
4606 ["I","was","expecting","a","closing","parenthesis","next,","so"
4607 ,"try","adding","a",D.dullyellow ")","to","see","if","that","helps?"
4611 PTupleExpr pattern row col ->
4612 toPatternReport source context pattern row col
4614 PTupleSpace space row col ->
4615 toSpaceReport source space row col
4617 PTupleIndentEnd row col ->
4619 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4620 region = toRegion row col
4622 Report.Report "UNFINISHED PARENTHESES" region [] $
4623 Code.toSnippet source surroundings (Just region) $
4626 "I was expecting a closing parenthesis next:"
4629 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
4631 "I can get confused by indentation in cases like this, so\
4632 \ maybe you have a closing parenthesis but it is not indented enough?"
4636 PTupleIndentExpr1 row col ->
4638 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4639 region = toRegion row col
4641 Report.Report "UNFINISHED PARENTHESES" region [] $
4642 Code.toSnippet source surroundings (Just region) $
4645 "I just saw an open parenthesis, but then I got stuck here:"
4648 ["I","was","expecting","so","see","a","pattern","next."
4649 ,"Maybe","it","will","end","up","being","something"
4650 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
4654 PTupleIndentExprN row col ->
4656 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4657 region = toRegion row col
4659 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
4660 Code.toSnippet source surroundings (Just region) $
4663 "I am partway through parsing a tuple pattern, but I got stuck here:"
4667 ["I","was","expecting","so","see","a","pattern","next."
4668 ,"I","am","expecting","the","final","result","to","be","something"
4669 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
4672 "I can get confused by indentation in cases like this, so the problem\
4673 \ may be that the next part is not indented enough?"
4678toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
4679toPListReport source context list startRow startCol =
4681 PListOpen row col ->
4682 case Code.whatIsNext source row col of
4683 Code.Keyword keyword ->
4685 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4686 region = toKeywordRegion row col keyword
4688 Report.Report "RESERVED WORD" region [] $
4689 Code.toSnippet source surroundings (Just region)
4692 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
4695 "This is a reserved word though! Try using some other name?"
4700 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4701 region = toRegion row col
4703 Report.Report "UNFINISHED LIST PATTERN" region [] $
4704 Code.toSnippet source surroundings (Just region) $
4707 "I just saw an open square bracket, but then I got stuck here:"
4709 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4714 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4715 region = toRegion row col
4717 Report.Report "UNFINISHED LIST PATTERN" region [] $
4718 Code.toSnippet source surroundings (Just region) $
4721 "I was expecting a closing square bracket to end this list pattern:"
4723 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4726 PListExpr pattern row col ->
4727 toPatternReport source context pattern row col
4729 PListSpace space row col ->
4730 toSpaceReport source space row col
4732 PListIndentOpen row col ->
4734 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4735 region = toRegion row col
4737 Report.Report "UNFINISHED LIST PATTERN" region [] $
4738 Code.toSnippet source surroundings (Just region) $
4741 "I just saw an open square bracket, but then I got stuck here:"
4744 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4746 "I can get confused by indentation in cases like this, so\
4747 \ maybe there is something next, but it is not indented enough?"
4751 PListIndentEnd row col ->
4753 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4754 region = toRegion row col
4756 Report.Report "UNFINISHED LIST PATTERN" region [] $
4757 Code.toSnippet source surroundings (Just region) $
4760 "I was expecting a closing square bracket to end this list pattern:"
4763 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4765 "I can get confused by indentation in cases like this, so\
4766 \ maybe you have a closing square bracket but it is not indented enough?"
4770 PListIndentExpr row col ->
4772 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4773 region = toRegion row col
4775 Report.Report "UNFINISHED LIST PATTERN" region [] $
4776 Code.toSnippet source surroundings (Just region) $
4779 "I am partway through parsing a list pattern, but I got stuck here:"
4783 "I was expecting to see another pattern next. Maybe a variable name."
4785 "I can get confused by indentation in cases like this, so\
4786 \ maybe there is more to this pattern but it is not indented enough?"
4796 = TC_Annotation Name.Name
4802toTypeReport :: Code.Source -> TContext -> Type -> Row -> Col -> Report.Report
4803toTypeReport source context tipe startRow startCol =
4805 TRecord record row col ->
4806 toTRecordReport source context record row col
4808 TTuple tuple row col ->
4809 toTTupleReport source context tuple row col
4812 case Code.whatIsNext source row col of
4813 Code.Keyword keyword ->
4815 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4816 region = toKeywordRegion row col keyword
4818 Report.Report "RESERVED WORD" region [] $
4819 Code.toSnippet source surroundings (Just region)
4822 "I was expecting to see a type next, but I got stuck on this reserved word:"
4825 "It looks like you are trying to use `" ++ keyword ++ "` as a type variable, but \
4826 \ it is a reserved word. Try using a different name!"
4831 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4832 region = toRegion row col
4836 TC_Annotation _ -> "type annotation"
4837 TC_CustomType -> "custom type"
4838 TC_TypeAlias -> "type alias"
4843 TC_Annotation name -> "the `" ++ Name.toChars name ++ "` type annotation"
4844 TC_CustomType -> "a custom type"
4845 TC_TypeAlias -> "a type alias"
4848 Report.Report ("PROBLEM IN " ++ map Char.toUpper thing) region [] $
4849 Code.toSnippet source surroundings (Just region)
4852 "I was partway through parsing " ++ something ++ ", but I got stuck here:"
4855 ["I","was","expecting","to","see","a","type","next."
4856 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
4860 TSpace space row col ->
4861 toSpaceReport source space row col
4863 TIndentStart row col ->
4865 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4866 region = toRegion row col
4870 TC_Annotation _ -> "type annotation"
4871 TC_CustomType -> "custom type"
4872 TC_TypeAlias -> "type alias"
4875 Report.Report ("UNFINISHED " ++ map Char.toUpper thing) region [] $
4876 Code.toSnippet source surroundings (Just region)
4879 "I was partway through parsing a " ++ thing ++ ", but I got stuck here:"
4883 ["I","was","expecting","to","see","a","type","next."
4884 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
4887 "I can get confused by indentation. If you think there is already a type\
4888 \ next, maybe it is not indented enough?"
4893toTRecordReport :: Code.Source -> TContext -> TRecord -> Row -> Col -> Report.Report
4894toTRecordReport source context record startRow startCol =
4896 TRecordOpen row col ->
4897 case Code.whatIsNext source row col of
4898 Code.Keyword keyword ->
4900 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4901 region = toKeywordRegion row col keyword
4903 Report.Report "RESERVED WORD" region [] $
4904 Code.toSnippet source surroundings (Just region)
4907 "I just started parsing a record type, but I got stuck on this field name:"
4910 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
4911 \ that is a reserved word. Try using a different name!"
4916 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4917 region = toRegion row col
4919 Report.Report "UNFINISHED RECORD TYPE" region [] $
4920 Code.toSnippet source surroundings (Just region)
4923 "I just started parsing a record type, but I got stuck here:"
4926 ["Record","types","look","like",D.dullyellow "{ name : String, age : Int },"
4927 ,"so","I","was","expecting","to","see","a","field","name","next."
4931 TRecordEnd row col ->
4933 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4934 region = toRegion row col
4936 Report.Report "UNFINISHED RECORD TYPE" region [] $
4937 Code.toSnippet source surroundings (Just region)
4940 "I am partway through parsing a record type, but I got stuck here:"
4944 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
4945 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
4948 "When I get stuck like this, it usually means that there is a missing parenthesis\
4949 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4953 TRecordField row col ->
4954 case Code.whatIsNext source row col of
4955 Code.Keyword keyword ->
4957 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4958 region = toKeywordRegion row col keyword
4960 Report.Report "RESERVED WORD" region [] $
4961 Code.toSnippet source surroundings (Just region)
4964 "I am partway through parsing a record type, but I got stuck on this field name:"
4967 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
4968 \ that is a reserved word. Try using a different name!"
4973 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4974 region = toRegion row col
4976 Report.Report "UNFINISHED RECORD TYPE" region [] $
4977 Code.toSnippet source surroundings (Just region)
4980 "I am partway through parsing a record type, but I got stuck after that last comma:"
4982 addNoteForRecordTypeError $
4984 "Trailing commas are not allowed in records, so I was expecting to see another\
4985 \ record field defined next. If you are done defining the record, the fix may\
4986 \ be to delete that last comma?"
4989 TRecordColon row col ->
4991 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4992 region = toRegion row col
4994 Report.Report "UNFINISHED RECORD TYPE" region [] $
4995 Code.toSnippet source surroundings (Just region)
4998 "I am partway through parsing a record type, but I got stuck here:"
5000 addNoteForRecordTypeError $
5002 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
5003 ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
5007 TRecordType tipe row col ->
5008 toTypeReport source context tipe row col
5010 TRecordSpace space row col ->
5011 toSpaceReport source space row col
5013 TRecordIndentOpen row col ->
5015 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5016 region = toRegion row col
5018 Report.Report "UNFINISHED RECORD TYPE" region [] $
5019 Code.toSnippet source surroundings (Just region)
5022 "I just saw the opening curly brace of a record type, but then I got stuck here:"
5024 addNoteForRecordTypeIndentError $
5026 ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
5027 ,"Try","defining","some","fields","of","your","own?"
5031 TRecordIndentEnd row col ->
5033 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5034 region = toRegion row col
5036 Report.Report "UNFINISHED RECORD TYPE" region [] $
5037 Code.toSnippet source surroundings (Just region)
5040 "I was expecting to see a closing curly brace next:"
5042 addNoteForRecordTypeIndentError $
5044 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
5048 TRecordIndentField row col ->
5050 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5051 region = toRegion row col
5053 Report.Report "UNFINISHED RECORD TYPE" region [] $
5054 Code.toSnippet source surroundings (Just region)
5057 "I am partway through parsing a record type, but I got stuck after that last comma:"
5059 addNoteForRecordTypeIndentError $
5061 "Trailing commas are not allowed in record types, so the fix may be to\
5062 \ delete that last comma? Or maybe you were in the middle of defining\
5063 \ an additional field?"
5066 TRecordIndentColon row col ->
5068 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5069 region = toRegion row col
5071 Report.Report "UNFINISHED RECORD TYPE" region [] $
5072 Code.toSnippet source surroundings (Just region)
5075 "I am partway through parsing a record type. I just saw a record\
5076 \ field, so I was expecting to see a colon next:"
5078 addNoteForRecordTypeIndentError $
5080 ["Try","putting","an",D.green ":","followed","by","a","type?"
5084 TRecordIndentType row col ->
5086 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5087 region = toRegion row col
5089 Report.Report "UNFINISHED RECORD TYPE" region [] $
5090 Code.toSnippet source surroundings (Just region)
5093 "I am partway through parsing a record type, and I was expecting to run into a type next:"
5095 addNoteForRecordTypeIndentError $
5097 ["Try","putting","something","like"
5098 ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5103addNoteForRecordTypeError :: D.Doc -> D.Doc
5104addNoteForRecordTypeError normalRecommendation =
5106 normalRecommendation
5109 "If you are trying to define a record type across multiple lines, I recommend using this format:"
5110 , D.indent 4 $ D.vcat $
5113 , ", height : Float"
5117 "Notice that each line starts with some indentation. Usually two or four spaces. I\
5118 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5119 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5123addNoteForRecordTypeIndentError :: D.Doc -> D.Doc
5124addNoteForRecordTypeIndentError normalRecommendation =
5126 normalRecommendation
5129 "I may be confused by indentation. For example, if you are trying to define\
5130 \ a record type across multiple lines, I recommend using this format:"
5131 , D.indent 4 $ D.vcat $
5134 , ", height : Float"
5138 "Notice that each line starts with some indentation. Usually two or four spaces. I\
5139 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5140 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5144toTTupleReport :: Code.Source -> TContext -> TTuple -> Row -> Col -> Report.Report
5145toTTupleReport source context tuple startRow startCol =
5147 TTupleOpen row col ->
5148 case Code.whatIsNext source row col of
5149 Code.Keyword keyword ->
5151 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5152 region = toKeywordRegion row col keyword
5154 Report.Report "RESERVED WORD" region [] $
5155 Code.toSnippet source surroundings (Just region)
5158 "I ran into a reserved word unexpectedly:"
5161 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but \
5162 \ it is a reserved word. Try using a different name!"
5167 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5168 region = toRegion row col
5170 Report.Report "UNFINISHED PARENTHESES" region [] $
5171 Code.toSnippet source surroundings (Just region)
5174 "I just saw an open parenthesis, so I was expecting to see a type next."
5177 ["Something","like",D.dullyellow "(Maybe Int)","or"
5178 ,D.dullyellow "(List Person)" <> "."
5179 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5183 TTupleEnd row col ->
5185 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5186 region = toRegion row col
5188 Report.Report "UNFINISHED PARENTHESES" region [] $
5189 Code.toSnippet source surroundings (Just region)
5192 "I was expecting to see a closing parentheses next, but I got stuck here:"
5195 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
5197 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
5198 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
5199 \ or missing brackets) that is confusing me."
5203 TTupleType tipe row col ->
5204 toTypeReport source context tipe row col
5206 TTupleSpace space row col ->
5207 toSpaceReport source space row col
5209 TTupleIndentType1 row col ->
5211 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5212 region = toRegion row col
5214 Report.Report "UNFINISHED PARENTHESES" region [] $
5215 Code.toSnippet source surroundings (Just region)
5218 "I just saw an open parenthesis, so I was expecting to see a type next."
5222 ["Something","like",D.dullyellow "(Maybe Int)","or"
5223 ,D.dullyellow "(List Person)" <> "."
5224 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5227 "I can get confused by indentation in cases like this, so\
5228 \ maybe you have a type but it is not indented enough?"
5232 TTupleIndentTypeN row col ->
5234 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5235 region = toRegion row col
5237 Report.Report "UNFINISHED TUPLE TYPE" region [] $
5238 Code.toSnippet source surroundings (Just region)
5241 "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."
5245 ["A","tuple","type","looks","like",D.dullyellow "(Float,Float)","or"
5246 ,D.dullyellow "(String,Int)" <> ","
5247 ,"so","I","think","there","is","a","type","missing","here?"
5250 "I can get confused by indentation in cases like this, so\
5251 \ maybe you have an expression but it is not indented enough?"
5255 TTupleIndentEnd row col ->
5257 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5258 region = toRegion row col
5260 Report.Report "UNFINISHED PARENTHESES" region [] $
5261 Code.toSnippet source surroundings (Just region)
5264 "I was expecting to see a closing parenthesis next:"
5267 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
5269 "I can get confused by indentation in cases like this, so\
5270 \ 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