1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Syntax
48import Prelude hiding (Char, String)
49import qualified Data.Char as Char
50import qualified Data.Name as Name
51import Data.Word (Word16)
52import Numeric (showHex)
54import qualified Elm.ModuleName as ModuleName
55import Parse.Primitives (Row, Col)
56import Parse.Symbol (BadOperator(..))
57import qualified Reporting.Annotation as A
58import qualified Reporting.Doc as D
59import qualified Reporting.Report as Report
60import qualified Reporting.Render.Code as Code
68 = ModuleNameUnspecified ModuleName.Raw
69 | ModuleNameMismatch ModuleName.Raw (A.Located ModuleName.Raw)
70 | UnexpectedPort A.Region
80 = ModuleSpace Space Row Col
81 | ModuleBadEnd Row Col
83 | ModuleProblem Row Col
85 | ModuleExposing Exposing Row Col
87 | PortModuleProblem Row Col
88 | PortModuleName Row Col
89 | PortModuleExposing Exposing Row Col
99 | ImportExposing Row Col
100 | ImportExposingList Exposing Row Col
101 | ImportEnd Row Col -- different based on col=1 or if greater
103 | ImportIndentName Row Col
104 | ImportIndentAlias Row Col
105 | ImportIndentExposingList Row Col
109 | Declarations Decl Row Col
113 = ExposingSpace Space Row Col
114 | ExposingStart Row Col
115 | ExposingValue Row Col
116 | ExposingOperator Row Col
117 | ExposingOperatorReserved BadOperator Row Col
118 | ExposingOperatorRightParen Row Col
119 | ExposingTypePrivacy Row Col
120 | ExposingEnd Row Col
122 | ExposingIndentEnd Row Col
123 | ExposingIndentValue Row Col
132 | DeclSpace Space Row Col
135 | DeclType DeclType Row Col
136 | DeclDef Name.Name DeclDef Row Col
138 | DeclFreshLineAfterDocComment Row Col
142 = DeclDefSpace Space Row Col
143 | DeclDefEquals Row Col
144 | DeclDefType Type Row Col
145 | DeclDefArg Pattern Row Col
146 | DeclDefBody Expr Row Col
147 | DeclDefNameRepeat Row Col
148 | DeclDefNameMatch Name.Name Row Col
150 | DeclDefIndentType Row Col
151 | DeclDefIndentEquals Row Col
152 | DeclDefIndentBody Row Col
156 = PortSpace Space Row Col
159 | PortType Type Row Col
160 | PortIndentName Row Col
161 | PortIndentColon Row Col
162 | PortIndentType Row Col
170 = DT_Space Space Row Col
172 | DT_Alias TypeAlias Row Col
173 | DT_Union CustomType Row Col
175 | DT_IndentName Row Col
179 = AliasSpace Space Row Col
181 | AliasEquals Row Col
182 | AliasBody Type Row Col
184 | AliasIndentEquals Row Col
185 | AliasIndentBody Row Col
189 = CT_Space Space Row Col
194 | CT_VariantArg Type Row Col
196 | CT_IndentEquals Row Col
197 | CT_IndentBar Row Col
198 | CT_IndentAfterBar Row Col
199 | CT_IndentAfterEquals Row Col
211 | Record Record Row Col
212 | Tuple Tuple Row Col
217 | OperatorRight Name.Name Row Col
218 | OperatorReserved BadOperator Row Col
222 | String String Row Col
223 | Number Number Row Col
224 | Space Space Row Col
225 | EndlessShader Row Col
226 | ShaderProblem [Char.Char] Row Col
227 | IndentOperatorRight Name.Name Row Col
233 | RecordField Row Col
234 | RecordEquals Row Col
235 | RecordExpr Expr Row Col
236 | RecordSpace Space Row Col
238 | RecordIndentOpen Row Col
239 | RecordIndentEnd Row Col
240 | RecordIndentField Row Col
241 | RecordIndentEquals Row Col
242 | RecordIndentExpr Row Col
246 = TupleExpr Expr Row Col
247 | TupleSpace Space Row Col
249 | TupleOperatorClose Row Col
250 | TupleOperatorReserved BadOperator Row Col
252 | TupleIndentExpr1 Row Col
253 | TupleIndentExprN Row Col
254 | TupleIndentEnd Row Col
258 = ListSpace Space Row Col
260 | ListExpr Expr Row Col
263 | ListIndentOpen Row Col
264 | ListIndentEnd Row Col
265 | ListIndentExpr Row Col
269 = FuncSpace Space Row Col
270 | FuncArg Pattern Row Col
271 | FuncBody Expr Row Col
274 | FuncIndentArg Row Col
275 | FuncIndentArrow Row Col
276 | FuncIndentBody Row Col
280 = CaseSpace Space Row Col
282 | CasePattern Pattern Row Col
284 | CaseExpr Expr Row Col
285 | CaseBranch Expr Row Col
287 | CaseIndentOf Row Col
288 | CaseIndentExpr Row Col
289 | CaseIndentPattern Row Col
290 | CaseIndentArrow Row Col
291 | CaseIndentBranch Row Col
292 | CasePatternAlignment Word16 Row Col
296 = IfSpace Space Row Col
299 | IfElseBranchStart Row Col
301 | IfCondition Expr Row Col
302 | IfThenBranch Expr Row Col
303 | IfElseBranch Expr Row Col
305 | IfIndentCondition Row Col
306 | IfIndentThen Row Col
307 | IfIndentThenBranch Row Col
308 | IfIndentElseBranch Row Col
309 | IfIndentElse Row Col
313 = LetSpace Space Row Col
315 | LetDefAlignment Word16 Row Col
317 | LetDef Name.Name Def Row Col
318 | LetDestruct Destruct Row Col
319 | LetBody Expr Row Col
320 | LetIndentDef Row Col
321 | LetIndentIn Row Col
322 | LetIndentBody Row Col
326 = DefSpace Space Row Col
327 | DefType Type Row Col
328 | DefNameRepeat Row Col
329 | DefNameMatch Name.Name Row Col
330 | DefArg Pattern Row Col
332 | DefBody Expr Row Col
333 | DefIndentEquals Row Col
334 | DefIndentType Row Col
335 | DefIndentBody Row Col
336 | DefAlignment Word16 Row Col
340 = DestructSpace Space Row Col
341 | DestructPattern Pattern Row Col
342 | DestructEquals Row Col
343 | DestructBody Expr Row Col
344 | DestructIndentEquals Row Col
345 | DestructIndentBody Row Col
353 = PRecord PRecord Row Col
354 | PTuple PTuple Row Col
355 | PList PList Row Col
359 | PString String Row Col
360 | PNumber Number Row Col
361 | PFloat Word16 Row Col
363 | PWildcardNotVar Name.Name Int Row Col
364 | PSpace Space Row Col
366 | PIndentStart Row Col
367 | PIndentAlias Row Col
371 = PRecordOpen Row Col
373 | PRecordField Row Col
374 | PRecordSpace Space Row Col
376 | PRecordIndentOpen Row Col
377 | PRecordIndentEnd Row Col
378 | PRecordIndentField Row Col
384 | PTupleExpr Pattern Row Col
385 | PTupleSpace Space Row Col
387 | PTupleIndentEnd Row Col
388 | PTupleIndentExpr1 Row Col
389 | PTupleIndentExprN Row Col
395 | PListExpr Pattern Row Col
396 | PListSpace Space Row Col
398 | PListIndentOpen Row Col
399 | PListIndentEnd Row Col
400 | PListIndentExpr Row Col
408 = TRecord TRecord Row Col
409 | TTuple TTuple Row Col
412 | TSpace Space Row Col
414 | TIndentStart Row Col
418 = TRecordOpen Row Col
421 | TRecordField Row Col
422 | TRecordColon Row Col
423 | TRecordType Type Row Col
425 | TRecordSpace Space Row Col
427 | TRecordIndentOpen Row Col
428 | TRecordIndentField Row Col
429 | TRecordIndentColon Row Col
430 | TRecordIndentType Row Col
431 | TRecordIndentEnd Row Col
437 | TTupleType Type Row Col
438 | TTupleSpace Space Row Col
440 | TTupleIndentType1 Row Col
441 | TTupleIndentTypeN Row Col
442 | TTupleIndentEnd Row Col
452 | CharNotString Word16
456 = StringEndless_Single
457 | StringEndless_Multi
458 | StringEscape Escape
463 | BadUnicodeFormat Word16
464 | BadUnicodeCode Word16
465 | BadUnicodeLength Word16 Int Int
472 | NumberNoLeadingZero
481 | EndlessMultiComment
488toReport :: Code.Source -> Error -> Report.Report
491 ModuleNameUnspecified name ->
493 region = toRegion 1 1
495 Report.Report "MODULE NAME MISSING" region [] $
498 "I need the module name to be declared at the top of this file, like this:"
499 , D.indent 4 $ D.fillSep $
500 [ D.cyan "module", D.fromName name, D.cyan "exposing", "(..)" ]
502 "Try adding that as the first line of your file!"
504 "It is best to replace (..) with an explicit list of types and\
505 \ functions you want to expose. When you know a value is only used\
506 \ within this module, you can refactor without worrying about uses\
507 \ elsewhere. Limiting exposed values can also speed up compilation\
508 \ because I can skip a bunch of work if I see that the exposed API\
512 ModuleNameMismatch expectedName (A.At region actualName) ->
513 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
514 Code.toSnippet source region Nothing
516 "It looks like this module name is out of sync:"
520 "I need it to match the file path, so I was expecting it to see `"
521 ++ ModuleName.toChars expectedName
522 ++ "` here. Make the following change, and you should be all set!"
524 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
526 "I require that module names correspond to file paths. This makes it much\
527 \ easier to explore unfamiliar codebases! So if you want to keep the current\
528 \ module name, try renaming the file instead."
532 UnexpectedPort region ->
533 Report.Report "UNEXPECTED PORTS" region [] $
534 Code.toSnippet source region Nothing
537 "You are declaring ports in a normal module."
541 ["Switch","this","to","say",D.cyan "port module","instead,"
542 ,"marking","that","this","module","contains","port","declarations."
545 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
547 "to learn the syntax and how to use it effectively."
552 Report.Report "NO PORTS" region [] $
553 Code.toSnippet source region Nothing
556 "This module does not declare any ports, but it says it will:"
559 ["Switch","this","to",D.cyan "module"
560 ,"and","you","should","be","all","set!"
565 toParseErrorReport source modul
568toParseErrorReport :: Code.Source -> Module -> Report.Report
569toParseErrorReport source modul =
571 ModuleSpace space row col ->
572 toSpaceReport source space row col
574 ModuleBadEnd row col ->
575 case Code.whatIsNext source row col of
576 Code.Keyword keyword ->
578 region = toKeywordRegion row col keyword
580 Report.Report "RESERVED WORD" region [] $
581 Code.toSnippet source region Nothing
584 "I got stuck on this reserved word:"
587 "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
592 region = toKeywordRegion row col op
594 Report.Report "UNEXPECTED SYMBOL" region [] $
595 Code.toSnippet source region Nothing
598 "I ran into an unexpected symbol:"
601 "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
602 \ I can give a better hint from there?"
605 Code.Close term bracket ->
607 region = toRegion row col
609 Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
610 Code.toSnippet source region Nothing
613 "I ran into an unexpected " ++ term ++ ":"
616 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
621 region = toRegion row col
623 Report.Report "SYNTAX PROBLEM" region [] $
624 Code.toSnippet source region Nothing
630 "Whatever I am running into is confusing me a lot! Normally I can give fairly\
631 \ specific hints, but something is really tripping me up this time."
634 ModuleProblem row col ->
636 region = toRegion row col
638 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
639 Code.toSnippet source region Nothing
642 "I am parsing an `module` declaration, but I got stuck here:"
646 "Here are some examples of valid `module` declarations:"
647 , D.indent 4 $ D.vcat $
648 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
649 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
652 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
653 \ of files when the public interface of a module stays the same, so exposing fewer\
654 \ values can help improve compile times!"
658 ModuleName row col ->
660 region = toRegion row col
662 Report.Report "EXPECTING MODULE NAME" region [] $
663 Code.toSnippet source region Nothing
666 "I was parsing an `module` declaration until I got stuck here:"
670 "I was expecting to see the module name next, like in these examples:"
671 , D.indent 4 $ D.vcat $
672 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
673 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
674 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
675 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
678 "Notice that the module names all start with capital letters. That is required!"
682 ModuleExposing exposing row col ->
683 toExposingReport source exposing row col
685 PortModuleProblem row col ->
687 region = toRegion row col
689 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
690 Code.toSnippet source region Nothing
693 "I am parsing an `port module` declaration, but I got stuck here:"
697 "Here are some examples of valid `port module` declarations:"
698 , D.indent 4 $ D.vcat $
699 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
700 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
702 , D.link "Note" "Read" "ports" "for more help."
706 PortModuleName row col ->
708 region = toRegion row col
710 Report.Report "EXPECTING MODULE NAME" region [] $
711 Code.toSnippet source region Nothing
714 "I was parsing an `module` declaration until I got stuck here:"
718 "I was expecting to see the module name next, like in these examples:"
719 , D.indent 4 $ D.vcat $
720 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
721 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
724 "Notice that the module names start with capital letters. That is required!"
728 PortModuleExposing exposing row col ->
729 toExposingReport source exposing row col
733 region = toRegion row col
735 Report.Report "BAD MODULE DECLARATION" region [] $
736 Code.toSnippet source region Nothing
739 "I cannot parse this module declaration:"
742 "This type of module is reserved for the @elm organization. It is used to\
743 \ define certain effects, avoiding building them into the compiler."
748 region = toRegion row col
750 toBadFirstLineReport keyword =
751 Report.Report "TOO MUCH INDENTATION" region [] $
752 Code.toSnippet source region Nothing
755 "This `" ++ keyword ++ "` should not have any spaces before it:"
758 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
762 case Code.whatIsNext source row col of
763 Code.Keyword "module" -> toBadFirstLineReport "module"
764 Code.Keyword "import" -> toBadFirstLineReport "import"
765 Code.Keyword "type" -> toBadFirstLineReport "type"
766 Code.Keyword "port" -> toBadFirstLineReport "port"
768 Report.Report "SYNTAX PROBLEM" region [] $
769 Code.toSnippet source region Nothing
776 "I am not sure what is going on, but I recommend starting an Elm\
777 \ file with the following lines:"
779 [ D.fillSep [D.cyan "import","Html"]
781 , D.fillSep [D.green "main","="]
782 , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
785 "You should be able to copy those lines directly into your file. Check out\
786 \ some of the examples on https://elm-lang.org for more help getting started!"
788 "This can also happen when something is indented too much!"
792 ImportStart row col ->
793 toImportReport source row col
795 ImportName row col ->
797 region = toRegion row col
799 Report.Report "EXPECTING IMPORT NAME" region [] $
800 Code.toSnippet source region Nothing
803 "I was parsing an `import` until I got stuck here:"
807 "I was expecting to see a module name next, like in these examples:"
808 , D.indent 4 $ D.vcat $
809 [ D.fillSep [D.cyan "import","Dict"]
810 , D.fillSep [D.cyan "import","Maybe"]
811 , D.fillSep [D.cyan "import","Html.Attributes"]
812 , D.fillSep [D.cyan "import","Json.Decode"]
815 "Notice that the module names all start with capital letters. That is required!"
820 toImportReport source row col
822 ImportAlias row col ->
824 region = toRegion row col
826 Report.Report "EXECTING IMPORT ALIAS" region [] $
827 Code.toSnippet source region Nothing
830 "I was parsing an `import` until I got stuck here:"
834 "I was expecting to see an alias next, like in these examples:"
835 , D.indent 4 $ D.vcat $
836 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
837 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
838 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
841 "Notice that the alias always starts with a capital letter. That is required!"
845 ImportExposing row col ->
846 toImportReport source row col
848 ImportExposingList exposing row col ->
849 toExposingReport source exposing row col
852 toImportReport source row col
854 ImportIndentName row col ->
855 toImportReport source row col
857 ImportIndentAlias row col ->
858 toImportReport source row col
860 ImportIndentExposingList row col ->
862 region = toRegion row col
864 Report.Report "UNFINISHED IMPORT" region [] $
865 Code.toSnippet source region Nothing
868 "I was parsing an `import` until I got stuck here:"
872 "I was expecting to see the list of exposed values next. For example, here\
873 \ are two ways to expose values from the `Html` module:"
874 , D.indent 4 $ D.vcat $
875 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
876 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
879 "I generally recommend the second style. It is more explicit, making it\
880 \ much easier to figure out where values are coming from in large projects!"
886 region = toRegion row col
888 Report.Report "BAD INFIX" region [] $
889 Code.toSnippet source region Nothing
892 "Something went wrong in this infix operator declaration:"
895 "This feature is used by the @elm organization to define the\
896 \ languages built-in operators."
899 Declarations decl _ _ ->
900 toDeclarationsReport source decl
907toImportReport :: Code.Source -> Row -> Col -> Report.Report
908toImportReport source row col =
910 region = toRegion row col
912 Report.Report "UNFINISHED IMPORT" region [] $
913 Code.toSnippet source region Nothing
916 "I am partway through parsing an import, but I got stuck here:"
920 "Here are some examples of valid `import` declarations:"
921 , D.indent 4 $ D.vcat $
922 [ D.fillSep [D.cyan "import","Html"]
923 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
924 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
925 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
928 "You are probably trying to import a different module, but try to make it look like one of these examples!"
937toExposingReport :: Code.Source -> Exposing -> Row -> Col -> Report.Report
938toExposingReport source exposing startRow startCol =
940 ExposingSpace space row col ->
941 toSpaceReport source space row col
943 ExposingStart row col ->
945 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
946 region = toRegion row col
948 Report.Report "PROBLEM IN EXPOSING" region [] $
949 Code.toSnippet source surroundings (Just region)
952 "I want to parse exposed values, but I am getting stuck here:"
956 ["Exposed","values","are","always","surrounded","by","parentheses."
957 ,"So","try","adding","a",D.green "(","here?"
959 , D.toSimpleNote "Here are some valid examples of `exposing` for reference:"
960 , D.indent 4 $ D.vcat $
961 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
962 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
965 "If you are getting tripped up, you can just expose everything for now. It should\
966 \ get easier to make an explicit exposing list as you see more examples in the wild."
970 ExposingValue row col ->
971 case Code.whatIsNext source row col of
972 Code.Keyword keyword ->
974 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
975 region = toKeywordRegion row col keyword
977 Report.Report "RESERVED WORD" region [] $
978 Code.toSnippet source surroundings (Just region)
981 "I got stuck on this reserved word:"
984 "It looks like you are trying to expose `" ++ keyword ++ "` but that is a reserved word. Is there a typo?"
989 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
990 region = toKeywordRegion row col op
992 Report.Report "UNEXPECTED SYMBOL" region [] $
993 Code.toSnippet source surroundings (Just region)
996 "I got stuck on this symbol:"
1000 "If you are trying to expose an operator, add parentheses around it like this:"
1001 , D.indent 4 $ D.dullyellow (D.fromChars op) <> " -> " <> D.green ("(" <> D.fromChars op <> ")")
1007 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1008 region = toRegion row col
1010 Report.Report "PROBLEM IN EXPOSING" region [] $
1011 Code.toSnippet source surroundings (Just region)
1014 "I got stuck while parsing these exposed values:"
1018 "I do not have an exact recommendation, so here are some valid examples\
1019 \ of `exposing` for reference:"
1020 , D.indent 4 $ D.vcat $
1021 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
1022 , D.fillSep [D.cyan "import","Basics",D.cyan "exposing","(Int, Float, Bool(..), (+), not, sqrt)"]
1025 "These examples show how to expose types, variants, operators, and functions. Everything\
1026 \ should be some permutation of these examples, just with different names."
1030 ExposingOperator row col ->
1032 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1033 region = toRegion row col
1035 Report.Report "PROBLEM IN EXPOSING" region [] $
1036 Code.toSnippet source surroundings (Just region)
1039 "I just saw an open parenthesis, so I was expecting an operator next:"
1042 ["It","is","possible","to","expose","operators,","so","I","was","expecting"
1043 ,"to","see","something","like",D.dullyellow "(+)","or",D.dullyellow "(|=)"
1044 ,"or",D.dullyellow "(||)","after","I","saw","that","open","parenthesis."
1048 ExposingOperatorReserved op row col ->
1050 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1051 region = toRegion row col
1053 Report.Report "RESERVED SYMBOL" region [] $
1054 Code.toSnippet source surroundings (Just region)
1057 "I cannot expose this as an operator:"
1060 BadDot -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1061 BadPipe -> D.fillSep ["Maybe","you","want",D.dullyellow "(||)","instead?"]
1062 BadArrow -> D.reflow "Try getting rid of this entry? Maybe I can give you a better hint after that?"
1063 BadEquals -> D.fillSep ["Maybe","you","want",D.dullyellow "(==)","instead?"]
1064 BadHasType -> D.fillSep ["Maybe","you","want",D.dullyellow "(::)","instead?"]
1067 ExposingOperatorRightParen row col ->
1069 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1070 region = toRegion row col
1072 Report.Report "PROBLEM IN EXPOSING" region [] $
1073 Code.toSnippet source surroundings (Just region)
1076 "It looks like you are exposing an operator, but I got stuck here:"
1079 ["I","was","expecting","to","see","the","closing","parenthesis","immediately"
1080 ,"after","the","operator.","Try","adding","a",D.green ")","right","here?"
1084 ExposingEnd row col ->
1086 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1087 region = toRegion row col
1089 Report.Report "UNFINISHED EXPOSING" region [] $
1090 Code.toSnippet source surroundings (Just region)
1093 "I was partway through parsing exposed values, but I got stuck here:"
1096 "Maybe there is a comma missing before this?"
1099 ExposingTypePrivacy row col ->
1101 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1102 region = toRegion row col
1104 Report.Report "PROBLEM EXPOSING CUSTOM TYPE VARIANTS" region [] $
1105 Code.toSnippet source surroundings (Just region)
1108 "It looks like you are trying to expose the variants of a custom type:"
1112 ["You","need","to","write","something","like"
1113 ,D.dullyellow "Status(..)","or",D.dullyellow "Entity(..)"
1114 ,"though.","It","is","all","or","nothing,","otherwise","`case`"
1115 ,"expressions","could","miss","a","variant","and","crash!"
1118 "It is often best to keep the variants hidden! If someone pattern matches on\
1119 \ the variants, it is a MAJOR change if any new variants are added. Suddenly\
1120 \ their `case` expressions do not cover all variants! So if you do not need\
1121 \ people to pattern match, keep the variants hidden and expose functions to\
1122 \ construct values of this type. This way you can add new variants as a MINOR change!"
1126 ExposingIndentEnd row col ->
1128 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1129 region = toRegion row col
1131 Report.Report "UNFINISHED EXPOSING" region [] $
1132 Code.toSnippet source surroundings (Just region)
1135 "I was partway through parsing exposed values, but I got stuck here:"
1139 ["I","was","expecting","a","closing","parenthesis."
1140 ,"Try","adding","a",D.green ")","right","here?"
1143 "I can get confused when there is not enough indentation, so if you already\
1144 \ have a closing parenthesis, it probably just needs some spaces in front of it."
1148 ExposingIndentValue row col ->
1150 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1151 region = toRegion row col
1153 Report.Report "UNFINISHED EXPOSING" region [] $
1154 Code.toSnippet source surroundings (Just region)
1157 "I was partway through parsing exposed values, but I got stuck here:"
1160 "I was expecting another value to expose."
1168toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
1169toSpaceReport source space row col =
1173 region = toRegion row col
1175 Report.Report "NO TABS" region [] $
1176 Code.toSnippet source region Nothing
1179 "I ran into a tab, but tabs are not allowed in Elm files."
1182 "Replace the tab with spaces."
1185 EndlessMultiComment ->
1187 region = toWiderRegion row col 2
1189 Report.Report "ENDLESS COMMENT" region [] $
1190 Code.toSnippet source region Nothing
1193 "I cannot find the end of this multi-line comment:"
1196 [ D.reflow "Add a -} somewhere after this to end the comment."
1198 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
1199 \ that happens to contain another comment. Like parentheses and curly braces,\
1200 \ the start and end markers must always be balanced. Maybe that is the problem?"
1209toRegion :: Row -> Col -> A.Region
1212 pos = A.Position row col
1217toWiderRegion :: Row -> Col -> Word16 -> A.Region
1218toWiderRegion row col extra =
1220 (A.Position row col)
1221 (A.Position row (col + extra))
1224toKeywordRegion :: Row -> Col -> [Char.Char] -> A.Region
1225toKeywordRegion row col keyword =
1227 (A.Position row col)
1228 (A.Position row (col + fromIntegral (length keyword)))
1231toDeclarationsReport :: Code.Source -> Decl -> Report.Report
1232toDeclarationsReport source decl =
1234 DeclStart row col ->
1235 case Code.whatIsNext source row col of
1236 Code.Close term bracket ->
1238 region = toRegion row col
1240 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1241 Code.toSnippet source region Nothing
1244 "I was not expecting to see a " ++ term ++ " here:"
1246 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1249 Code.Keyword keyword ->
1251 region = toKeywordRegion row col keyword
1253 Report.Report "RESERVED WORD" region [] $
1254 Code.toSnippet source region Nothing
1257 "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1262 "It is reserved for declaring imports at the top of your module. If you want\
1263 \ another import, try moving it up top with the other imports. If you want to\
1264 \ define a value or function, try changing the name to something else!"
1269 "It is reserved for writing `case` expressions. Try using a different name?"
1271 "If you are trying to write a `case` expression, it needs to be part of a\
1272 \ definition. So you could write something like this instead:"
1274 [ D.indent 0 $ D.fillSep [D.green "getWidth","maybeWidth","="]
1275 , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1276 , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1277 , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1279 , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1280 , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1283 "This defines a `getWidth` function that we can use elsewhere in our program."
1289 "It is reserved for writing `if` expressions. Try using a different name?"
1291 "If you are trying to write an `if` expression, it needs to be part of a\
1292 \ definition. So you could write something like this instead:"
1294 [ D.indent 0 $ D.fillSep [D.green "reviewPowerLevel","powerLevel","="]
1295 , D.indent 2 $ D.fillSep $
1296 [D.cyan "if","powerLevel",">",D.dullyellow "9000"
1297 ,D.cyan "then",D.dullyellow "\"OVER 9000!!!\""
1298 ,D.cyan "else",D.dullyellow "\"not bad\""
1302 "This defines a `reviewPowerLevel` function that we can use elsewhere in our program."
1307 "It is a reserved word. Try changing the name to something else?"
1312 region = toRegion row col
1314 Report.Report "SYNTAX PROBLEM" region [] $
1315 Code.toSnippet source region Nothing
1318 "I was expecting to see a new declaration here:"
1322 "I am not sure what is going wrong exactly, but here are a couple valid\
1323 \ declarations for reference:"
1325 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1326 , D.fillSep [D.green "add","x","y","="]
1327 , D.fillSep [" ","x","+","y"]
1329 , D.fillSep [D.cyan "type",D.green "User","=","Anonymous","|","LoggedIn String"]
1331 "Note that all declarations start with lower-case letters in Elm. Capitalization\
1332 \ makes a difference, so be consious of that if you are working from examples!"
1336 DeclSpace space row col ->
1337 toSpaceReport source space row col
1339 Port port_ row col ->
1340 toPortReport source port_ row col
1342 DeclType declType row col ->
1343 toDeclTypeReport source declType row col
1345 DeclDef name declDef row col ->
1346 toDeclDefReport source name declDef row col
1348 DeclFreshLineAfterDocComment row col ->
1350 region = toRegion row col
1352 Report.Report "EXPECTING DECLARATION" region [] $
1353 Code.toSnippet source region Nothing
1356 "I just saw a doc comment, but then I got stuck here:"
1359 "I was expecting to see the corresponding declaration next, starting on a fresh\
1360 \ line with no indentation."
1368toPortReport :: Code.Source -> Port -> Row -> Col -> Report.Report
1369toPortReport source port_ startRow startCol =
1371 PortSpace space row col ->
1372 toSpaceReport source space row col
1375 case Code.whatIsNext source row col of
1376 Code.Keyword keyword ->
1378 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1379 region = toKeywordRegion row col keyword
1381 Report.Report "RESERVED WORD" region [] $
1382 Code.toSnippet source surroundings (Just region)
1385 "I cannot handle ports with names like this:"
1388 "You are trying to make a port named `" ++ keyword
1389 ++ "` but that is a reserved word. Try using some other name?"
1394 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1395 region = toRegion row col
1397 Report.Report "PORT PROBLEM" region [] $
1398 Code.toSnippet source surroundings (Just region)
1401 "I just saw the start of a `port` declaration, but then I got stuck here:"
1405 ["I","was","expecting","to","see","a","name","like"
1406 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1407 ,"Something","that","starts","with","a","lower-case","letter."
1413 PortColon row col ->
1415 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1416 region = toRegion row col
1418 Report.Report "PORT PROBLEM" region [] $
1419 Code.toSnippet source surroundings (Just region)
1422 "I just saw the start of a `port` declaration, but then I got stuck here:"
1426 "I was expecting to see a colon next. And then a type that tells me\
1427 \ what type of values are going to flow through."
1432 PortType tipe row col ->
1433 toTypeReport source TC_Port tipe row col
1435 PortIndentName row col ->
1437 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1438 region = toRegion row col
1440 Report.Report "UNFINISHED PORT" region [] $
1441 Code.toSnippet source surroundings (Just region)
1444 "I just saw the start of a `port` declaration, but then I got stuck here:"
1448 ["I","was","expecting","to","see","a","name","like"
1449 ,D.dullyellow "send","or",D.dullyellow "receive","next."
1450 ,"Something","that","starts","with","a","lower-case","letter."
1456 PortIndentColon row col ->
1458 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1459 region = toRegion row col
1461 Report.Report "UNFINISHED PORT" region [] $
1462 Code.toSnippet source surroundings (Just region)
1465 "I just saw the start of a `port` declaration, but then I got stuck here:"
1469 "I was expecting to see a colon next. And then a type that tells me\
1470 \ what type of values are going to flow through."
1475 PortIndentType row col ->
1477 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1478 region = toRegion row col
1480 Report.Report "UNFINISHED PORT" region [] $
1481 Code.toSnippet source surroundings (Just region)
1484 "I just saw the start of a `port` declaration, but then I got stuck here:"
1488 "I was expecting to see a type next. Here are examples of outgoing and\
1489 \ incoming ports for reference:"
1491 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1492 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1495 "The first line defines a `send` port so you can send strings out to JavaScript.\
1496 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1497 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1498 \ get receive messages when new WebSocket messages come in or when an entry in\
1499 \ IndexedDB changes for some external reason."
1508 "Here are some example `port` declarations for reference:"
1510 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
1511 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
1514 "The first line defines a `send` port so you can send strings out to JavaScript.\
1515 \ Maybe you send them on a WebSocket or put them into IndexedDB. The second line\
1516 \ defines a `receive` port so you can receive strings from JavaScript. Maybe you\
1517 \ get receive messages when new WebSocket messages come in or when the IndexedDB\
1518 \ is changed for some external reason."
1526toDeclTypeReport :: Code.Source -> DeclType -> Row -> Col -> Report.Report
1527toDeclTypeReport source declType startRow startCol =
1529 DT_Space space row col ->
1530 toSpaceReport source space row col
1534 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1535 region = toRegion row col
1537 Report.Report "EXPECTING TYPE NAME" region [] $
1538 Code.toSnippet source surroundings (Just region)
1541 "I think I am parsing a type declaration, but I got stuck here:"
1545 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1546 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1552 DT_Alias typeAlias row col ->
1553 toTypeAliasReport source typeAlias row col
1555 DT_Union customType row col ->
1556 toCustomTypeReport source customType row col
1558 DT_IndentName row col ->
1560 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1561 region = toRegion row col
1563 Report.Report "EXPECTING TYPE NAME" region [] $
1564 Code.toSnippet source surroundings (Just region)
1567 "I think I am parsing a type declaration, but I got stuck here:"
1571 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1572 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1579toTypeAliasReport :: Code.Source -> TypeAlias -> Row -> Col -> Report.Report
1580toTypeAliasReport source typeAlias startRow startCol =
1582 AliasSpace space row col ->
1583 toSpaceReport source space row col
1585 AliasName row col ->
1587 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1588 region = toRegion row col
1590 Report.Report "EXPECTING TYPE ALIAS NAME" region [] $
1591 Code.toSnippet source surroundings (Just region)
1594 "I am partway through parsing a type alias, but I got stuck here:"
1598 ["I","was","expecting","a","name","like",D.dullyellow "Person","or",D.dullyellow "Point"
1599 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1605 AliasEquals row col ->
1606 case Code.whatIsNext source row col of
1607 Code.Keyword keyword ->
1609 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1610 region = toKeywordRegion row col keyword
1612 Report.Report "RESERVED WORD" region [] $
1613 Code.toSnippet source surroundings (Just region)
1616 "I ran into a reserved word unexpectedly while parsing this type alias:"
1620 "It looks like you are trying use `" ++ keyword
1621 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1628 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1629 region = toRegion row col
1631 Report.Report "PROBLEM IN TYPE ALIAS" region [] $
1632 Code.toSnippet source surroundings (Just region)
1635 "I am partway through parsing a type alias, but I got stuck here:"
1639 "I was expecting to see a type variable or an an equals sign next."
1644 AliasBody tipe row col ->
1645 toTypeReport source TC_TypeAlias tipe row col
1647 AliasIndentEquals row col ->
1649 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1650 region = toRegion row col
1652 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1653 Code.toSnippet source surroundings (Just region)
1656 "I am partway through parsing a type alias, but I got stuck here:"
1660 "I was expecting to see a type variable or an an equals sign next."
1665 AliasIndentBody row col ->
1667 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1668 region = toRegion row col
1670 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1671 Code.toSnippet source surroundings (Just region)
1674 "I am partway through parsing a type alias, but I got stuck here:"
1678 ["I","was","expecting","to","see","a","type","next.","Something","as","simple"
1679 ,"as",D.dullyellow "Int","or",D.dullyellow "Float","would","work!"
1686typeAliasNote :: D.Doc
1690 "Here is an example of a valid `type alias` for reference:"
1692 [ D.indent 0 $ D.fillSep [D.cyan "type",D.cyan "alias",D.green "Person","="]
1693 , D.indent 2 $ D.vcat $
1701 "This would let us use `Person` as a shorthand for that record type. Using this\
1702 \ shorthand makes type annotations much easier to read, and makes changing code\
1703 \ easier if you decide later that there is more to a person than age and height!"
1707toCustomTypeReport :: Code.Source -> CustomType -> Row -> Col -> Report.Report
1708toCustomTypeReport source customType startRow startCol =
1710 CT_Space space row col ->
1711 toSpaceReport source space row col
1715 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1716 region = toRegion row col
1718 Report.Report "EXPECTING TYPE NAME" region [] $
1719 Code.toSnippet source surroundings (Just region)
1722 "I think I am parsing a type declaration, but I got stuck here:"
1726 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1727 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1733 CT_Equals row col ->
1734 case Code.whatIsNext source row col of
1735 Code.Keyword keyword ->
1737 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1738 region = toKeywordRegion row col keyword
1740 Report.Report "RESERVED WORD" region [] $
1741 Code.toSnippet source surroundings (Just region)
1744 "I ran into a reserved word unexpectedly while parsing this custom type:"
1748 "It looks like you are trying use `" ++ keyword
1749 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1756 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1757 region = toRegion row col
1759 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1760 Code.toSnippet source surroundings (Just region)
1763 "I am partway through parsing a custom type, but I got stuck here:"
1767 "I was expecting to see a type variable or an an equals sign next."
1774 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1775 region = toRegion row col
1777 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1778 Code.toSnippet source surroundings (Just region)
1781 "I am partway through parsing a custom type, but I got stuck here:"
1785 "I was expecting to see a vertical bar like | next."
1790 CT_Variant row col ->
1792 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1793 region = toRegion row col
1795 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1796 Code.toSnippet source surroundings (Just region)
1799 "I am partway through parsing a custom type, but I got stuck here:"
1803 ["I","was","expecting","to","see","a","variant","name","next."
1804 ,"Something","like",D.dullyellow "Success","or",D.dullyellow "Sandwich" <> "."
1805 ,"Any","name","that","starts","with","a","capital","letter","really!"
1811 CT_VariantArg tipe row col ->
1812 toTypeReport source TC_CustomType tipe row col
1814 CT_IndentEquals row col ->
1816 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1817 region = toRegion row col
1819 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1820 Code.toSnippet source surroundings (Just region)
1823 "I am partway through parsing a custom type, but I got stuck here:"
1827 "I was expecting to see a type variable or an an equals sign next."
1832 CT_IndentBar row col ->
1834 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1835 region = toRegion row col
1837 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1838 Code.toSnippet source surroundings (Just region)
1841 "I am partway through parsing a custom type, but I got stuck here:"
1845 "I was expecting to see a vertical bar like | next."
1850 CT_IndentAfterBar row col ->
1852 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1853 region = toRegion row col
1855 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1856 Code.toSnippet source surroundings (Just region)
1859 "I am partway through parsing a custom type, but I got stuck here:"
1863 "I just saw a vertical bar, so I was expecting to see another variant defined next."
1868 CT_IndentAfterEquals row col ->
1870 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1871 region = toRegion row col
1873 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1874 Code.toSnippet source surroundings (Just region)
1877 "I am partway through parsing a custom type, but I got stuck here:"
1881 "I just saw an equals sign, so I was expecting to see the first variant defined next."
1887customTypeNote :: D.Doc
1891 "Here is an example of a valid `type` declaration for reference:"
1893 [ D.indent 0 $ D.fillSep [D.cyan "type",D.green "Status"]
1894 , D.indent 2 $ D.fillSep ["=","Failure"]
1895 , D.indent 2 $ D.fillSep ["|","Waiting"]
1896 , D.indent 2 $ D.fillSep ["|","Success","String"]
1899 "This defines a new `Status` type with three variants. This could be useful if\
1900 \ we are waiting for an HTTP request. Maybe we start with `Waiting` and then\
1901 \ switch to `Failure` or `Success \"message from server\"` depending on how\
1902 \ things go. Notice that the Success variant has some associated data, allowing\
1903 \ us to store a String if the request goes well!"
1911toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
1912toDeclDefReport source name declDef startRow startCol =
1914 DeclDefSpace space row col ->
1915 toSpaceReport source space row col
1917 DeclDefEquals row col ->
1918 case Code.whatIsNext source row col of
1919 Code.Keyword keyword ->
1921 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1922 region = toKeywordRegion row col keyword
1924 Report.Report "RESERVED WORD" region [] $
1925 Code.toSnippet source surroundings (Just region)
1928 "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
1931 "This is a reserved word! Try using some other name?"
1936 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1937 region = toKeywordRegion row col op
1939 Report.Report "UNEXPECTED SYMBOL" region [] $
1940 Code.toSnippet source surroundings (Just region)
1943 "I was not expecting to see this symbol here:"
1947 "I am not sure what is going wrong exactly, so here is a valid\
1948 \ definition (with an optional type annotation) for reference:"
1950 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1951 , D.fillSep [D.green "add","x","y","="]
1952 , D.fillSep [" ","x","+","y"]
1955 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
1961 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1962 region = toRegion row col
1964 Report.Report "PROBLEM IN DEFINITION" region [] $
1965 Code.toSnippet source surroundings (Just region)
1968 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
1972 "I am not sure what is going wrong exactly, so here is a valid\
1973 \ definition (with an optional type annotation) for reference:"
1975 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1976 , D.fillSep [D.green "add","x","y","="]
1977 , D.fillSep [" ","x","+","y"]
1980 "Try to use that format!"
1984 DeclDefType tipe row col ->
1985 toTypeReport source (TC_Annotation name) tipe row col
1987 DeclDefArg pattern row col ->
1988 toPatternReport source PArg pattern row col
1990 DeclDefBody expr row col ->
1991 toExprReport source (InDef name startRow startCol) expr row col
1993 DeclDefNameRepeat row col ->
1995 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1996 region = toRegion row col
1998 Report.Report "EXPECTING DEFINITION" region [] $
1999 Code.toSnippet source surroundings (Just region)
2002 "I just saw the type annotation for `" ++ Name.toChars name
2003 ++ "` so I was expecting to see its definition here:"
2007 "Type annotations always appear directly above the relevant\
2008 \ definition, without anything else in between. (Not even doc comments!)"
2013 DeclDefNameMatch defName row col ->
2015 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2016 region = toRegion row col
2018 Report.Report "NAME MISMATCH" region [] $
2019 Code.toSnippet source surroundings (Just region)
2022 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
2026 "These names do not match! Is there a typo?"
2027 , D.indent 4 $ D.fillSep $
2028 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
2032 DeclDefIndentType row col ->
2034 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2035 region = toRegion row col
2037 Report.Report "UNFINISHED DEFINITION" region [] $
2038 Code.toSnippet source surroundings (Just region)
2041 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
2045 "I just saw a colon, so I am expecting to see a type next."
2050 DeclDefIndentEquals row col ->
2052 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2053 region = toRegion row col
2055 Report.Report "UNFINISHED DEFINITION" region [] $
2056 Code.toSnippet source surroundings (Just region)
2059 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2063 "I was expecting to see an argument or an equals sign next."
2068 DeclDefIndentBody row col ->
2070 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2071 region = toRegion row col
2073 Report.Report "UNFINISHED DEFINITION" region [] $
2074 Code.toSnippet source surroundings (Just region)
2077 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
2081 "I was expecting to see an expression next. What is it equal to?"
2091 "Here is a valid definition (with a type annotation) for reference:"
2093 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2094 , D.fillSep [D.green "add","x","y","="]
2095 , D.fillSep [" ","x","+","y"]
2098 "The top line (called a \"type annotation\") is optional. You can leave it off\
2099 \ if you want. As you get more comfortable with Elm and as your project grows,\
2100 \ it becomes more and more valuable to add them though! They work great as\
2101 \ compiler-verified documentation, and they often improve error messages!"
2110 = InNode Node Row Col Context
2111 | InDef Name.Name Row Col
2112 | InDestruct Row Col
2128getDefName :: Context -> Maybe Name.Name
2131 InDestruct _ _ -> Nothing
2132 InDef name _ _ -> Just name
2133 InNode _ _ _ c -> getDefName c
2136isWithin :: Node -> Context -> Bool
2137isWithin desiredNode context =
2139 InDestruct _ _ -> False
2140 InDef _ _ _ -> False
2141 InNode actualNode _ _ _ -> desiredNode == actualNode
2148toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
2149toExprReport source context expr startRow startCol =
2152 toLetReport source context let_ row col
2154 Case case_ row col ->
2155 toCaseReport source context case_ row col
2158 toIfReport source context if_ row col
2160 List list row col ->
2161 toListReport source context list row col
2163 Record record row col ->
2164 toRecordReport source context record row col
2166 Tuple tuple row col ->
2167 toTupleReport source context tuple row col
2169 Func func row col ->
2170 toFuncReport source context func row col
2173 let region = toRegion row col in
2174 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2175 Code.toSnippet source region Nothing
2178 "I was expecting to see a record accessor here:"
2181 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2182 ,"that","accesses","a","value","from","a","record."
2187 let region = toRegion row col in
2188 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
2189 Code.toSnippet source region Nothing
2192 "I am trying to parse a record accessor here:"
2197 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
2198 ,"that","accesses","a","value","from","a","record."
2202 "Record field names must start with a lower case letter!"
2206 OperatorRight op row col ->
2207 let region = toRegion row col in
2208 Report.Report "MISSING EXPRESSION" region [] $
2209 Code.toSnippet source region Nothing
2212 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
2216 ["You","can","just","put","anything","for","now,","like"
2217 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
2218 ,"Once","there","is","something","there,","I","can","probably"
2219 ,"give","a","more","specific","hint!"
2222 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
2223 \ Or if I run into operators in unexpected spots. Point is, there are a\
2224 \ couple ways I can get confused and give sort of weird advice!"
2228 OperatorReserved operator row col ->
2229 toOperatorReport source context operator row col
2233 (contextRow, contextCol, aThing) =
2235 InDestruct r c -> (r, c, "a definition")
2236 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
2237 InNode NRecord r c _ -> (r, c, "a record")
2238 InNode NParens r c _ -> (r, c, "some parentheses")
2239 InNode NList r c _ -> (r, c, "a list")
2240 InNode NFunc r c _ -> (r, c, "an anonymous function")
2241 InNode NCond r c _ -> (r, c, "an `if` expression")
2242 InNode NThen r c _ -> (r, c, "an `if` expression")
2243 InNode NElse r c _ -> (r, c, "an `if` expression")
2244 InNode NCase r c _ -> (r, c, "a `case` expression")
2245 InNode NBranch r c _ -> (r, c, "a `case` expression")
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?"
2411 "For a string that spans multiple lines, you can use the multi-line string\
2412 \ syntax like this:"
2414 [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2416 , D.dullyellow "# Multi-line Strings"
2418 , D.dullyellow "- start with triple double quotes"
2419 , D.dullyellow "- write whatever you want"
2420 , D.dullyellow "- no need to escape newlines or double quotes"
2421 , D.dullyellow "- end with triple double quotes"
2423 , D.dullyellow "\"\"\""
2428 StringEndless_Multi ->
2430 region = toWiderRegion row col 3
2432 Report.Report "ENDLESS STRING" region [] $
2433 Code.toSnippet source region Nothing
2436 "I cannot find the end of this multi-line string:"
2439 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
2441 "Here is a valid multi-line string for reference:"
2443 [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2445 , D.dullyellow "# Multi-line Strings"
2447 , D.dullyellow "- start with triple double quotes"
2448 , D.dullyellow "- write whatever you want"
2449 , D.dullyellow "- no need to escape newlines or double quotes"
2450 , D.dullyellow "- end with triple double quotes"
2452 , D.dullyellow "\"\"\""
2457 StringEscape escape ->
2458 toEscapeReport source escape row col
2465toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
2466toEscapeReport source escape row col =
2470 region = toWiderRegion row col 2
2472 Report.Report "UNKNOWN ESCAPE" region [] $
2473 Code.toSnippet source region Nothing
2476 "Backslashes always start escaped characters, but I do not recognize this one:"
2480 "Valid escape characters include:"
2481 , D.dullyellow $ D.indent 4 $ D.vcat $
2491 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
2493 "The last style lets encode ANY character by its Unicode code\
2494 \ point. That means \\u{0009} and \\t are the same. You can use\
2495 \ that style for anything not covered by the other six escapes!"
2499 BadUnicodeFormat width ->
2501 region = toWiderRegion row col width
2503 Report.Report "BAD UNICODE ESCAPE" region [] $
2504 Code.toSnippet source region Nothing
2507 "I ran into an invalid Unicode escape:"
2511 "Here are some examples of valid Unicode escapes:"
2512 , D.dullyellow $ D.indent 4 $ D.vcat $
2519 "Notice that the code point is always surrounded by curly braces.\
2520 \ Maybe you are missing the opening or closing curly brace?"
2523 BadUnicodeCode width ->
2525 region = toWiderRegion row col width
2527 Report.Report "BAD UNICODE ESCAPE" region [] $
2528 Code.toSnippet source region Nothing
2531 "This is not a valid code point:"
2534 "The valid code points are between 0 and 10FFFF inclusive."
2537 BadUnicodeLength width numDigits badCode ->
2539 region = toWiderRegion row col width
2541 Report.Report "BAD UNICODE ESCAPE" region [] $
2542 Code.toSnippet source region Nothing $
2543 if numDigits < 4 then
2546 "Every code point needs at least four digits:"
2549 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
2550 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
2552 D.fillSep ["Try",D.green suggestion,"instead?"]
2558 "This code point has too many digits:"
2561 ["Valid","code","points","are","between"
2562 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
2563 ,"so","try","trimming","any","leading","zeros","until"
2564 ,"you","have","between","four","and","six","digits."
2573toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
2574toNumberReport source number row col =
2576 region = toRegion row col
2580 Report.Report "WEIRD NUMBER" region [] $
2581 Code.toSnippet source region Nothing
2584 "I thought I was reading a number, but I ran into some weird stuff here:"
2588 "I recognize numbers in the following formats:"
2589 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
2591 "So is there a way to write it like one of those?"
2596 Report.Report "WEIRD NUMBER" region [] $
2597 Code.toSnippet source region Nothing
2600 "Numbers cannot end with a dot like this:"
2603 ["Switching","to",D.green (D.fromChars (show int))
2604 ,"or",D.green (D.fromChars (show int ++ ".0"))
2605 ,"will","work","though!"
2610 Report.Report "WEIRD HEXIDECIMAL" region [] $
2611 Code.toSnippet source region Nothing
2614 "I thought I was reading a hexidecimal number until I got here:"
2618 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
2619 \ only recognize things like this:"
2620 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
2624 NumberNoLeadingZero ->
2625 Report.Report "LEADING ZEROS" region [] $
2626 Code.toSnippet source region Nothing
2629 "I do not accept numbers with leading zeros:"
2633 "Just delete the leading zeros and it should work!"
2635 "Some languages let you to specify octal numbers by adding a leading zero.\
2636 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
2637 \ that, but others probably want it to equal 111. Either path is going to\
2638 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
2648toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
2649toOperatorReport source context operator row col =
2653 region = toRegion row col
2655 Report.Report "UNEXPECTED SYMBOL" region [] $
2656 Code.toSnippet source region Nothing
2658 "I was not expecting this dot:"
2661 "Dots are for record access and decimal points, so\
2662 \ they cannot float around on their own. Maybe\
2663 \ there is some extra whitespace?"
2668 region = toRegion row col
2670 Report.Report "UNEXPECTED SYMBOL" region [] $
2671 Code.toSnippet source region Nothing
2674 "I was not expecting this vertical bar:"
2677 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
2682 region = toWiderRegion row col 2
2684 Report.Report "UNEXPECTED ARROW" region [] $
2685 Code.toSnippet source region Nothing $
2686 if isWithin NBranch context then
2689 "I was not expecting to see an arrow here:"
2694 "I think I am parsing a `case` expression right now, so it makes sense to\
2695 \ see arrows around here. This one is confusing me though!"
2698 "I may be getting confused by the indentation. Every pattern in a `case` must be\
2699 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
2700 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
2701 \ indented too far?"
2708 "I was not expecting an arrow here:"
2711 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
2712 \ you want > or >= instead?"
2717 region = toRegion row col
2719 Report.Report "UNEXPECTED EQUALS" region [] $
2720 Code.toSnippet source region Nothing
2723 "I was not expecting to see this equals sign:"
2727 D.reflow "Maybe you want == instead? To check if two values are equal?"
2730 if isWithin NRecord context then
2731 "Records look like { x = 3, y = 4 } with the equals sign right\
2732 \ after the field name. So maybe you forgot a comma?"
2734 case getDefName context of
2736 "I may be getting confused by your indentation. I need all definitions to be indented\
2737 \ exactly the same amount, so if this is meant to be a new definition, it may have too\
2738 \ many spaces in front of it."
2741 "I may be getting confused by your indentation. I think I am still parsing the `"
2742 ++ Name.toChars name ++ "` definition. Is this supposed to be part of a definition\
2743 \ after that? If so, the problem may be a bit before the equals sign. I need all\
2744 \ definitions to be indented exactly the same amount, so the problem may be that\
2745 \ this new definition has too many spaces in front of it."
2751 region = toRegion row col
2753 Report.Report "UNEXPECTED SYMBOL" region [] $
2754 Code.toSnippet source region Nothing $
2757 "I was not expecting to run into the \"has type\" symbol here:"
2759 case getDefName context of
2762 ["Maybe","you","want",D.green "::","instead?"
2763 ,"To","put","something","on","the","front","of","a","list?"
2770 ["Maybe","you","want",D.green "::","instead?"
2771 ,"To","put","something","on","the","front","of","a","list?"
2774 "The single colon is reserved for type annotations and record types, but I think\
2775 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
2778 "I may be getting confused by your indentation. Is this supposed to be part of\
2779 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
2780 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
2781 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
2782 \ this new definition is indented a bit too much."
2791toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
2792toLetReport source context let_ startRow startCol =
2794 LetSpace space row col ->
2795 toSpaceReport source space row col
2799 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2800 region = toRegion row col
2802 Report.Report "LET PROBLEM" region [] $
2803 Code.toSnippet source surroundings (Just region)
2806 "I was partway through parsing a `let` expression, but I got stuck here:"
2810 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2811 ,"keyword","next.","Is","there","a","typo?"
2814 "This can also happen if you are trying to define another value within the `let` but\
2815 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2816 \ spaces before it. They should line up exactly!"
2820 LetDefAlignment _ row col ->
2822 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2823 region = toRegion row col
2825 Report.Report "LET PROBLEM" region [] $
2826 Code.toSnippet source surroundings (Just region)
2829 "I was partway through parsing a `let` expression, but I got stuck here:"
2833 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2834 ,"keyword","next.","Is","there","a","typo?"
2837 "This can also happen if you are trying to define another value within the `let` but\
2838 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2839 \ spaces before it. The should line up exactly!"
2843 LetDefName row col ->
2844 case Code.whatIsNext source row col of
2845 Code.Keyword keyword ->
2847 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2848 region = toKeywordRegion row col keyword
2850 Report.Report "RESERVED WORD" region [] $
2851 Code.toSnippet source surroundings (Just region)
2854 "I was partway through parsing a `let` expression, but I got stuck here:"
2857 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
2858 \ it is a reserved word! Try using a different name instead."
2862 toUnfinishLetReport source row col startRow startCol $
2864 "I was expecting the name of a definition next."
2866 LetDef name def row col ->
2867 toLetDefReport source name def row col
2869 LetDestruct destruct row col ->
2870 toLetDestructReport source destruct row col
2872 LetBody expr row col ->
2873 toExprReport source context expr row col
2875 LetIndentDef row col ->
2876 toUnfinishLetReport source row col startRow startCol $
2878 "I was expecting a value to be defined here."
2880 LetIndentIn row col ->
2881 toUnfinishLetReport source row col startRow startCol $
2883 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
2884 ,"Or","maybe","more","of","that","expression?"
2887 LetIndentBody row col ->
2888 toUnfinishLetReport source row col startRow startCol $
2890 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
2893toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
2894toUnfinishLetReport source row col startRow startCol message =
2896 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2897 region = toRegion row col
2899 Report.Report "UNFINISHED LET" region [] $
2900 Code.toSnippet source surroundings (Just region)
2903 "I was partway through parsing a `let` expression, but I got stuck here:"
2908 "Here is an example with a valid `let` expression for reference:"
2910 [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
2911 , D.indent 2 $ D.fillSep [D.cyan "let"]
2912 , D.indent 4 $ D.fillSep ["fullName","="]
2913 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
2914 , D.indent 2 $ D.fillSep [D.cyan "in"]
2915 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
2918 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
2919 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
2920 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
2921 \ indented a bit more than that. That is important!"
2926toLetDefReport :: Code.Source -> Name.Name -> Def -> Row -> Col -> Report.Report
2927toLetDefReport source name def startRow startCol =
2929 DefSpace space row col ->
2930 toSpaceReport source space row col
2932 DefType tipe row col ->
2933 toTypeReport source (TC_Annotation name) tipe row col
2935 DefNameRepeat row col ->
2937 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2938 region = toRegion row col
2940 Report.Report "EXPECTING DEFINITION" region [] $
2941 Code.toSnippet source surroundings (Just region)
2944 "I just saw the type annotation for `" ++ Name.toChars name
2945 ++ "` so I was expecting to see its definition here:"
2949 "Type annotations always appear directly above the relevant\
2950 \ definition, without anything else in between."
2955 DefNameMatch defName row col ->
2957 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2958 region = toRegion row col
2960 Report.Report "NAME MISMATCH" region [] $
2961 Code.toSnippet source surroundings (Just region)
2964 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
2968 "These names do not match! Is there a typo?"
2969 , D.indent 4 $ D.fillSep $
2970 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
2974 DefArg pattern row col ->
2975 toPatternReport source PArg pattern row col
2977 DefEquals row col ->
2978 case Code.whatIsNext source row col of
2979 Code.Keyword keyword ->
2981 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2982 region = toKeywordRegion row col keyword
2984 Report.Report "RESERVED WORD" region [] $
2985 Code.toSnippet source surroundings (Just region)
2988 "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
2991 "This is a reserved word! Try using some other name?"
2996 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2997 region = toKeywordRegion row col op
2999 Report.Report "UNEXPECTED SYMBOL" region [] $
3000 Code.toSnippet source surroundings (Just region)
3003 "I was not expecting to see this symbol here:"
3007 "I am not sure what is going wrong exactly, so here is a valid\
3008 \ definition (with an optional type annotation) for reference:"
3010 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3011 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3012 , D.indent 6 $ D.fillSep ["x","+","y"]
3015 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
3021 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3022 region = toRegion row col
3024 Report.Report "PROBLEM IN DEFINITION" region [] $
3025 Code.toSnippet source surroundings (Just region)
3028 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3032 "I am not sure what is going wrong exactly, so here is a valid\
3033 \ definition (with an optional type annotation) for reference:"
3035 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3036 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3037 , D.indent 4 $ D.fillSep ["x","+","y"]
3040 "Try to use that format!"
3044 DefBody expr row col ->
3045 toExprReport source (InDef name startRow startCol) expr row col
3047 DefIndentEquals row col ->
3049 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3050 region = toRegion row col
3052 Report.Report "UNFINISHED DEFINITION" region [] $
3053 Code.toSnippet source surroundings (Just region)
3056 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3060 "I was expecting to see an argument or an equals sign next."
3065 DefIndentType row col ->
3067 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3068 region = toRegion row col
3070 Report.Report "UNFINISHED DEFINITION" region [] $
3071 Code.toSnippet source surroundings (Just region)
3074 "I got stuck while parsing the `" ++ Name.toChars name ++ "` type annotation:"
3078 "I just saw a colon, so I am expecting to see a type next."
3083 DefIndentBody row col ->
3085 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3086 region = toRegion row col
3088 Report.Report "UNFINISHED DEFINITION" region [] $
3089 Code.toSnippet source surroundings (Just region)
3092 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3096 "I was expecting to see an expression next. What is it equal to?"
3101 DefAlignment indent row col ->
3103 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3104 region = toRegion row col
3105 offset = indent - col
3107 Report.Report "PROBLEM IN DEFINITION" region [] $
3108 Code.toSnippet source surroundings (Just region)
3111 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
3114 "I just saw a type annotation indented " ++ show indent ++ " spaces, so I was\
3115 \ expecting to see the corresponding definition next with the exact same amount\
3116 \ of indentation. It looks like this line needs "
3117 ++ show offset ++ " more " ++ (if offset == 1 then "space" else "spaces") ++ "?"
3126 "Here is a valid definition (with a type annotation) for reference:"
3128 [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3129 , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3130 , D.indent 6 $ D.fillSep ["x","+","y"]
3133 "The top line (called a \"type annotation\") is optional. You can leave it off\
3134 \ if you want. As you get more comfortable with Elm and as your project grows,\
3135 \ it becomes more and more valuable to add them though! They work great as\
3136 \ compiler-verified documentation, and they often improve error messages!"
3140toLetDestructReport :: Code.Source -> Destruct -> Row -> Col -> Report.Report
3141toLetDestructReport source destruct startRow startCol =
3143 DestructSpace space row col ->
3144 toSpaceReport source space row col
3146 DestructPattern pattern row col ->
3147 toPatternReport source PLet pattern row col
3149 DestructEquals row col ->
3151 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3152 region = toRegion row col
3154 Report.Report "PROBLEM IN DEFINITION" region [] $
3155 Code.toSnippet source surroundings (Just region)
3158 "I got stuck trying to parse this definition:"
3160 case Code.whatIsNext source row col of
3161 Code.Operator ":" ->
3164 "I was expecting to see an equals sign next, followed by an expression\
3165 \ telling me what to compute."
3167 "It looks like you may be trying to write a type annotation? It is not\
3168 \ possible to add type annotations on destructuring definitions like this.\
3169 \ You can assign a name to the overall structure, put a type annotation on\
3170 \ that, and then destructure separately though."
3175 "I was expecting to see an equals sign next, followed by an expression\
3176 \ telling me what to compute."
3179 DestructBody expr row col ->
3180 toExprReport source (InDestruct startRow startCol) expr row col
3182 DestructIndentEquals row col ->
3184 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3185 region = toRegion row col
3187 Report.Report "UNFINISHED DEFINITION" region [] $
3188 Code.toSnippet source surroundings (Just region)
3191 "I got stuck trying to parse this definition:"
3194 "I was expecting to see an equals sign next, followed by an expression\
3195 \ telling me what to compute."
3198 DestructIndentBody row col ->
3200 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3201 region = toRegion row col
3203 Report.Report "UNFINISHED DEFINITION" region [] $
3204 Code.toSnippet source surroundings (Just region)
3207 "I got stuck while parsing this definition:"
3210 "I was expecting to see an expression next. What is it equal to?"
3218toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
3219toCaseReport source context case_ startRow startCol =
3221 CaseSpace space row col ->
3222 toSpaceReport source space row col
3225 toUnfinishCaseReport source row col startRow startCol $
3226 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3228 CasePattern pattern row col ->
3229 toPatternReport source PCase pattern row col
3231 CaseArrow row col ->
3232 case Code.whatIsNext source row col of
3233 Code.Keyword keyword ->
3235 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3236 region = toKeywordRegion row col keyword
3238 Report.Report "RESERVED WORD" region [] $
3239 Code.toSnippet source surroundings (Just region)
3242 "I am partway through parsing a `case` expression, but I got stuck here:"
3245 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
3246 \ patterns, but it is a reserved word. Try using a different name?"
3249 Code.Operator ":" ->
3251 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3252 region = toRegion row col
3254 Report.Report "UNEXPECTED OPERATOR" region [] $
3255 Code.toSnippet source surroundings (Just region)
3258 "I am partway through parsing a `case` expression, but I got stuck here:"
3261 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
3262 ,"For","pattern","matching","on","lists?"
3266 Code.Operator "=" ->
3268 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3269 region = toRegion row col
3271 Report.Report "UNEXPECTED OPERATOR" region [] $
3272 Code.toSnippet source surroundings (Just region)
3275 "I am partway through parsing a `case` expression, but I got stuck here:"
3278 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
3284 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3285 region = toRegion row col
3287 Report.Report "MISSING ARROW" region [] $
3288 Code.toSnippet source surroundings (Just region)
3291 "I am partway through parsing a `case` expression, but I got stuck here:"
3293 addNoteForCaseIndentError $
3295 "I was expecting to see an arrow next."
3298 CaseExpr expr row col ->
3299 toExprReport source (InNode NCase startRow startCol context) expr row col
3301 CaseBranch expr row col ->
3302 toExprReport source (InNode NBranch startRow startCol context) expr row col
3304 CaseIndentOf row col ->
3305 toUnfinishCaseReport source row col startRow startCol $
3306 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
3308 CaseIndentExpr row col ->
3309 toUnfinishCaseReport source row col startRow startCol $
3310 D.reflow "I was expecting to see a expression next."
3312 CaseIndentPattern row col ->
3313 toUnfinishCaseReport source row col startRow startCol $
3314 D.reflow "I was expecting to see a pattern next."
3316 CaseIndentArrow row col ->
3317 toUnfinishCaseReport source row col startRow startCol $
3319 ["I","just","saw","a","pattern,","so","I","was","expecting"
3320 ,"to","see","a",D.dullyellow "->","next."
3323 CaseIndentBranch row col ->
3324 toUnfinishCaseReport source row col startRow startCol $
3326 "I was expecting to see an expression next. What should I do when\
3327 \ I run into this particular pattern?"
3329 CasePatternAlignment indent row col ->
3330 toUnfinishCaseReport source row col startRow startCol $
3332 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
3335toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3336toUnfinishCaseReport source row col startRow startCol message =
3338 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3339 region = toRegion row col
3341 Report.Report "UNFINISHED CASE" region [] $
3342 Code.toSnippet source surroundings (Just region)
3345 "I was partway through parsing a `case` expression, but I got stuck here:"
3350 "Here is an example of a valid `case` expression for reference."
3352 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3353 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3354 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3356 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3357 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3360 "Notice the indentation. Each pattern is aligned, and each branch is indented\
3361 \ a bit more than the corresponding pattern. That is important!"
3366addNoteForCaseIndentError :: D.Doc -> D.Doc
3367addNoteForCaseIndentError message =
3372 "Sometimes I get confused by indentation, so try to make your `case` look\
3373 \ something like this:"
3375 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
3376 , D.indent 6 $ D.fillSep [D.blue "Just","width","->"]
3377 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
3379 , D.indent 6 $ D.fillSep [D.blue "Nothing","->"]
3380 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
3383 "Notice the indentation! Each pattern is aligned, and each branch is indented\
3384 \ a bit more than the corresponding pattern. That is important!"
3392toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
3393toIfReport source context if_ startRow startCol =
3395 IfSpace space row col ->
3396 toSpaceReport source space row col
3400 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3401 region = toRegion row col
3403 Report.Report "UNFINISHED IF" region [] $
3404 Code.toSnippet source surroundings (Just region)
3407 "I was expecting to see more of this `if` expression, but I got stuck here:"
3410 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3416 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3417 region = toRegion row col
3419 Report.Report "UNFINISHED IF" region [] $
3420 Code.toSnippet source surroundings (Just region)
3423 "I was expecting to see more of this `if` expression, but I got stuck here:"
3426 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
3430 IfElseBranchStart row col ->
3432 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3433 region = toRegion row col
3435 Report.Report "UNFINISHED IF" region [] $
3436 Code.toSnippet source surroundings (Just region)
3439 "I just saw the start of an `else` branch, but then I got stuck here:"
3442 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3445 IfCondition expr row col ->
3446 toExprReport source (InNode NCond startRow startCol context) expr row col
3448 IfThenBranch expr row col ->
3449 toExprReport source (InNode NThen startRow startCol context) expr row col
3451 IfElseBranch expr row col ->
3452 toExprReport source (InNode NElse startRow startCol context) expr row col
3454 IfIndentCondition row col ->
3456 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3457 region = toRegion row col
3459 Report.Report "UNFINISHED IF" region [] $
3460 Code.toSnippet source surroundings (Just region)
3463 "I was expecting to see more of this `if` expression, but I got stuck here:"
3467 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
3468 ,"that","evaluates","to","True","or","False."
3471 "I can be confused by indentation. Maybe something is not indented enough?"
3475 IfIndentThen row col ->
3477 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3478 region = toRegion row col
3480 Report.Report "UNFINISHED IF" region [] $
3481 Code.toSnippet source surroundings (Just region)
3484 "I was expecting to see more of this `if` expression, but I got stuck here:"
3488 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
3491 "I can be confused by indentation. Maybe something is not indented enough?"
3495 IfIndentThenBranch row col ->
3497 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3498 region = toRegion row col
3500 Report.Report "UNFINISHED IF" region [] $
3501 Code.toSnippet source surroundings (Just region)
3504 "I got stuck after the start of this `then` branch:"
3508 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3510 "I can be confused by indentation, so if the `then` branch is already\
3511 \ present, it may not be indented enough for me to recognize it."
3515 IfIndentElseBranch row col ->
3517 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3518 region = toRegion row col
3520 Report.Report "UNFINISHED IF" region [] $
3521 Code.toSnippet source surroundings (Just region)
3524 "I got stuck after the start of this `else` branch:"
3528 "I was expecting to see an expression next. Maybe it is not filled in yet?"
3530 "I can be confused by indentation, so if the `else` branch is already\
3531 \ present, it may not be indented enough for me to recognize it."
3535 IfIndentElse row col ->
3537 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3538 region = toRegion row col
3540 Report.Report "UNFINISHED IF" region [] $
3541 Code.toSnippet source surroundings (Just region)
3544 "I was expecting to see an `else` branch after this:"
3548 "I know what to do when the condition is `True`, but not when it is `False`."
3550 ["Add","an",D.cyan "else","branch","to","handle","that","scenario!"]
3559toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
3560toRecordReport source context record startRow startCol =
3562 RecordOpen row col ->
3563 case Code.whatIsNext source row col of
3564 Code.Keyword keyword ->
3566 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3567 region = toKeywordRegion row col keyword
3569 Report.Report "RESERVED WORD" region [] $
3570 Code.toSnippet source surroundings (Just region)
3573 "I just started parsing a record, but I got stuck on this field name:"
3576 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3577 \ that is a reserved word. Try using a different name!"
3582 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3583 region = toRegion row col
3585 Report.Report "UNFINISHED RECORD" region [] $
3586 Code.toSnippet source surroundings (Just region)
3589 "I just started parsing a record, but I got stuck here:"
3592 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
3593 ,"so","I","was","expecting","to","see","a","field","name","next."
3597 RecordEnd row col ->
3599 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3600 region = toRegion row col
3602 Report.Report "UNFINISHED RECORD" region [] $
3603 Code.toSnippet source surroundings (Just region)
3606 "I am partway through parsing a record, but I got stuck here:"
3610 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
3611 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
3614 "When I get stuck like this, it usually means that there is a missing parenthesis\
3615 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3619 RecordField row col ->
3620 case Code.whatIsNext source row col of
3621 Code.Keyword keyword ->
3623 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3624 region = toKeywordRegion row col keyword
3626 Report.Report "RESERVED WORD" region [] $
3627 Code.toSnippet source surroundings (Just region)
3630 "I am partway through parsing a record, but I got stuck on this field name:"
3633 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3634 \ that is a reserved word. Try using a different name!"
3639 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3640 region = toRegion row col
3642 Report.Report "UNFINISHED RECORD" region [] $
3643 Code.toSnippet source surroundings (Just region)
3646 "I am partway through parsing a record, but I got stuck after that last comma:"
3648 addNoteForRecordError $
3650 "Trailing commas are not allowed in records, so I was expecting to see another\
3651 \ record field defined next. If you are done defining the record, the fix may\
3652 \ be to delete that last comma?"
3655 RecordEquals row col ->
3657 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3658 region = toRegion row col
3660 Report.Report "UNFINISHED RECORD" region [] $
3661 Code.toSnippet source surroundings (Just region)
3664 "I am partway through parsing a record, but I got stuck here:"
3666 addNoteForRecordError $
3668 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
3669 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
3673 RecordExpr expr row col ->
3674 toExprReport source (InNode NRecord startRow startCol context) expr row col
3676 RecordSpace space row col ->
3677 toSpaceReport source space row col
3679 RecordIndentOpen row col ->
3681 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3682 region = toRegion row col
3684 Report.Report "UNFINISHED RECORD" region [] $
3685 Code.toSnippet source surroundings (Just region)
3688 "I just saw the opening curly brace of a record, but then I got stuck here:"
3690 addNoteForRecordIndentError $
3692 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
3693 ,"Try","defining","some","fields","of","your","own?"
3697 RecordIndentEnd row col ->
3699 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3700 region = toRegion row col
3702 Report.Report "UNFINISHED RECORD" region [] $
3703 Code.toSnippet source surroundings (Just region)
3706 "I was expecting to see a closing curly brace next:"
3708 addNoteForRecordIndentError $
3710 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
3714 RecordIndentField row col ->
3716 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3717 region = toRegion row col
3719 Report.Report "UNFINISHED RECORD" region [] $
3720 Code.toSnippet source surroundings (Just region)
3723 "I am partway through parsing a record, but I got stuck after that last comma:"
3725 addNoteForRecordError $
3727 "Trailing commas are not allowed in records, so the fix may be to\
3728 \ delete that last comma? Or maybe you were in the middle of defining\
3729 \ an additional field?"
3732 RecordIndentEquals row col ->
3734 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3735 region = toRegion row col
3737 Report.Report "UNFINISHED RECORD" region [] $
3738 Code.toSnippet source surroundings (Just region)
3741 "I am partway through parsing a record. I just saw a record\
3742 \ field, so I was expecting to see an equals sign next:"
3744 addNoteForRecordIndentError $
3746 ["Try","putting","an",D.green "=","followed","by","an","expression?"
3750 RecordIndentExpr row col ->
3752 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3753 region = toRegion row col
3755 Report.Report "UNFINISHED RECORD" region [] $
3756 Code.toSnippet source surroundings (Just region)
3759 "I am partway through parsing a record, and I was expecting to run into an expression next:"
3761 addNoteForRecordIndentError $
3763 ["Try","putting","something","like"
3764 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
3769addNoteForRecordError :: D.Doc -> D.Doc
3770addNoteForRecordError normalRecommendation =
3772 normalRecommendation
3775 "If you are trying to define a record across multiple lines, I recommend using this format:"
3776 , D.indent 4 $ D.vcat $
3777 [ "{ name = \"Alice\""
3783 "Notice that each line starts with some indentation. Usually two or four spaces. I\
3784 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
3785 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3789addNoteForRecordIndentError :: D.Doc -> D.Doc
3790addNoteForRecordIndentError normalRecommendation =
3792 normalRecommendation
3795 "I may be confused by indentation. For example, if you are trying to define\
3796 \ a record across multiple lines, I recommend using this format:"
3797 , D.indent 4 $ D.vcat $
3798 [ "{ name = \"Alice\""
3804 "Notice that each line starts with some indentation. Usually two or four spaces. I\
3805 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
3806 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3814toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
3815toTupleReport source context tuple startRow startCol =
3817 TupleExpr expr row col ->
3818 toExprReport source (InNode NParens startRow startCol context) expr row col
3820 TupleSpace space row col ->
3821 toSpaceReport source space row col
3825 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3826 region = toRegion row col
3828 Report.Report "UNFINISHED PARENTHESES" region [] $
3829 Code.toSnippet source surroundings (Just region)
3832 "I was expecting to see a closing parentheses next, but I got stuck here:"
3835 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3837 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
3838 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
3839 \ or missing brackets) that is confusing me."
3843 TupleOperatorClose row col ->
3845 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3846 region = toRegion row col
3848 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
3849 Code.toSnippet source surroundings (Just region)
3851 D.reflow "I was expecting a closing parenthesis here:"
3854 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
3856 "I think I am parsing an operator function right now, so I am expecting to see\
3857 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
3862 TupleOperatorReserved operator row col ->
3864 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3865 region = toRegion row col
3867 Report.Report "UNEXPECTED SYMBOL" region [] $
3868 Code.toSnippet source surroundings (Just region)
3871 "I ran into an unexpected symbol here:"
3875 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
3876 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
3877 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
3878 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
3879 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
3882 TupleIndentExpr1 row col ->
3884 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3885 region = toRegion row col
3887 Report.Report "UNFINISHED PARENTHESES" region [] $
3888 Code.toSnippet source surroundings (Just region)
3891 "I just saw an open parenthesis, so I was expecting to see an expression next."
3895 ["Something","like",D.dullyellow "(4 + 5)","or"
3896 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
3897 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
3900 "I can get confused by indentation in cases like this, so\
3901 \ maybe you have an expression but it is not indented enough?"
3905 TupleIndentExprN row col ->
3907 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3908 region = toRegion row col
3910 Report.Report "UNFINISHED TUPLE" region [] $
3911 Code.toSnippet source surroundings (Just region)
3914 "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."
3918 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
3919 ,D.dullyellow "(\"Tom\",42)" <> ","
3920 ,"so","I","think","there","is","an","expression","missing","here?"
3923 "I can get confused by indentation in cases like this, so\
3924 \ maybe you have an expression but it is not indented enough?"
3928 TupleIndentEnd row col ->
3930 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3931 region = toRegion row col
3933 Report.Report "UNFINISHED PARENTHESES" region [] $
3934 Code.toSnippet source surroundings (Just region)
3937 "I was expecting to see a closing parenthesis next:"
3940 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
3942 "I can get confused by indentation in cases like this, so\
3943 \ maybe you have a closing parenthesis but it is not indented enough?"
3948toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
3949toListReport source context list startRow startCol =
3951 ListSpace space row col ->
3952 toSpaceReport source space row col
3956 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3957 region = toRegion row col
3959 Report.Report "UNFINISHED LIST" region [] $
3960 Code.toSnippet source surroundings (Just region)
3963 "I am partway through parsing a list, but I got stuck here:"
3967 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
3968 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
3971 "When I get stuck like this, it usually means that there is a missing parenthesis\
3972 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3976 ListExpr expr row col ->
3980 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
3981 region = toRegion r c
3983 Report.Report "UNFINISHED LIST" region [] $
3984 Code.toSnippet source surroundings (Just region)
3987 "I was expecting to see another list entry after that last comma:"
3991 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
3993 "I recommend using the following format for lists that span multiple lines:"
3994 , D.indent 4 $ D.vcat $
4001 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4002 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4003 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4008 toExprReport source (InNode NList startRow startCol context) expr row col
4012 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4013 region = toRegion row col
4015 Report.Report "UNFINISHED LIST" region [] $
4016 Code.toSnippet source surroundings (Just region)
4019 "I am partway through parsing a list, but I got stuck here:"
4023 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
4024 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
4027 "When I get stuck like this, it usually means that there is a missing parenthesis\
4028 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4032 ListIndentOpen row col ->
4034 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4035 region = toRegion row col
4037 Report.Report "UNFINISHED LIST" region [] $
4038 Code.toSnippet source surroundings (Just region)
4041 "I cannot find the end of this list:"
4045 ["You","could","change","it","to","something","like"
4046 ,D.dullyellow "[3,4,5]"
4048 ,D.dullyellow "[]" <> "."
4049 ,"Anything","where","there","is","an","open","and","close","square","brace,"
4050 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
4053 "I may be confused by indentation. For example, if you are trying to define\
4054 \ a list across multiple lines, I recommend using this format:"
4055 , D.indent 4 $ D.vcat $
4062 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4063 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4064 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4068 ListIndentEnd row col ->
4070 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4071 region = toRegion row col
4073 Report.Report "UNFINISHED LIST" region [] $
4074 Code.toSnippet source surroundings (Just region)
4077 "I cannot find the end of this list:"
4081 ["You","can","just","add","a","closing",D.dullyellow "]"
4082 ,"right","here,","and","I","will","be","all","set!"
4085 "I may be confused by indentation. For example, if you are trying to define\
4086 \ a list across multiple lines, I recommend using this format:"
4087 , D.indent 4 $ D.vcat $
4094 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4095 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4096 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4100 ListIndentExpr row col ->
4102 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4103 region = toRegion row col
4105 Report.Report "UNFINISHED LIST" region [] $
4106 Code.toSnippet source surroundings (Just region)
4109 "I was expecting to see another list entry after this comma:"
4113 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
4115 "I recommend using the following format for lists that span multiple lines:"
4116 , D.indent 4 $ D.vcat $
4123 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4124 \ This style can be jarring for people coming from C-like syntax, but folks generally\
4125 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4130toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
4131toFuncReport source context func startRow startCol =
4133 FuncSpace space row col ->
4134 toSpaceReport source space row col
4136 FuncArg pattern row col ->
4137 toPatternReport source PArg pattern row col
4139 FuncBody expr row col ->
4140 toExprReport source (InNode NFunc startRow startCol context) expr row col
4142 FuncArrow row col ->
4143 case Code.whatIsNext source row col of
4144 Code.Keyword keyword ->
4146 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4147 region = toKeywordRegion row col keyword
4149 Report.Report "RESERVED WORD" region [] $
4150 Code.toSnippet source surroundings (Just region)
4153 "I was parsing an anonymous function, but I got stuck here:"
4156 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
4157 \ it is a reserved word in this language. Try using a different argument name!"
4162 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4163 region = toRegion row col
4165 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4166 Code.toSnippet source surroundings (Just region)
4169 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4172 ["The","syntax","for","anonymous","functions","is"
4173 ,D.dullyellow "(\\x -> x + 1)"
4174 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4178 FuncIndentArg row col ->
4180 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4181 region = toRegion row col
4183 Report.Report "MISSING ARGUMENT" region [] $
4184 Code.toSnippet source surroundings (Just region)
4187 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
4191 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
4192 ,"Anything","that","starts","with","a","lower","case","letter!"
4195 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
4196 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
4197 \ like a better idea at the time!"
4201 FuncIndentArrow row col ->
4203 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4204 region = toRegion row col
4206 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4207 Code.toSnippet source surroundings (Just region)
4210 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
4214 ["The","syntax","for","anonymous","functions","is"
4215 ,D.dullyellow "(\\x -> x + 1)"
4216 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
4219 "It is possible that I am confused about indetation! I generally recommend\
4220 \ switching to named functions if the definition cannot fit inline nicely, so\
4221 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4222 \ the whole thing out into a named function. Things tend to be clearer that way!"
4226 FuncIndentBody row col ->
4228 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4229 region = toRegion row col
4231 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
4232 Code.toSnippet source surroundings (Just region)
4235 "I was expecting to see the body of your anonymous function next:"
4239 ["The","syntax","for","anonymous","functions","is"
4240 ,D.dullyellow "(\\x -> x + 1)"
4241 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
4244 "It is possible that I am confused about indetation! I generally recommend\
4245 \ switching to named functions if the definition cannot fit inline nicely, so\
4246 \ either (1) try to fit the whole anonymous function on one line or (2) break\
4247 \ the whole thing out into a named function. Things tend to be clearer that way!"
4262toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
4263toPatternReport source context pattern startRow startCol =
4265 PRecord record row col ->
4266 toPRecordReport source record row col
4268 PTuple tuple row col ->
4269 toPTupleReport source context tuple row col
4271 PList list row col ->
4272 toPListReport source context list row col
4275 case Code.whatIsNext source row col of
4276 Code.Keyword keyword ->
4278 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4279 region = toKeywordRegion row col keyword
4282 PArg -> "as an argument"
4283 PCase -> "in this pattern"
4284 PLet -> "in this pattern"
4286 Report.Report "RESERVED WORD" region [] $
4287 Code.toSnippet source surroundings (Just region)
4290 "It looks like you are trying to use `" ++ keyword ++ "` " ++ inThisThing ++ ":"
4293 "This is a reserved word! Try using some other name?"
4296 Code.Operator "-" ->
4298 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4299 region = toRegion row col
4301 Report.Report "UNEXPECTED SYMBOL" region [] $
4302 Code.toSnippet source surroundings (Just region)
4305 "I ran into a minus sign unexpectedly in this pattern:"
4308 "It is not possible to pattern match on negative numbers at this\
4309 \ time. Try using an `if` expression for that sort of thing for now."
4314 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4315 region = toRegion row col
4317 Report.Report "PROBLEM IN PATTERN" region [] $
4318 Code.toSnippet source surroundings (Just region)
4321 "I wanted to parse a pattern next, but I got stuck here:"
4324 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4325 ,"I","just","know","that","I","want","a","pattern","next."
4326 ,"Something","as","simple","as"
4327 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4332 PChar char row col ->
4333 toCharReport source char row col
4335 PString string row col ->
4336 toStringReport source string row col
4338 PNumber number row col ->
4339 toNumberReport source number row col
4341 PFloat width row col ->
4343 region = toWiderRegion row col width
4345 Report.Report "UNEXPECTED PATTERN" region [] $
4346 Code.toSnippet source region Nothing
4349 "I cannot pattern match with floating point numbers:"
4352 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
4353 ,"to","check","that","they","are","nearby","with","some","sort","of"
4354 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
4360 region = toRegion row col
4362 Report.Report "UNFINISHED PATTERN" region [] $
4363 Code.toSnippet source region Nothing $
4366 "I was expecting to see a variable name after the `as` keyword:"
4370 ["The","`as`","keyword","lets","you","write","patterns","like"
4371 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4372 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4373 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4374 ,"thing","with",D.dullyellow "point."
4377 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4378 \ people just want to use `as` as a variable name though. Try using a different name\
4383 PWildcardNotVar name width row col ->
4385 region = toWiderRegion row col (fromIntegral width)
4387 case dropWhile (=='_') (Name.toChars name) of
4388 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
4389 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
4391 Report.Report "UNEXPECTED NAME" region [] $
4392 Code.toSnippet source region Nothing $
4395 "Variable names cannot start with underscores like this:"
4398 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
4399 ,"ignore","the","value,","or","you","can","have","a","name","like"
4400 ] ++ examples ++ ["to","use","the","matched","value." ]
4403 PSpace space row col ->
4404 toSpaceReport source space row col
4406 PIndentStart row col ->
4408 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4409 region = toRegion row col
4411 Report.Report "UNFINISHED PATTERN" region [] $
4412 Code.toSnippet source surroundings (Just region)
4415 "I wanted to parse a pattern next, but I got stuck here:"
4419 ["I","am","not","sure","why","I","am","getting","stuck","exactly."
4420 ,"I","just","know","that","I","want","a","pattern","next."
4421 ,"Something","as","simple","as"
4422 ,D.dullyellow "maybeHeight","or",D.dullyellow "result"
4426 "I can get confused by indentation. If you think there is a pattern next, maybe\
4427 \ it needs to be indented a bit more?"
4431 PIndentAlias row col ->
4433 region = toRegion row col
4435 Report.Report "UNFINISHED PATTERN" region [] $
4436 Code.toSnippet source region Nothing $
4439 "I was expecting to see a variable name after the `as` keyword:"
4443 ["The","`as`","keyword","lets","you","write","patterns","like"
4444 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
4445 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
4446 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
4447 ,"thing","with",D.dullyellow "point."
4450 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
4451 \ people just want to use `as` as a variable name though. Try using a different name\
4457toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
4458toPRecordReport source record startRow startCol =
4460 PRecordOpen row col ->
4461 toUnfinishRecordPatternReport source row col startRow startCol $
4462 D.reflow "I was expecting to see a field name next."
4464 PRecordEnd row col ->
4465 toUnfinishRecordPatternReport source row col startRow startCol $
4467 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4468 ,"Try","adding","a",D.dullyellow "}","here?"
4471 PRecordField row col ->
4472 case Code.whatIsNext source row col of
4473 Code.Keyword keyword ->
4475 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4476 region = toKeywordRegion row col keyword
4478 Report.Report "RESERVED WORD" region [] $
4479 Code.toSnippet source surroundings (Just region)
4482 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
4485 "This is a reserved word, not available for variable names. Try another name!"
4489 toUnfinishRecordPatternReport source row col startRow startCol $
4490 D.reflow "I was expecting to see a field name next."
4492 PRecordSpace space row col ->
4493 toSpaceReport source space row col
4495 PRecordIndentOpen row col ->
4496 toUnfinishRecordPatternReport source row col startRow startCol $
4497 D.reflow "I was expecting to see a field name next."
4499 PRecordIndentEnd row col ->
4500 toUnfinishRecordPatternReport source row col startRow startCol $
4502 ["I","was","expecting","to","see","a","closing","curly","brace","next."
4503 ,"Try","adding","a",D.dullyellow "}","here?"
4506 PRecordIndentField row col ->
4507 toUnfinishRecordPatternReport source row col startRow startCol $
4508 D.reflow "I was expecting to see a field name next."
4511toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
4512toUnfinishRecordPatternReport source row col startRow startCol message =
4514 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4515 region = toRegion row col
4517 Report.Report "UNFINISHED RECORD PATTERN" region [] $
4518 Code.toSnippet source surroundings (Just region)
4521 "I was partway through parsing a record pattern, but I got stuck here:"
4526 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
4527 ,"where","you","list","the","field","names","you","want","to","access."
4534toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
4535toPTupleReport source context tuple startRow startCol =
4537 PTupleOpen row col ->
4538 case Code.whatIsNext source row col of
4539 Code.Keyword keyword ->
4541 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4542 region = toKeywordRegion row col keyword
4544 Report.Report "RESERVED WORD" region [] $
4545 Code.toSnippet source surroundings (Just region)
4548 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
4551 "This is a reserved word! Try using some other name?"
4556 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4557 region = toRegion row col
4559 Report.Report "UNFINISHED PARENTHESES" region [] $
4560 Code.toSnippet source surroundings (Just region)
4563 "I just saw an open parenthesis, but I got stuck here:"
4566 ["I","was","expecting","so","see","a","pattern","next."
4567 ,"Maybe","it","will","end","up","being","something"
4568 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
4572 PTupleEnd row col ->
4573 case Code.whatIsNext source row col of
4574 Code.Keyword keyword ->
4576 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4577 region = toKeywordRegion row col keyword
4579 Report.Report "RESERVED WORD" region [] $
4580 Code.toSnippet source surroundings (Just region) $
4583 "I ran into a reserved word in this pattern:"
4586 "The `" ++ keyword ++ "` keyword is reserved. Try using a different name instead!"
4591 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4592 region = toKeywordRegion row col op
4594 Report.Report "UNEXPECTED SYMBOL" region [] $
4595 Code.toSnippet source surroundings (Just region) $
4598 "I ran into the " ++ op ++ " symbol unexpectedly in this pattern:"
4601 "Only the :: symbol that works in patterns. It is useful if you\
4602 \ are pattern matching on lists, trying to get the first element\
4603 \ off the front. Did you want that instead?"
4606 Code.Close term bracket ->
4608 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4609 region = toRegion row col
4611 Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
4612 Code.toSnippet source surroundings (Just region) $
4615 "I ran into a an unexpected " ++ term ++ " in this pattern:"
4618 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
4623 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4624 region = toRegion row col
4626 Report.Report "UNFINISHED PARENTHESES" region [] $
4627 Code.toSnippet source surroundings (Just region) $
4630 "I was partway through parsing a pattern, but I got stuck here:"
4633 ["I","was","expecting","a","closing","parenthesis","next,","so"
4634 ,"try","adding","a",D.dullyellow ")","to","see","if","that","helps?"
4638 PTupleExpr pattern row col ->
4639 toPatternReport source context pattern row col
4641 PTupleSpace space row col ->
4642 toSpaceReport source space row col
4644 PTupleIndentEnd row col ->
4646 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4647 region = toRegion row col
4649 Report.Report "UNFINISHED PARENTHESES" region [] $
4650 Code.toSnippet source surroundings (Just region) $
4653 "I was expecting a closing parenthesis next:"
4656 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
4658 "I can get confused by indentation in cases like this, so\
4659 \ maybe you have a closing parenthesis but it is not indented enough?"
4663 PTupleIndentExpr1 row col ->
4665 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4666 region = toRegion row col
4668 Report.Report "UNFINISHED PARENTHESES" region [] $
4669 Code.toSnippet source surroundings (Just region) $
4672 "I just saw an open parenthesis, but then I got stuck here:"
4675 ["I","was","expecting","so","see","a","pattern","next."
4676 ,"Maybe","it","will","end","up","being","something"
4677 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
4681 PTupleIndentExprN row col ->
4683 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4684 region = toRegion row col
4686 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
4687 Code.toSnippet source surroundings (Just region) $
4690 "I am partway through parsing a tuple pattern, but I got stuck here:"
4694 ["I","was","expecting","so","see","a","pattern","next."
4695 ,"I","am","expecting","the","final","result","to","be","something"
4696 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
4699 "I can get confused by indentation in cases like this, so the problem\
4700 \ may be that the next part is not indented enough?"
4705toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
4706toPListReport source context list startRow startCol =
4708 PListOpen row col ->
4709 case Code.whatIsNext source row col of
4710 Code.Keyword keyword ->
4712 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4713 region = toKeywordRegion row col keyword
4715 Report.Report "RESERVED WORD" region [] $
4716 Code.toSnippet source surroundings (Just region)
4719 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
4722 "This is a reserved word though! Try using some other name?"
4727 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4728 region = toRegion row col
4730 Report.Report "UNFINISHED LIST PATTERN" region [] $
4731 Code.toSnippet source surroundings (Just region) $
4734 "I just saw an open square bracket, but then I got stuck here:"
4736 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4741 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4742 region = toRegion row col
4744 Report.Report "UNFINISHED LIST PATTERN" region [] $
4745 Code.toSnippet source surroundings (Just region) $
4748 "I was expecting a closing square bracket to end this list pattern:"
4750 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4753 PListExpr pattern row col ->
4754 toPatternReport source context pattern row col
4756 PListSpace space row col ->
4757 toSpaceReport source space row col
4759 PListIndentOpen row col ->
4761 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4762 region = toRegion row col
4764 Report.Report "UNFINISHED LIST PATTERN" region [] $
4765 Code.toSnippet source surroundings (Just region) $
4768 "I just saw an open square bracket, but then I got stuck here:"
4771 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4773 "I can get confused by indentation in cases like this, so\
4774 \ maybe there is something next, but it is not indented enough?"
4778 PListIndentEnd row col ->
4780 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4781 region = toRegion row col
4783 Report.Report "UNFINISHED LIST PATTERN" region [] $
4784 Code.toSnippet source surroundings (Just region) $
4787 "I was expecting a closing square bracket to end this list pattern:"
4790 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
4792 "I can get confused by indentation in cases like this, so\
4793 \ maybe you have a closing square bracket but it is not indented enough?"
4797 PListIndentExpr row col ->
4799 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4800 region = toRegion row col
4802 Report.Report "UNFINISHED LIST PATTERN" region [] $
4803 Code.toSnippet source surroundings (Just region) $
4806 "I am partway through parsing a list pattern, but I got stuck here:"
4810 "I was expecting to see another pattern next. Maybe a variable name."
4812 "I can get confused by indentation in cases like this, so\
4813 \ maybe there is more to this pattern but it is not indented enough?"
4823 = TC_Annotation Name.Name
4829toTypeReport :: Code.Source -> TContext -> Type -> Row -> Col -> Report.Report
4830toTypeReport source context tipe startRow startCol =
4832 TRecord record row col ->
4833 toTRecordReport source context record row col
4835 TTuple tuple row col ->
4836 toTTupleReport source context tuple row col
4839 case Code.whatIsNext source row col of
4840 Code.Keyword keyword ->
4842 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4843 region = toKeywordRegion row col keyword
4845 Report.Report "RESERVED WORD" region [] $
4846 Code.toSnippet source surroundings (Just region)
4849 "I was expecting to see a type next, but I got stuck on this reserved word:"
4852 "It looks like you are trying to use `" ++ keyword ++ "` as a type variable, but \
4853 \ it is a reserved word. Try using a different name!"
4858 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4859 region = toRegion row col
4863 TC_Annotation _ -> "type annotation"
4864 TC_CustomType -> "custom type"
4865 TC_TypeAlias -> "type alias"
4870 TC_Annotation name -> "the `" ++ Name.toChars name ++ "` type annotation"
4871 TC_CustomType -> "a custom type"
4872 TC_TypeAlias -> "a type alias"
4875 Report.Report ("PROBLEM IN " ++ map Char.toUpper thing) region [] $
4876 Code.toSnippet source surroundings (Just region)
4879 "I was partway through parsing " ++ something ++ ", but I got stuck here:"
4882 ["I","was","expecting","to","see","a","type","next."
4883 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
4887 TSpace space row col ->
4888 toSpaceReport source space row col
4890 TIndentStart row col ->
4892 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4893 region = toRegion row col
4897 TC_Annotation _ -> "type annotation"
4898 TC_CustomType -> "custom type"
4899 TC_TypeAlias -> "type alias"
4902 Report.Report ("UNFINISHED " ++ map Char.toUpper thing) region [] $
4903 Code.toSnippet source surroundings (Just region)
4906 "I was partway through parsing a " ++ thing ++ ", but I got stuck here:"
4910 ["I","was","expecting","to","see","a","type","next."
4911 ,"Try","putting",D.dullyellow "Int","or",D.dullyellow "String","for","now?"
4914 "I can get confused by indentation. If you think there is already a type\
4915 \ next, maybe it is not indented enough?"
4920toTRecordReport :: Code.Source -> TContext -> TRecord -> Row -> Col -> Report.Report
4921toTRecordReport source context record startRow startCol =
4923 TRecordOpen row col ->
4924 case Code.whatIsNext source row col of
4925 Code.Keyword keyword ->
4927 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4928 region = toKeywordRegion row col keyword
4930 Report.Report "RESERVED WORD" region [] $
4931 Code.toSnippet source surroundings (Just region)
4934 "I just started parsing a record type, but I got stuck on this field name:"
4937 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
4938 \ that is a reserved word. Try using a different name!"
4943 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4944 region = toRegion row col
4946 Report.Report "UNFINISHED RECORD TYPE" region [] $
4947 Code.toSnippet source surroundings (Just region)
4950 "I just started parsing a record type, but I got stuck here:"
4953 ["Record","types","look","like",D.dullyellow "{ name : String, age : Int },"
4954 ,"so","I","was","expecting","to","see","a","field","name","next."
4958 TRecordEnd row col ->
4960 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4961 region = toRegion row col
4963 Report.Report "UNFINISHED RECORD TYPE" region [] $
4964 Code.toSnippet source surroundings (Just region)
4967 "I am partway through parsing a record type, but I got stuck here:"
4971 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
4972 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
4975 "When I get stuck like this, it usually means that there is a missing parenthesis\
4976 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
4980 TRecordField row col ->
4981 case Code.whatIsNext source row col of
4982 Code.Keyword keyword ->
4984 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4985 region = toKeywordRegion row col keyword
4987 Report.Report "RESERVED WORD" region [] $
4988 Code.toSnippet source surroundings (Just region)
4991 "I am partway through parsing a record type, but I got stuck on this field name:"
4994 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
4995 \ that is a reserved word. Try using a different name!"
5000 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5001 region = toRegion row col
5003 Report.Report "UNFINISHED RECORD TYPE" region [] $
5004 Code.toSnippet source surroundings (Just region)
5007 "I am partway through parsing a record type, but I got stuck after that last comma:"
5009 addNoteForRecordTypeError $
5011 "Trailing commas are not allowed in records, so I was expecting to see another\
5012 \ record field defined next. If you are done defining the record, the fix may\
5013 \ be to delete that last comma?"
5016 TRecordColon row col ->
5018 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5019 region = toRegion row col
5021 Report.Report "UNFINISHED RECORD TYPE" region [] $
5022 Code.toSnippet source surroundings (Just region)
5025 "I am partway through parsing a record type, but I got stuck here:"
5027 addNoteForRecordTypeError $
5029 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
5030 ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
5034 TRecordType tipe row col ->
5035 toTypeReport source context tipe row col
5037 TRecordSpace space row col ->
5038 toSpaceReport source space row col
5040 TRecordIndentOpen row col ->
5042 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5043 region = toRegion row col
5045 Report.Report "UNFINISHED RECORD TYPE" region [] $
5046 Code.toSnippet source surroundings (Just region)
5049 "I just saw the opening curly brace of a record type, but then I got stuck here:"
5051 addNoteForRecordTypeIndentError $
5053 ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
5054 ,"Try","defining","some","fields","of","your","own?"
5058 TRecordIndentEnd row col ->
5060 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5061 region = toRegion row col
5063 Report.Report "UNFINISHED RECORD TYPE" region [] $
5064 Code.toSnippet source surroundings (Just region)
5067 "I was expecting to see a closing curly brace next:"
5069 addNoteForRecordTypeIndentError $
5071 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
5075 TRecordIndentField row col ->
5077 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5078 region = toRegion row col
5080 Report.Report "UNFINISHED RECORD TYPE" region [] $
5081 Code.toSnippet source surroundings (Just region)
5084 "I am partway through parsing a record type, but I got stuck after that last comma:"
5086 addNoteForRecordTypeIndentError $
5088 "Trailing commas are not allowed in record types, so the fix may be to\
5089 \ delete that last comma? Or maybe you were in the middle of defining\
5090 \ an additional field?"
5093 TRecordIndentColon row col ->
5095 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5096 region = toRegion row col
5098 Report.Report "UNFINISHED RECORD TYPE" region [] $
5099 Code.toSnippet source surroundings (Just region)
5102 "I am partway through parsing a record type. I just saw a record\
5103 \ field, so I was expecting to see a colon next:"
5105 addNoteForRecordTypeIndentError $
5107 ["Try","putting","an",D.green ":","followed","by","a","type?"
5111 TRecordIndentType row col ->
5113 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5114 region = toRegion row col
5116 Report.Report "UNFINISHED RECORD TYPE" region [] $
5117 Code.toSnippet source surroundings (Just region)
5120 "I am partway through parsing a record type, and I was expecting to run into a type next:"
5122 addNoteForRecordTypeIndentError $
5124 ["Try","putting","something","like"
5125 ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5130addNoteForRecordTypeError :: D.Doc -> D.Doc
5131addNoteForRecordTypeError normalRecommendation =
5133 normalRecommendation
5136 "If you are trying to define a record type across multiple lines, I recommend using this format:"
5137 , D.indent 4 $ D.vcat $
5140 , ", height : Float"
5144 "Notice that each line starts with some indentation. Usually two or four spaces. I\
5145 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5146 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5150addNoteForRecordTypeIndentError :: D.Doc -> D.Doc
5151addNoteForRecordTypeIndentError normalRecommendation =
5153 normalRecommendation
5156 "I may be confused by indentation. For example, if you are trying to define\
5157 \ a record type across multiple lines, I recommend using this format:"
5158 , D.indent 4 $ D.vcat $
5161 , ", height : Float"
5165 "Notice that each line starts with some indentation. Usually two or four spaces. I\
5166 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5167 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5171toTTupleReport :: Code.Source -> TContext -> TTuple -> Row -> Col -> Report.Report
5172toTTupleReport source context tuple startRow startCol =
5174 TTupleOpen row col ->
5175 case Code.whatIsNext source row col of
5176 Code.Keyword keyword ->
5178 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5179 region = toKeywordRegion row col keyword
5181 Report.Report "RESERVED WORD" region [] $
5182 Code.toSnippet source surroundings (Just region)
5185 "I ran into a reserved word unexpectedly:"
5188 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but \
5189 \ it is a reserved word. Try using a different name!"
5194 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5195 region = toRegion row col
5197 Report.Report "UNFINISHED PARENTHESES" region [] $
5198 Code.toSnippet source surroundings (Just region)
5201 "I just saw an open parenthesis, so I was expecting to see a type next."
5204 ["Something","like",D.dullyellow "(Maybe Int)","or"
5205 ,D.dullyellow "(List Person)" <> "."
5206 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5210 TTupleEnd row col ->
5212 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5213 region = toRegion row col
5215 Report.Report "UNFINISHED PARENTHESES" region [] $
5216 Code.toSnippet source surroundings (Just region)
5219 "I was expecting to see a closing parentheses next, but I got stuck here:"
5222 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
5224 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
5225 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
5226 \ or missing brackets) that is confusing me."
5230 TTupleType tipe row col ->
5231 toTypeReport source context tipe row col
5233 TTupleSpace space row col ->
5234 toSpaceReport source space row col
5236 TTupleIndentType1 row col ->
5238 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5239 region = toRegion row col
5241 Report.Report "UNFINISHED PARENTHESES" region [] $
5242 Code.toSnippet source surroundings (Just region)
5245 "I just saw an open parenthesis, so I was expecting to see a type next."
5249 ["Something","like",D.dullyellow "(Maybe Int)","or"
5250 ,D.dullyellow "(List Person)" <> "."
5251 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
5254 "I can get confused by indentation in cases like this, so\
5255 \ maybe you have a type but it is not indented enough?"
5259 TTupleIndentTypeN row col ->
5261 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5262 region = toRegion row col
5264 Report.Report "UNFINISHED TUPLE TYPE" region [] $
5265 Code.toSnippet source surroundings (Just region)
5268 "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."
5272 ["A","tuple","type","looks","like",D.dullyellow "(Float,Float)","or"
5273 ,D.dullyellow "(String,Int)" <> ","
5274 ,"so","I","think","there","is","a","type","missing","here?"
5277 "I can get confused by indentation in cases like this, so\
5278 \ maybe you have an expression but it is not indented enough?"
5282 TTupleIndentEnd row col ->
5284 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5285 region = toRegion row col
5287 Report.Report "UNFINISHED PARENTHESES" region [] $
5288 Code.toSnippet source surroundings (Just region)
5291 "I was expecting to see a closing parenthesis next:"
5294 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
5296 "I can get confused by indentation in cases like this, so\
5297 \ 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