1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Syntax
47import Prelude hiding (Char, String)
48import qualified Data.Char as Char
49import qualified Data.Name as Name
50import Data.Word (Word16)
51import Numeric (showHex)
53import qualified Elm.ModuleName as ModuleName
54import Parse.Primitives (Row, Col)
55import Parse.Symbol (BadOperator(..))
56import qualified Reporting.Annotation as A
57import qualified Reporting.Doc as D
58import qualified Reporting.Report as Report
59import qualified Reporting.Render.Code as Code
67 = ModuleNameUnspecified ModuleName.Raw
68 | ModuleNameMismatch ModuleName.Raw (A.Located ModuleName.Raw)
69 | UnexpectedPort A.Region
79 = ModuleSpace Space Row Col
80 | ModuleEndOfFile Row Col
82 | ModuleProblem Row Col
84 | ModuleExposing Exposing Row Col
86 | PortModuleProblem Row Col
87 | PortModuleName Row Col
88 | PortModuleExposing Exposing Row Col
98 | ImportExposing Row Col
99 | ImportExposingList Exposing Row Col
100 | ImportEnd Row Col -- different based on col=1 or if greater
102 | ImportIndentName Row Col
103 | ImportIndentAlias Row Col
104 | ImportIndentExposingList Row Col
108 | Declarations Decl Row Col
112 = ExposingSpace Space Row Col
113 | ExposingStart Row Col
114 | ExposingValue Row Col
115 | ExposingOperator Row Col
116 | ExposingOperatorReserved BadOperator Row Col
117 | ExposingOperatorRightParen Row Col
118 | ExposingEnd Row Col
120 | ExposingTypePrivacy Row Col
121 | ExposingTypePrivacyDots Row Col
122 | ExposingTypePrivacyEnd Row Col
124 | ExposingIndentEnd Row Col
125 | ExposingIndentValue Row Col
126 | ExposingIndentValueEnd Row Col
127 | ExposingIndentTypePrivacy Row Col
128 | ExposingIndentTypePrivacyDots Row Col
129 | ExposingIndentTypePrivacyEnd Row Col
138 | DeclSpace Space Row Col
141 | DeclType DeclType Row Col
142 | DeclDef Name.Name DeclDef Row Col
144 | DeclFreshLineStart Row Col
145 | DeclFreshLineAfterDocComment Row Col
149 = DeclDefSpace Space Row Col
150 | DeclDefEquals Row Col
151 | DeclDefType Type Row Col
152 | DeclDefArg Pattern Row Col
153 | DeclDefBody Expr Row Col
154 | DeclDefNameRepeat Row Col
155 | DeclDefNameMatch Name.Name Row Col
157 | DeclDefIndentType Row Col
158 | DeclDefIndentEquals Row Col
159 | DeclDefIndentBody Row Col
161 | DeclDefFreshLineAfterType Row Col
165 = PortSpace Space Row Col
168 | PortType Type Row Col
169 | PortIndentName Row Col
170 | PortIndentColon Row Col
171 | PortIndentType Row Col
179 = DT_Space Space Row Col
181 | DT_Alias TypeAlias Row Col
182 | DT_Union CustomType Row Col
184 | DT_IndentName Row Col
188 = AliasSpace Space Row Col
190 | AliasEquals Row Col
191 | AliasBody Type Row Col
193 | AliasIndentEquals Row Col
194 | AliasIndentBody Row Col
198 = CT_Space Space Row Col
203 | CT_VariantArg Type Row Col
205 | CT_IndentEquals Row Col
206 | CT_IndentBar Row Col
207 | CT_IndentAfterBar Row Col
208 | CT_IndentAfterEquals Row Col
220 | Record Record Row Col
221 | Tuple Tuple Row Col
226 | OperatorRight Name.Name Row Col
227 | OperatorReserved BadOperator Row Col
231 | String String Row Col
232 | Number Number Row Col
233 | Space Space Row Col
234 | EndlessShader Row Col
235 | ShaderProblem [Char.Char] Row Col
236 | IndentOperatorRight Name.Name Row Col
237 | IndentMoreExpr Row Col
243 | RecordField Row Col
244 | RecordEquals Row Col
245 | RecordExpr Expr Row Col
246 | RecordSpace Space Row Col
248 | RecordIndentOpen Row Col
249 | RecordIndentEnd Row Col
250 | RecordIndentField Row Col
251 | RecordIndentEquals Row Col
252 | RecordIndentExpr Row Col
256 = TupleExpr Expr Row Col
257 | TupleSpace Space Row Col
259 | TupleOperatorClose Row Col
260 | TupleOperatorReserved BadOperator Row Col
262 | TupleIndentExpr1 Row Col
263 | TupleIndentExprN Row Col
264 | TupleIndentEnd Row Col
268 = ListSpace Space Row Col
270 | ListExpr Expr Row Col
273 | ListIndentOpen Row Col
274 | ListIndentEnd Row Col
275 | ListIndentExpr Row Col
279 = FuncSpace Space Row Col
280 | FuncArg Pattern Row Col
281 | FuncBody Expr Row Col
284 | FuncIndentArg Row Col
285 | FuncIndentArrow Row Col
286 | FuncIndentBody Row Col
290 = CaseSpace Space Row Col
292 | CasePattern Pattern Row Col
294 | CaseExpr Expr Row Col
295 | CaseBranch Expr Row Col
297 | CaseIndentOf Row Col
298 | CaseIndentExpr Row Col
299 | CaseIndentPattern Row Col
300 | CaseIndentArrow Row Col
301 | CaseIndentBranch Row Col
302 | CasePatternAlignment Word16 Row Col
306 = IfSpace Space Row Col
309 | IfElseBranchStart Row Col
311 | IfCondition Expr Row Col
312 | IfThenBranch Expr Row Col
313 | IfElseBranch Expr Row Col
315 | IfIndentCondition Row Col
316 | IfIndentThen Row Col
317 | IfIndentThenBranch Row Col
318 | IfIndentElseBranch Row Col
319 | IfIndentElse Row Col
323 = LetSpace Space Row Col
325 | LetDefAlignment Word16 Row Col
327 | LetDef Name.Name Def Row Col
328 | LetDestruct Destruct Row Col
329 | LetBody Expr Row Col
330 | LetIndentDef Row Col
331 | LetIndentIn Row Col
332 | LetIndentBody Row Col
336 = DefSpace Space Row Col
337 | DefType Type Row Col
338 | DefNameRepeat Name.Name Row Col
339 | DefNameMatch Name.Name Name.Name Row Col
340 | DefArg Pattern Row Col
342 | DefBody Expr Row Col
343 | DefIndentEquals Row Col
344 | DefIndentType Row Col
345 | DefIndentBody Row Col
346 | DefAlignment Word16 Row Col
350 = DestructSpace Space Row Col
351 | DestructPattern Pattern Row Col
352 | DestructEquals Row Col
353 | DestructBody Expr Row Col
354 | DestructIndentEquals Row Col
355 | DestructIndentBody Row Col
363 = PRecord PRecord Row Col
364 | PTuple PTuple Row Col
365 | PList PList Row Col
369 | PString String Row Col
370 | PNumber Number Row Col
371 | PFloat Word16 Row Col
373 | PWildcardNotVar Name.Name Int Row Col
374 | PSpace Space Row Col
376 | PIndentStart Row Col
377 | PIndentAlias Row Col
381 = PRecordOpen Row Col
383 | PRecordField Row Col
384 | PRecordSpace Space Row Col
386 | PRecordIndentOpen Row Col
387 | PRecordIndentEnd Row Col
388 | PRecordIndentField Row Col
394 | PTupleExpr Pattern Row Col
395 | PTupleSpace Space Row Col
397 | PTupleIndentEnd Row Col
398 | PTupleIndentExpr1 Row Col
399 | PTupleIndentExprN Row Col
405 | PListExpr Pattern Row Col
406 | PListSpace Space Row Col
408 | PListIndentOpen Row Col
409 | PListIndentEnd Row Col
410 | PListIndentExpr Row Col
418 = TRecord TRecord Row Col
419 | TTuple TTuple Row Col
423 | TSpace Space Row Col
425 | TIndentStart Row Col
429 = TRecordOpen Row Col
432 | TRecordField Row Col
433 | TRecordColon Row Col
434 | TRecordType Type Row Col
436 | TRecordSpace Space Row Col
438 | TRecordIndentOpen Row Col
439 | TRecordIndentField Row Col
440 | TRecordIndentColon Row Col
441 | TRecordIndentType Row Col
442 | TRecordIndentEnd Row Col
448 | TTupleType Type Row Col
449 | TTupleSpace Space Row Col
451 | TTupleIndentType1 Row Col
452 | TTupleIndentTypeN Row Col
453 | TTupleIndentEnd Row Col
463 | CharNotString Word16
467 = StringEndless_Single
468 | StringEndless_Multi
469 | StringEscape Escape
474 | BadUnicodeFormat Word16
475 | BadUnicodeCode Word16
476 | BadUnicodeLength Word16 Int Int
483 | NumberNoLeadingZero
492 | EndlessMultiComment
499toReport :: Code.Source -> Error -> Report.Report
502 ModuleNameUnspecified name ->
504 region = toRegion 1 1
506 Report.Report "MODULE NAME MISSING" region [] $
509 "I need the module name to be declared at the top of this file, like this:"
510 , D.indent 4 $ D.fillSep $
511 [ D.cyan "module", D.fromName name, D.cyan "exposing", "(..)" ]
513 "Try adding that as the first line of your file!"
515 "It is best to replace (..) with an explicit list of types and\
516 \ functions you want to expose. When you know a value is only used\
517 \ within this module, you can refactor without worrying about uses\
518 \ elsewhere. Limiting exposed values can also speed up compilation\
519 \ because I can skip a bunch of work if I see that the exposed API\
523 ModuleNameMismatch expectedName (A.At region actualName) ->
524 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
525 Code.toSnippet source region Nothing
527 "It looks like this module name is out of sync:"
531 "I need it to match the file path, so I was expecting it to see `"
532 ++ ModuleName.toChars expectedName
533 ++ "` here. Make the following change, and you should be all set!"
535 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
537 "I require that module names correspond to file paths. This makes it much\
538 \ easier to explore unfamiliar codebases! So if you want to keep the current\
539 \ module name, try renaming the file instead."
543 UnexpectedPort region ->
544 Report.Report "UNEXPECTED PORTS" region [] $
545 Code.toSnippet source region Nothing
548 "You are declaring ports in a normal module."
552 ["Switch","this","to","say",D.cyan "port module","instead,"
553 ,"marking","that","this","module","contains","port","declarations."
556 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
558 "to learn the syntax and how to use it effectively."
563 Report.Report "NO PORTS" region [] $
564 Code.toSnippet source region Nothing
567 "This module does not declare any ports, but it says it will:"
570 ["Switch","this","to",D.cyan "module"
571 ,"and","you","should","be","all","set!"
576 toParseErrorReport source modul
579toParseErrorReport :: Code.Source -> Module -> Report.Report
580toParseErrorReport source modul =
582 ModuleSpace space row col ->
583 toSpaceReport source space row col
585 ModuleEndOfFile row col ->
586 case Code.whatIsNext source row col of
587 Code.Keyword keyword ->
589 region = toKeywordRegion row col keyword
591 Report.Report "RESERVED WORD" region [] $
592 Code.toSnippet source region Nothing
595 "I got stuck on this reserved word:"
598 "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
603 region = toKeywordRegion row col op
605 Report.Report "UNEXPECTED SYMBOL" region [] $
606 Code.toSnippet source region Nothing
609 "I ran into an unexpected symbol:"
612 "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
613 \ I can give a better hint from there?"
616 Code.Close term bracket ->
618 region = toRegion row col
620 Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
621 Code.toSnippet source region Nothing
624 "I ran into an unexpected " ++ term ++ ":"
627 "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
632 region = toRegion row col
634 Report.Report "SYNTAX PROBLEM" region [] $
635 Code.toSnippet source region Nothing
641 "Whatever I am running into is confusing me a lot! Normally I can give fairly\
642 \ specific hints, but something is really tripping me up this time."
645 ModuleProblem row col ->
647 region = toRegion row col
649 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
650 Code.toSnippet source region Nothing
653 "I am parsing an `module` declaration, but I got stuck here:"
657 "Here are some examples of valid `module` declarations:"
658 , D.indent 4 $ D.vcat $
659 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
660 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
663 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
664 \ of files when the public interface of a module stays the same, so exposing fewer\
665 \ values can help improve compile times!"
669 ModuleName row col ->
671 region = toRegion row col
673 Report.Report "EXPECTING MODULE NAME" region [] $
674 Code.toSnippet source region Nothing
677 "I was parsing an `module` declaration until I got stuck here:"
681 "I was expecting to see the module name next, like in these examples:"
682 , D.indent 4 $ D.vcat $
683 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
684 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
685 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
686 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
689 "Notice that the module names all start with capital letters. That is required!"
693 ModuleExposing exposing row col ->
694 error "TODO ModuleExposing" exposing row col
696 PortModuleProblem row col ->
698 region = toRegion row col
700 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
701 Code.toSnippet source region Nothing
704 "I am parsing an `port module` declaration, but I got stuck here:"
708 "Here are some examples of valid `port module` declarations:"
709 , D.indent 4 $ D.vcat $
710 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
711 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
713 , D.link "Note" "Read" "ports" "for more help."
717 PortModuleName row col ->
719 region = toRegion row col
721 Report.Report "EXPECTING MODULE NAME" region [] $
722 Code.toSnippet source region Nothing
725 "I was parsing an `module` declaration until I got stuck here:"
729 "I was expecting to see the module name next, like in these examples:"
730 , D.indent 4 $ D.vcat $
731 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
732 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
735 "Notice that the module names start with capital letters. That is required!"
739 PortModuleExposing exposing row col ->
740 error "TODO PortModuleExposing" exposing row col
744 region = toRegion row col
746 Report.Report "BAD MODULE DECLARATION" region [] $
747 Code.toSnippet source region Nothing
750 "I cannot parse this module declaration:"
753 "This type of module is reserved for the @elm organization. It is used to\
754 \ define certain effects, avoiding building them into the compiler."
759 region = toRegion row col
761 toBadFirstLineReport keyword =
762 Report.Report "TOO MUCH INDENTATION" region [] $
763 Code.toSnippet source region Nothing
766 "This `" ++ keyword ++ "` should not have any spaces before it:"
769 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
773 case Code.whatIsNext source row col of
774 Code.Keyword "module" -> toBadFirstLineReport "module"
775 Code.Keyword "import" -> toBadFirstLineReport "import"
776 Code.Keyword "type" -> toBadFirstLineReport "type"
777 Code.Keyword "port" -> toBadFirstLineReport "port"
779 Report.Report "SYNTAX PROBLEM" region [] $
780 Code.toSnippet source region Nothing
787 "I am not sure what is going on, but I recommend starting an Elm\
788 \ file with the following lines:"
790 [ D.fillSep [D.cyan "import","Html"]
792 , D.fillSep [D.green "main","="]
793 , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
796 "You should be able to copy those lines directly into your file. Check out\
797 \ some of the examples on https://elm-lang.org for more help getting started!"
799 "This can also happen when something is indented too much!"
803 ImportStart row col ->
804 toImportReport source row col
806 ImportName row col ->
808 region = toRegion row col
810 Report.Report "EXPECTING IMPORT NAME" region [] $
811 Code.toSnippet source region Nothing
814 "I was parsing an `import` until I got stuck here:"
818 "I was expecting to see a module name next, like in these examples:"
819 , D.indent 4 $ D.vcat $
820 [ D.fillSep [D.cyan "import","Dict"]
821 , D.fillSep [D.cyan "import","Maybe"]
822 , D.fillSep [D.cyan "import","Html.Attributes"]
823 , D.fillSep [D.cyan "import","Json.Decode"]
826 "Notice that the module names all start with capital letters. That is required!"
831 toImportReport source row col
833 ImportAlias row col ->
835 region = toRegion row col
837 Report.Report "EXECTING IMPORT ALIAS" region [] $
838 Code.toSnippet source region Nothing
841 "I was parsing an `import` until I got stuck here:"
845 "I was expecting to see an alias next, like in these examples:"
846 , D.indent 4 $ D.vcat $
847 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
848 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
849 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
852 "Notice that the alias always starts with a capital letter. That is required!"
856 ImportExposing row col ->
857 toImportReport source row col
859 ImportExposingList exposing row col ->
860 error "TODO ImportExposingList" exposing row col
863 toImportReport source row col
865 ImportIndentName row col ->
866 toImportReport source row col
868 ImportIndentAlias row col ->
869 toImportReport source row col
871 ImportIndentExposingList row col ->
873 region = toRegion row col
875 Report.Report "UNFINISHED IMPORT" region [] $
876 Code.toSnippet source region Nothing
879 "I was parsing an `import` until I got stuck here:"
883 "I was expecting to see the list of exposed values next. For example, here\
884 \ are two ways to expose values from the `Html` module:"
885 , D.indent 4 $ D.vcat $
886 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
887 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
890 "I generally recommend the second style. It is more explicit, making it\
891 \ much easier to figure out where values are coming from in large projects!"
897 region = toRegion row col
899 Report.Report "BAD INFIX" region [] $
900 Code.toSnippet source region Nothing
903 "Something went wrong in this infix operator declaration:"
906 "This feature is used by the @elm organization to define the\
907 \ languages built-in operators."
910 Declarations decl _ _ ->
911 toDeclarationsReport source decl
918toImportReport :: Code.Source -> Row -> Col -> Report.Report
919toImportReport source row col =
921 region = toRegion row col
923 Report.Report "UNFINISHED IMPORT" region [] $
924 Code.toSnippet source region Nothing
927 "I am partway through parsing an import, but I got stuck here:"
931 "Here are some examples of valid `import` declarations:"
932 , D.indent 4 $ D.vcat $
933 [ D.fillSep [D.cyan "import","Html"]
934 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
935 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
936 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
939 "You are probably trying to import a different module, but try to make it look like one of these examples!"
948toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
949toSpaceReport source space row col =
953 region = toRegion row col
955 Report.Report "NO TABS" region [] $
956 Code.toSnippet source region Nothing
959 "I ran into a tab, but tabs are not allowed in Elm files."
962 "Replace the tab with spaces."
965 EndlessMultiComment ->
967 region = toWiderRegion row col 2
969 Report.Report "ENDLESS COMMENT" region [] $
970 Code.toSnippet source region Nothing
973 "I cannot find the end of this multi-line comment:"
976 [ D.reflow "Add a -} somewhere after this to end the comment."
978 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
979 \ that happens to contain another comment. Like parentheses and curly braces,\
980 \ the start and end markers must always be balanced. Maybe that is the problem?"
989toRegion :: Row -> Col -> A.Region
992 pos = A.Position row col
997toWiderRegion :: Row -> Col -> Word16 -> A.Region
998toWiderRegion row col extra =
1000 (A.Position row col)
1001 (A.Position row (col + extra))
1004toKeywordRegion :: Row -> Col -> [Char.Char] -> A.Region
1005toKeywordRegion row col keyword =
1007 (A.Position row col)
1008 (A.Position row (col + fromIntegral (length keyword)))
1011toDeclarationsReport :: Code.Source -> Decl -> Report.Report
1012toDeclarationsReport source decl =
1014 DeclStart row col ->
1015 error "TODO DeclStart" row col
1017 DeclSpace space row col ->
1018 toSpaceReport source space row col
1020 Port port_ row col ->
1021 error "TODO Port" port_ row col
1023 DeclType declType row col ->
1024 toDeclTypeReport source declType row col
1026 DeclDef name declDef row col ->
1027 toDeclDefReport source name declDef row col
1029 DeclFreshLineStart row col ->
1030 error "TODO DeclFreshLineStart" row col
1032 DeclFreshLineAfterDocComment row col ->
1033 error "TODO DeclFreshLineAfterDocComment" row col
1040toDeclTypeReport :: Code.Source -> DeclType -> Row -> Col -> Report.Report
1041toDeclTypeReport source declType startRow startCol =
1043 DT_Space space row col ->
1044 toSpaceReport source space row col
1048 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1049 region = toRegion row col
1051 Report.Report "EXPECTING TYPE NAME" region [] $
1052 Code.toSnippet source surroundings (Just region)
1055 "I think I am parsing a type declaration, but I got stuck here:"
1059 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1060 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1066 DT_Alias typeAlias row col ->
1067 toTypeAliasReport source typeAlias row col
1069 DT_Union customType row col ->
1070 toCustomTypeReport source customType row col
1072 DT_IndentName row col ->
1074 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1075 region = toRegion row col
1077 Report.Report "EXPECTING TYPE NAME" region [] $
1078 Code.toSnippet source surroundings (Just region)
1081 "I think I am parsing a type declaration, but I got stuck here:"
1085 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1086 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1093toTypeAliasReport :: Code.Source -> TypeAlias -> Row -> Col -> Report.Report
1094toTypeAliasReport source typeAlias startRow startCol =
1096 AliasSpace space row col ->
1097 toSpaceReport source space row col
1099 AliasName row col ->
1101 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1102 region = toRegion row col
1104 Report.Report "EXPECTING TYPE ALIAS NAME" region [] $
1105 Code.toSnippet source surroundings (Just region)
1108 "I am partway through parsing a type alias, but I got stuck here:"
1112 ["I","was","expecting","a","name","like",D.dullyellow "Person","or",D.dullyellow "Point"
1113 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1119 AliasEquals row col ->
1120 case Code.whatIsNext source row col of
1121 Code.Keyword keyword ->
1123 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1124 region = toKeywordRegion row col keyword
1126 Report.Report "RESERVED WORD" region [] $
1127 Code.toSnippet source surroundings (Just region)
1130 "I ran into a reserved word unexpectedly while parsing this type alias:"
1134 "It looks like you are trying use `" ++ keyword
1135 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1142 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1143 region = toRegion row col
1145 Report.Report "PROBLEM IN TYPE ALIAS" region [] $
1146 Code.toSnippet source surroundings (Just region)
1149 "I am partway through parsing a type alias, but I got stuck here:"
1153 "I was expecting to see a type variable or an an equals sign next."
1158 AliasBody tipe row col ->
1159 toTypeReport source tipe row col
1161 AliasIndentEquals row col ->
1163 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1164 region = toRegion row col
1166 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1167 Code.toSnippet source surroundings (Just region)
1170 "I am partway through parsing a type alias, but I got stuck here:"
1174 "I was expecting to see a type variable or an an equals sign next."
1179 AliasIndentBody row col ->
1181 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1182 region = toRegion row col
1184 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1185 Code.toSnippet source surroundings (Just region)
1188 "I am partway through parsing a type alias, but I got stuck here:"
1192 ["I","was","expecting","to","see","a","type","next.","Something","as","simple"
1193 ,"as",D.dullyellow "Int","or",D.dullyellow "Float","would","work!"
1200typeAliasNote :: D.Doc
1204 "Here is an example of a valid `type alias` for reference:"
1206 [ D.indent 0 $ D.fillSep [D.cyan "type",D.cyan "alias",D.green "Person","="]
1207 , D.indent 2 $ D.vcat $
1215 "This would let us use `Person` as a shorthand for that record type. Using this\
1216 \ shorthand makes type annotations much easier to read, and makes changing code\
1217 \ easier if you decide later that there is more to a person than age and height!"
1221toCustomTypeReport :: Code.Source -> CustomType -> Row -> Col -> Report.Report
1222toCustomTypeReport source customType startRow startCol =
1224 CT_Space space row col ->
1225 toSpaceReport source space row col
1229 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1230 region = toRegion row col
1232 Report.Report "EXPECTING TYPE NAME" region [] $
1233 Code.toSnippet source surroundings (Just region)
1236 "I think I am parsing a type declaration, but I got stuck here:"
1240 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1241 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1247 CT_Equals row col ->
1248 case Code.whatIsNext source row col of
1249 Code.Keyword keyword ->
1251 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1252 region = toKeywordRegion row col keyword
1254 Report.Report "RESERVED WORD" region [] $
1255 Code.toSnippet source surroundings (Just region)
1258 "I ran into a reserved word unexpectedly while parsing this custom type:"
1262 "It looks like you are trying use `" ++ keyword
1263 ++ "` as a type variable, but it is a reserved word. Try using a different name?"
1270 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1271 region = toRegion row col
1273 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1274 Code.toSnippet source surroundings (Just region)
1277 "I am partway through parsing a custom type, but I got stuck here:"
1281 "I was expecting to see a type variable or an an equals sign next."
1288 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1289 region = toRegion row col
1291 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1292 Code.toSnippet source surroundings (Just region)
1295 "I am partway through parsing a custom type, but I got stuck here:"
1299 "I was expecting to see a vertical bar like | next."
1304 CT_Variant row col ->
1306 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1307 region = toRegion row col
1309 Report.Report "PROBLEM IN CUSTOM TYPE" region [] $
1310 Code.toSnippet source surroundings (Just region)
1313 "I am partway through parsing a custom type, but I got stuck here:"
1317 ["I","was","expecting","to","see","a","variant","name","next."
1318 ,"Something","like",D.dullyellow "Success","or",D.dullyellow "Sandwich" <> "."
1319 ,"Any","name","that","starts","with","a","capital","letter","really!"
1325 CT_VariantArg tipe row col ->
1326 toTypeReport source tipe row col
1328 CT_IndentEquals row col ->
1330 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1331 region = toRegion row col
1333 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1334 Code.toSnippet source surroundings (Just region)
1337 "I am partway through parsing a custom type, but I got stuck here:"
1341 "I was expecting to see a type variable or an an equals sign next."
1346 CT_IndentBar row col ->
1348 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1349 region = toRegion row col
1351 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1352 Code.toSnippet source surroundings (Just region)
1355 "I am partway through parsing a custom type, but I got stuck here:"
1359 "I was expecting to see a vertical bar like | next."
1364 CT_IndentAfterBar row col ->
1366 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1367 region = toRegion row col
1369 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1370 Code.toSnippet source surroundings (Just region)
1373 "I am partway through parsing a custom type, but I got stuck here:"
1377 "I just saw a vertical bar, so I was expecting to see another variant defined next."
1382 CT_IndentAfterEquals row col ->
1384 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1385 region = toRegion row col
1387 Report.Report "UNFINISHED CUSTOM TYPE" region [] $
1388 Code.toSnippet source surroundings (Just region)
1391 "I am partway through parsing a custom type, but I got stuck here:"
1395 "I just saw an equals sign, so I was expecting to see the first variant defined next."
1401customTypeNote :: D.Doc
1405 "Here is an example of a valid `type` declaration for reference:"
1407 [ D.indent 0 $ D.fillSep [D.cyan "type",D.green "Status"]
1408 , D.indent 2 $ D.fillSep ["=","Failure"]
1409 , D.indent 2 $ D.fillSep ["|","Waiting"]
1410 , D.indent 2 $ D.fillSep ["|","Success","String"]
1413 "This defines a new `Status` type with three variants. This could be useful if\
1414 \ we are waiting for an HTTP request. Maybe we start with `Waiting` and then\
1415 \ switch to `Failure` or `Success \"message from server\"` depending on how\
1416 \ things go. Notice that the Success variant has some associated data, allowing\
1417 \ us to store a String if the request goes well!"
1425toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
1426toDeclDefReport source name declDef startRow startCol =
1428 DeclDefSpace space row col ->
1429 toSpaceReport source space row col
1431 DeclDefEquals row col ->
1432 case Code.whatIsNext source row col of
1433 Code.Keyword keyword ->
1435 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1436 region = toKeywordRegion row col keyword
1438 Report.Report "RESERVED WORD" region [] $
1439 Code.toSnippet source surroundings (Just region)
1442 "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
1445 "This is a reserved word! Try using some other name?"
1450 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1451 region = toKeywordRegion row col op
1453 Report.Report "UNEXPECTED SYMBOL" region [] $
1454 Code.toSnippet source surroundings (Just region)
1457 "I was not expecting to see this symbol here:"
1461 "I am not sure what is going wrong exactly, so here is a valid\
1462 \ definition (with an optional type annotation) for reference:"
1464 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1465 , D.fillSep [D.green "add","x","y","="]
1466 , D.fillSep [" ","x","+","y"]
1469 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
1475 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1476 region = toRegion row col
1478 Report.Report "PROBLEM IN DEFINITION" region [] $
1479 Code.toSnippet source surroundings (Just region)
1482 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
1486 "I am not sure what is going wrong exactly, so here is a valid\
1487 \ definition (with an optional type annotation) for reference:"
1489 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1490 , D.fillSep [D.green "add","x","y","="]
1491 , D.fillSep [" ","x","+","y"]
1494 "Try to use that format!"
1498 DeclDefType tipe row col ->
1499 toTypeReport source tipe row col
1501 DeclDefArg pattern row col ->
1502 toPatternReport source PArg pattern row col
1504 DeclDefBody expr row col ->
1505 toExprReport source (InDef name startRow startCol) expr row col
1507 DeclDefNameRepeat row col ->
1509 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1510 region = toRegion row col
1512 Report.Report "EXPECTING DEFINITION" region [] $
1513 Code.toSnippet source surroundings (Just region)
1516 "I just saw the type annotation for `" ++ Name.toChars name
1517 ++ "` so I was expecting to see its definition here:"
1520 "Type annotations always appear directly above the relevant\
1521 \ definition, without anything else (even doc comments) in between."
1524 DeclDefNameMatch defName row col ->
1526 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1527 region = toRegion row col
1529 Report.Report "NAME MISMATCH" region [] $
1530 Code.toSnippet source surroundings (Just region)
1533 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
1537 "These names do not match! Is there a typo?"
1538 , D.indent 4 $ D.fillSep $
1539 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
1543 DeclDefIndentType row col ->
1544 error "TODO DeclDefIndentType" row col
1546 DeclDefIndentEquals row col ->
1547 error "TODO DeclDefIndentEquals" row col
1549 DeclDefIndentBody row col ->
1550 error "TODO DeclDefIndentBody" row col
1552 DeclDefFreshLineAfterType row col ->
1553 error "TODO DeclDefFreshLineAfterType" row col
1561 = InNode Node Row Col Context
1562 | InDef Name.Name Row Col
1578getDefName :: Context -> Name.Name
1581 InDef name _ _ -> name
1582 InNode _ _ _ c -> getDefName c
1585isWithin :: Node -> Context -> Bool
1586isWithin desiredNode context =
1588 InDef _ _ _ -> False
1589 InNode actualNode _ _ _ -> desiredNode == actualNode
1596toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
1597toExprReport source context expr startRow startCol =
1600 toLetReport source context let_ row col
1602 Case case_ row col ->
1603 toCaseReport source context case_ row col
1606 toIfReport source context if_ row col
1608 List list row col ->
1609 toListReport source context list row col
1611 Record record row col ->
1612 toRecordReport source context record row col
1614 Tuple tuple row col ->
1615 toTupleReport source context tuple row col
1617 Func func row col ->
1618 toFuncReport source context func row col
1621 let region = toRegion row col in
1622 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
1623 Code.toSnippet source region Nothing
1626 "I was expecting to see a record accessor here:"
1629 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
1630 ,"that","accesses","a","value","from","a","record."
1635 let region = toRegion row col in
1636 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
1637 Code.toSnippet source region Nothing
1640 "I am trying to parse a record accessor here:"
1645 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
1646 ,"that","accesses","a","value","from","a","record."
1650 "Record field names must start with a lower case letter!"
1654 OperatorRight op row col ->
1655 let region = toRegion row col in
1656 Report.Report "MISSING EXPRESSION" region [] $
1657 Code.toSnippet source region Nothing
1660 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1664 ["You","can","just","put","anything","for","now,","like"
1665 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1666 ,"Once","there","is","something","there,","I","can","probably"
1667 ,"give","a","more","specific","hint!"
1670 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
1671 \ Or if I run into operators in unexpected spots. Point is, there are a\
1672 \ couple ways I can get confused and give sort of weird advice!"
1676 OperatorReserved operator row col ->
1677 toOperatorReport source context operator row col
1681 (contextRow, contextCol, aThing) =
1683 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
1684 InNode NRecord r c _ -> (r, c, "a record")
1685 InNode NParens r c _ -> (r, c, "some parentheses")
1686 InNode NList r c _ -> (r, c, "a list")
1687 InNode NFunc r c _ -> (r, c, "an anonymous function")
1688 InNode NCond r c _ -> (r, c, "an `if` expression")
1689 InNode NThen r c _ -> (r, c, "an `if` expression")
1690 InNode NElse r c _ -> (r, c, "an `if` expression")
1691 InNode NCase r c _ -> (r, c, "a `case` expression")
1692 InNode NBranch r c _ -> (r, c, "a `case` expression")
1693 -- TODO check if this is actually the best way to get error messages here
1695 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
1696 region = toRegion row col
1698 Report.Report "MISSING EXPRESSION" region [] $
1699 Code.toSnippet source surroundings (Just region)
1702 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
1706 ["I","was","expecting","to","see","an","expression","like"
1707 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1708 ,"Once","there","is","something","there,","I","can","probably"
1709 ,"give","a","more","specific","hint!"
1712 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
1713 \ Or if I run into operators in unexpected spots. Point is, there are a\
1714 \ couple ways I can get confused and give sort of weird advice!"
1718 Char char row col ->
1719 toCharReport source char row col
1721 String string row col ->
1722 toStringReport source string row col
1724 Number number row col ->
1725 toNumberReport source number row col
1727 Space space row col ->
1728 toSpaceReport source space row col
1730 EndlessShader row col ->
1732 region = toWiderRegion row col 6
1734 Report.Report "ENDLESS SHADER" region [] $
1735 Code.toSnippet source region Nothing
1737 D.reflow "I cannot find the end of this shader:"
1739 D.reflow "Add a |] somewhere after this to end the shader."
1742 ShaderProblem problem row col ->
1744 region = toRegion row col
1746 Report.Report "SHADER PROBLEM" region [] $
1747 Code.toSnippet source region Nothing
1750 "I ran into a problem while parsing this GLSL block."
1754 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
1755 , D.indent 4 $ D.vcat $
1756 map D.fromChars (filter (/="") (lines problem))
1760 IndentOperatorRight op row col ->
1762 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1763 region = toRegion row col
1765 Report.Report "MISSING EXPRESSION" region [] $
1766 Code.toSnippet source surroundings (Just region)
1769 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1774 ["You","can","just","put","anything","for","now,","like"
1775 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1776 ,"Once","there","is","something","there,","I","can","probably"
1777 ,"give","a","more","specific","hint!"
1781 "I may be getting confused by your indentation? The easiest way to make sure\
1782 \ this is not an indentation problem is to put the expression on the right of\
1783 \ the " ++ Name.toChars op ++ " operator on the same line."
1787 IndentMoreExpr _ _ ->
1788 error "TODO IndentMoreExpr"
1795toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
1796toCharReport source char row col =
1800 region = toRegion row col
1802 Report.Report "MISSING SINGLE QUOTE" region [] $
1803 Code.toSnippet source region Nothing
1806 "I thought I was parsing a character, but I got to the end of\
1807 \ the line without seeing the closing single quote:"
1810 "Add a closing single quote here!"
1813 CharEscape escape ->
1814 toEscapeReport source escape row col
1816 CharNotString width ->
1818 region = toWiderRegion row col width
1820 Report.Report "NEEDS DOUBLE QUOTES" region [] $
1821 Code.toSnippet source region Nothing
1823 "The following string uses single quotes:"
1826 [ "Please switch to double quotes instead:"
1828 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
1830 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
1831 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
1832 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
1833 \ individual characters."
1842toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
1843toStringReport source string row col =
1845 StringEndless_Single ->
1847 region = toRegion row col
1849 Report.Report "ENDLESS STRING" region [] $
1850 Code.toSnippet source region Nothing
1853 "I got to the end of the line without seeing the closing double quote:"
1857 ["Strings","look","like",D.green "\"this\"","with","double"
1858 ,"quotes","on","each","end.","Is","the","closing","double"
1859 ,"quote","missing","in","your","code?"
1861 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
1865 StringEndless_Multi ->
1867 region = toWiderRegion row col 3
1869 Report.Report "ENDLESS STRING" region [] $
1870 Code.toSnippet source region Nothing
1873 "I cannot find the end of this multi-line string:"
1876 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
1877 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
1881 StringEscape escape ->
1882 toEscapeReport source escape row col
1889toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1890toEscapeReport source escape row col =
1894 region = toWiderRegion row col 2
1896 Report.Report "UNKNOWN ESCAPE" region [] $
1897 Code.toSnippet source region Nothing
1900 "Backslashes always start escaped characters, but I do not recognize this one:"
1904 "Valid escape characters include:"
1905 , D.dullyellow $ D.indent 4 $ D.vcat $
1915 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1917 "The last style lets encode ANY character by its Unicode code\
1918 \ point. That means \\u{0009} and \\t are the same. You can use\
1919 \ that style for anything not covered by the other six escapes!"
1923 BadUnicodeFormat width ->
1925 region = toWiderRegion row col width
1927 Report.Report "BAD UNICODE ESCAPE" region [] $
1928 Code.toSnippet source region Nothing
1931 "I ran into an invalid Unicode escape:"
1935 "Here are some examples of valid Unicode escapes:"
1936 , D.dullyellow $ D.indent 4 $ D.vcat $
1943 "Notice that the code point is always surrounded by curly braces.\
1944 \ Maybe you are missing the opening or closing curly brace?"
1947 BadUnicodeCode width ->
1949 region = toWiderRegion row col width
1951 Report.Report "BAD UNICODE ESCAPE" region [] $
1952 Code.toSnippet source region Nothing
1955 "This is not a valid code point:"
1958 "The valid code points are between 0 and 10FFFF inclusive."
1961 BadUnicodeLength width numDigits badCode ->
1963 region = toWiderRegion row col width
1965 Report.Report "BAD UNICODE ESCAPE" region [] $
1966 Code.toSnippet source region Nothing $
1967 if numDigits < 4 then
1970 "Every code point needs at least four digits:"
1973 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1974 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1976 D.fillSep ["Try",D.green suggestion,"instead?"]
1982 "This code point has too many digits:"
1985 ["Valid","code","points","are","between"
1986 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1987 ,"so","try","trimming","any","leading","zeros","until"
1988 ,"you","have","between","four","and","six","digits."
1997toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1998toNumberReport source number row col =
2000 region = toRegion row col
2004 Report.Report "WEIRD NUMBER" region [] $
2005 Code.toSnippet source region Nothing
2008 "I thought I was reading a number, but I ran into some weird stuff here:"
2012 "I recognize numbers in the following formats:"
2013 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
2015 "So is there a way to write it like one of those?"
2020 Report.Report "WEIRD NUMBER" region [] $
2021 Code.toSnippet source region Nothing
2024 "Numbers cannot end with a dot like this:"
2027 ["Switching","to",D.green (D.fromChars (show int))
2028 ,"or",D.green (D.fromChars (show int ++ ".0"))
2029 ,"will","work","though!"
2034 Report.Report "WEIRD HEXIDECIMAL" region [] $
2035 Code.toSnippet source region Nothing
2038 "I thought I was reading a hexidecimal number until I got here:"
2042 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
2043 \ only recognize things like this:"
2044 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
2048 NumberNoLeadingZero ->
2049 Report.Report "LEADING ZEROS" region [] $
2050 Code.toSnippet source region Nothing
2053 "I do not accept numbers with leading zeros:"
2057 "Just delete the leading zeros and it should work!"
2059 "Some languages let you to specify octal numbers by adding a leading zero.\
2060 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
2061 \ that, but others probably want it to equal 111. Either path is going to\
2062 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
2072toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
2073toOperatorReport source context operator row col =
2077 region = toRegion row col
2079 Report.Report "UNEXPECTED SYMBOL" region [] $
2080 Code.toSnippet source region Nothing
2082 "I was not expecting this dot:"
2085 "Dots are for record access and decimal points, so\
2086 \ they cannot float around on their own. Maybe\
2087 \ there is some extra whitespace?"
2092 region = toRegion row col
2094 Report.Report "UNEXPECTED SYMBOL" region [] $
2095 Code.toSnippet source region Nothing
2098 "I was not expecting this vertical bar:"
2101 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
2106 region = toWiderRegion row col 2
2108 Report.Report "UNEXPECTED ARROW" region [] $
2109 Code.toSnippet source region Nothing $
2110 if isWithin NBranch context then
2113 "I was not expecting to see an arrow here:"
2118 "I think I am parsing a `case` expression right now, so it makes sense to\
2119 \ see arrows around here. This one is confusing me though!"
2122 "I may be getting confused by the indentation. Every pattern in a `case` must be\
2123 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
2124 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
2125 \ indented too far?"
2132 "I was not expecting an arrow here:"
2135 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
2136 \ you want > or >= instead?"
2141 region = toRegion row col
2142 name = getDefName context
2144 Report.Report "UNEXPECTED EQUALS" region [] $
2145 Code.toSnippet source region Nothing
2148 "I was not expecting to see this equals sign:"
2152 D.reflow "Maybe you want == instead? To check if two values are equal?"
2155 if isWithin NRecord context then
2156 "Records look like { x = 3, y = 4 } with the equals sign right\
2157 \ after the field name. So maybe you forgot a comma?"
2159 "I may be getting confused by your indentation. Is this supposed to be part of\
2160 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
2161 \ the problem may be a bit before the equals sign. I need all definitions to\
2162 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
2163 \ this new definition is indented a bit too much."
2169 region = toRegion row col
2170 name = getDefName context
2172 Report.Report "UNEXPECTED SYMBOL" region [] $
2173 Code.toSnippet source region Nothing $
2176 "I was not expecting to run into the \"has type\" symbol here:"
2181 ["Maybe","you","want",D.green "::","instead?"
2182 ,"To","put","something","on","the","front","of","a","list?"
2185 "The single colon is reserved for type annotations and record types, but I think\
2186 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
2189 "I may be getting confused by your indentation. Is this supposed to be part of\
2190 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
2191 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
2192 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
2193 \ this new definition is indented a bit too much."
2202toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
2203toLetReport source context let_ startRow startCol =
2205 LetSpace space row col ->
2206 toSpaceReport source space row col
2210 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2211 region = toRegion row col
2213 Report.Report "LET PROBLEM" region [] $
2214 Code.toSnippet source surroundings (Just region)
2217 "I was partway through parsing a `let` expression, but I got stuck here:"
2221 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2222 ,"keyword","next.","Is","there","a","typo?"
2225 "This can also happen if you are trying to define another value within the `let` but\
2226 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2227 \ spaces before it. They should line up exactly!"
2231 LetDefAlignment _ row col ->
2233 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2234 region = toRegion row col
2236 Report.Report "LET PROBLEM" region [] $
2237 Code.toSnippet source surroundings (Just region)
2240 "I was partway through parsing a `let` expression, but I got stuck here:"
2244 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2245 ,"keyword","next.","Is","there","a","typo?"
2248 "This can also happen if you are trying to define another value within the `let` but\
2249 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2250 \ spaces before it. The should line up exactly!"
2254 LetDefName row col ->
2255 case Code.whatIsNext source row col of
2256 Code.Keyword keyword ->
2258 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2259 region = toKeywordRegion row col keyword
2261 Report.Report "RESERVED WORD" region [] $
2262 Code.toSnippet source surroundings (Just region)
2265 "I was partway through parsing a `let` expression, but I got stuck here:"
2268 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
2269 \ it is a reserved word! Try using a different name instead."
2273 toUnfinishLetReport source row col startRow startCol $
2275 "I was expecting the name of a definition next."
2277 LetDef name def row col ->
2278 error "TODO LetDef" name def row col
2280 LetDestruct destruct row col ->
2281 error "TODO LetDestruct" destruct row col
2283 LetBody expr row col ->
2284 toExprReport source context expr row col
2286 LetIndentDef row col ->
2287 toUnfinishLetReport source row col startRow startCol $
2289 "I was expecting a value to be defined here."
2291 LetIndentIn row col ->
2292 toUnfinishLetReport source row col startRow startCol $
2294 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
2295 ,"Or","maybe","more","of","that","expression?"
2298 LetIndentBody row col ->
2299 toUnfinishLetReport source row col startRow startCol $
2301 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
2304toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
2305toUnfinishLetReport source row col startRow startCol message =
2307 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2308 region = toRegion row col
2310 Report.Report "UNFINISHED LET" region [] $
2311 Code.toSnippet source surroundings (Just region)
2314 "I was partway through parsing a `let` expression, but I got stuck here:"
2319 "Here is an example with a valid `let` expression for reference:"
2321 [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
2322 , D.indent 2 $ D.fillSep [D.cyan "let"]
2323 , D.indent 4 $ D.fillSep ["fullName","="]
2324 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
2325 , D.indent 2 $ D.fillSep [D.cyan "in"]
2326 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
2329 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
2330 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
2331 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
2332 \ indented a bit more than that. That is important!"
2341toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
2342toCaseReport source context case_ startRow startCol =
2344 CaseSpace space row col ->
2345 toSpaceReport source space row col
2348 toUnfinishCaseReport source row col startRow startCol $
2349 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
2351 CasePattern pattern row col ->
2352 toPatternReport source PCase pattern row col
2354 CaseArrow row col ->
2355 case Code.whatIsNext source row col of
2356 Code.Keyword keyword ->
2358 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2359 region = toKeywordRegion row col keyword
2361 Report.Report "RESERVED WORD" region [] $
2362 Code.toSnippet source surroundings (Just region)
2365 "I am partway through parsing a `case` expression, but I got stuck here:"
2368 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
2369 \ patterns, but it is a reserved word. Try using a different name?"
2372 Code.Operator ":" ->
2374 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2375 region = toRegion row col
2377 Report.Report "UNEXPECTED OPERATOR" region [] $
2378 Code.toSnippet source surroundings (Just region)
2381 "I am partway through parsing a `case` expression, but I got stuck here:"
2384 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
2385 ,"For","pattern","matching","on","lists?"
2389 Code.Operator "=" ->
2391 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2392 region = toRegion row col
2394 Report.Report "UNEXPECTED OPERATOR" region [] $
2395 Code.toSnippet source surroundings (Just region)
2398 "I am partway through parsing a `case` expression, but I got stuck here:"
2401 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
2407 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2408 region = toRegion row col
2410 Report.Report "MISSING ARROW" region [] $
2411 Code.toSnippet source surroundings (Just region)
2414 "I am partway through parsing a `case` expression, but I got stuck here:"
2416 addNoteForCaseIndentError $
2418 "I was expecting to see an arrow next."
2421 CaseExpr expr row col ->
2422 toExprReport source (InNode NCase startRow startCol context) expr row col
2424 CaseBranch expr row col ->
2425 toExprReport source (InNode NBranch startRow startCol context) expr row col
2427 CaseIndentOf row col ->
2428 toUnfinishCaseReport source row col startRow startCol $
2429 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
2431 CaseIndentExpr row col ->
2432 toUnfinishCaseReport source row col startRow startCol $
2433 D.reflow "I was expecting to see a expression next."
2435 CaseIndentPattern row col ->
2436 toUnfinishCaseReport source row col startRow startCol $
2437 D.reflow "I was expecting to see a pattern next."
2439 CaseIndentArrow row col ->
2440 toUnfinishCaseReport source row col startRow startCol $
2442 ["I","just","saw","a","pattern,","so","I","was","expecting"
2443 ,"to","see","a",D.dullyellow "->","next."
2446 CaseIndentBranch row col ->
2447 toUnfinishCaseReport source row col startRow startCol $
2449 "I was expecting to see an expression next. What should I do when\
2450 \ I run into this particular pattern?"
2452 CasePatternAlignment indent row col ->
2453 toUnfinishCaseReport source row col startRow startCol $
2455 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
2458toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
2459toUnfinishCaseReport source row col startRow startCol message =
2461 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2462 region = toRegion row col
2464 Report.Report "UNFINISHED CASE" region [] $
2465 Code.toSnippet source surroundings (Just region)
2468 "I was partway through parsing a `case` expression, but I got stuck here:"
2473 "Here is an example of a valid `case` expression for reference."
2475 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2476 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2477 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
2479 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2480 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
2483 "Notice the indentation. Each pattern is aligned, and each branch is indented\
2484 \ a bit more than the corresponding pattern. That is important!"
2489addNoteForCaseIndentError :: D.Doc -> D.Doc
2490addNoteForCaseIndentError message =
2495 "Sometimes I get confused by indentation, so try to make your `case` look\
2496 \ something like this:"
2498 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2499 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2500 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
2502 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2503 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
2506 "Notice the indentation! Each pattern is aligned, and each branch is indented\
2507 \ a bit more than the corresponding pattern. That is important!"
2515toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
2516toIfReport source context if_ startRow startCol =
2518 IfSpace space row col ->
2519 toSpaceReport source space row col
2523 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2524 region = toRegion row col
2526 Report.Report "UNFINISHED IF" region [] $
2527 Code.toSnippet source surroundings (Just region)
2530 "I was expecting to see more of this `if` expression, but I got stuck here:"
2533 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
2539 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2540 region = toRegion row col
2542 Report.Report "UNFINISHED IF" region [] $
2543 Code.toSnippet source surroundings (Just region)
2546 "I was expecting to see more of this `if` expression, but I got stuck here:"
2549 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
2553 IfElseBranchStart row col ->
2555 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2556 region = toRegion row col
2558 Report.Report "UNFINISHED IF" region [] $
2559 Code.toSnippet source surroundings (Just region)
2562 "I just saw the start of an `else` branch, but then I got stuck here:"
2565 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2568 IfCondition expr row col ->
2569 toExprReport source (InNode NCond startRow startCol context) expr row col
2571 IfThenBranch expr row col ->
2572 toExprReport source (InNode NThen startRow startCol context) expr row col
2574 IfElseBranch expr row col ->
2575 toExprReport source (InNode NElse startRow startCol context) expr row col
2577 IfIndentCondition row col ->
2579 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2580 region = toRegion row col
2582 Report.Report "UNFINISHED IF" region [] $
2583 Code.toSnippet source surroundings (Just region)
2586 "I was expecting to see more of this `if` expression, but I got stuck here:"
2590 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
2591 ,"that","evaluates","to","True","or","False."
2594 "I can be confused by indentation. Maybe something is not indented enough?"
2598 IfIndentThen row col ->
2600 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2601 region = toRegion row col
2603 Report.Report "UNFINISHED IF" region [] $
2604 Code.toSnippet source surroundings (Just region)
2607 "I was expecting to see more of this `if` expression, but I got stuck here:"
2611 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
2614 "I can be confused by indentation. Maybe something is not indented enough?"
2618 IfIndentThenBranch row col ->
2620 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2621 region = toRegion row col
2623 Report.Report "UNFINISHED IF" region [] $
2624 Code.toSnippet source surroundings (Just region)
2627 "I got stuck after the start of this `then` branch:"
2631 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2633 "I can be confused by indentation, so if the `then` branch is already\
2634 \ present, it may not be indented enough for me to recognize it."
2638 IfIndentElseBranch row col ->
2640 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2641 region = toRegion row col
2643 Report.Report "UNFINISHED IF" region [] $
2644 Code.toSnippet source surroundings (Just region)
2647 "I got stuck after the start of this `else` branch:"
2651 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2653 "I can be confused by indentation, so if the `else` branch is already\
2654 \ present, it may not be indented enough for me to recognize it."
2658 IfIndentElse row col ->
2660 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2661 region = toRegion row col
2663 Report.Report "UNFINISHED IF" region [] $
2664 Code.toSnippet source surroundings (Just region)
2667 "I was expecting to see an `else` branch after this:"
2671 "I know what to do when the condition is `True`, but not when it is `False`."
2673 ["Add","an",D.cyan "else","branch","to","handle","that","scenario!"]
2682toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
2683toRecordReport source context record startRow startCol =
2685 RecordOpen row col ->
2686 case Code.whatIsNext source row col of
2687 Code.Keyword keyword ->
2689 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2690 region = toKeywordRegion row col keyword
2692 Report.Report "RESERVED WORD" region [] $
2693 Code.toSnippet source surroundings (Just region)
2696 "I just started parsing a record, but I got stuck on this field name:"
2699 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
2700 \ that is a reserved word. Try using a different name!"
2705 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2706 region = toRegion row col
2708 Report.Report "UNFINISHED RECORD" region [] $
2709 Code.toSnippet source surroundings (Just region)
2712 "I just started parsing a record, but I got stuck here:"
2715 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
2716 ,"so","I","was","expecting","to","see","a","field","name","next."
2720 RecordEnd row col ->
2722 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2723 region = toRegion row col
2725 Report.Report "UNFINISHED RECORD" region [] $
2726 Code.toSnippet source surroundings (Just region)
2729 "I am partway through parsing a record, but I got stuck here:"
2733 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
2734 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
2737 "When I get stuck like this, it usually means that there is a missing parenthesis\
2738 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2742 RecordField row col ->
2743 case Code.whatIsNext source row col of
2744 Code.Keyword keyword ->
2746 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2747 region = toKeywordRegion row col keyword
2749 Report.Report "RESERVED WORD" region [] $
2750 Code.toSnippet source surroundings (Just region)
2753 "I am partway through parsing a record, but I got stuck on this field name:"
2756 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
2757 \ that is a reserved word. Try using a different name!"
2762 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2763 region = toRegion row col
2765 Report.Report "UNFINISHED RECORD" region [] $
2766 Code.toSnippet source surroundings (Just region)
2769 "I am partway through parsing a record, but I got stuck after that last comma:"
2771 addNoteForRecordError $
2773 "Trailing commas are not allowed in records, so I was expecting to see another\
2774 \ record field defined next. If you are done defining the record, the fix may\
2775 \ be to delete that last comma?"
2778 RecordEquals row col ->
2780 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2781 region = toRegion row col
2783 Report.Report "UNFINISHED RECORD" region [] $
2784 Code.toSnippet source surroundings (Just region)
2787 "I am partway through parsing a record, but I got stuck here:"
2789 addNoteForRecordError $
2791 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
2792 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
2796 RecordExpr expr row col ->
2797 toExprReport source (InNode NRecord startRow startCol context) expr row col
2799 RecordSpace space row col ->
2800 toSpaceReport source space row col
2802 RecordIndentOpen row col ->
2804 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2805 region = toRegion row col
2807 Report.Report "UNFINISHED RECORD" region [] $
2808 Code.toSnippet source surroundings (Just region)
2811 "I just saw the opening curly brace of a record, but then I got stuck here:"
2813 addNoteForRecordIndentError $
2815 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
2816 ,"Try","defining","some","fields","of","your","own?"
2820 RecordIndentEnd row col ->
2822 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2823 region = toRegion row col
2825 Report.Report "UNFINISHED RECORD" region [] $
2826 Code.toSnippet source surroundings (Just region)
2829 "I was expecting to see a closing curly brace next:"
2831 addNoteForRecordIndentError $
2833 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
2837 RecordIndentField row col ->
2839 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2840 region = toRegion row col
2842 Report.Report "UNFINISHED RECORD" region [] $
2843 Code.toSnippet source surroundings (Just region)
2846 "I am partway through parsing a record, but I got stuck after that last comma:"
2848 addNoteForRecordError $
2850 "Trailing commas are not allowed in records, so the fix may be to\
2851 \ delete that last comma? Or maybe you were in the middle of defining\
2852 \ an additional field?"
2855 RecordIndentEquals row col ->
2857 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2858 region = toRegion row col
2860 Report.Report "UNFINISHED RECORD" region [] $
2861 Code.toSnippet source surroundings (Just region)
2864 "I am partway through parsing a record. I just saw a record\
2865 \ field, so I was expecting to see an equals sign next:"
2867 addNoteForRecordIndentError $
2869 ["Try","putting","an",D.green "=","followed","by","an","expression?"
2873 RecordIndentExpr row col ->
2875 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2876 region = toRegion row col
2878 Report.Report "UNFINISHED RECORD" region [] $
2879 Code.toSnippet source surroundings (Just region)
2882 "I am partway through parsing a record, and I was expecting to run into an expression next:"
2884 addNoteForRecordIndentError $
2886 ["Try","putting","something,","like"
2887 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
2892addNoteForRecordError :: D.Doc -> D.Doc
2893addNoteForRecordError normalRecommendation =
2895 normalRecommendation
2898 "If you are trying to define a record across multiple lines, I recommend using this format:"
2899 , D.indent 4 $ D.vcat $
2900 [ "{ name = \"Alice\""
2906 "Notice that each line starts with some indentation. Usually two or four spaces. I\
2907 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
2908 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2912addNoteForRecordIndentError :: D.Doc -> D.Doc
2913addNoteForRecordIndentError normalRecommendation =
2915 normalRecommendation
2918 "I may be confused by indentation. For example, if you are trying to define\
2919 \ a record across multiple lines, I recommend using this format:"
2920 , D.indent 4 $ D.vcat $
2921 [ "{ name = \"Alice\""
2927 "Notice that each line starts with some indentation. Usually two or four spaces. I\
2928 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
2929 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2937toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
2938toTupleReport source context tuple startRow startCol =
2940 TupleExpr expr row col ->
2941 toExprReport source (InNode NParens startRow startCol context) expr row col
2943 TupleSpace space row col ->
2944 toSpaceReport source space row col
2948 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2949 region = toRegion row col
2951 Report.Report "UNFINISHED PARENTHESES" region [] $
2952 Code.toSnippet source surroundings (Just region)
2955 "I was expecting to see a closing parentheses next, but I got stuck here:"
2958 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
2960 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
2961 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
2962 \ or missing brackets) that is confusing me."
2966 TupleOperatorClose row col ->
2968 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2969 region = toRegion row col
2971 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
2972 Code.toSnippet source surroundings (Just region)
2974 D.reflow "I was expecting a closing parenthesis here:"
2977 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
2979 "I think I am parsing an operator function right now, so I am expecting to see\
2980 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
2985 TupleOperatorReserved operator row col ->
2987 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2988 region = toRegion row col
2990 Report.Report "UNEXPECTED SYMBOL" region [] $
2991 Code.toSnippet source surroundings (Just region)
2994 "I ran into an unexpected symbol here:"
2998 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
2999 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
3000 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
3001 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
3002 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
3005 TupleIndentExpr1 row col ->
3007 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3008 region = toRegion row col
3010 Report.Report "UNFINISHED PARENTHESES" region [] $
3011 Code.toSnippet source surroundings (Just region)
3014 "I just saw an open parenthesis, so I was expecting to see an expression next."
3018 ["Something","like",D.dullyellow "(4 + 5)","or"
3019 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
3020 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
3023 "I can get confused by indentation in cases like this, so\
3024 \ maybe you have an expression but it is not indented enough?"
3028 TupleIndentExprN row col ->
3030 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3031 region = toRegion row col
3033 Report.Report "UNFINISHED TUPLE" region [] $
3034 Code.toSnippet source surroundings (Just region)
3037 "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."
3041 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
3042 ,D.dullyellow "(\"Tom\",42)" <> ","
3043 ,"so","I","think","there","is","an","expression","missing","here?"
3046 "I can get confused by indentation in cases like this, so\
3047 \ maybe you have an expression but it is not indented enough?"
3051 TupleIndentEnd row col ->
3053 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3054 region = toRegion row col
3056 Report.Report "UNFINISHED PARENTHESES" region [] $
3057 Code.toSnippet source surroundings (Just region)
3060 "I was expecting to see a closing parenthesis next:"
3063 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
3065 "I can get confused by indentation in cases like this, so\
3066 \ maybe you have a closing parenthesis but it is not indented enough?"
3071toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
3072toListReport source context list startRow startCol =
3074 ListSpace space row col ->
3075 toSpaceReport source space row col
3079 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3080 region = toRegion row col
3082 Report.Report "UNFINISHED LIST" region [] $
3083 Code.toSnippet source surroundings (Just region)
3086 "I am partway through parsing a list, but I got stuck here:"
3090 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
3091 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
3094 "When I get stuck like this, it usually means that there is a missing parenthesis\
3095 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3099 ListExpr expr row col ->
3103 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
3104 region = toRegion r c
3106 Report.Report "UNFINISHED LIST" region [] $
3107 Code.toSnippet source surroundings (Just region)
3110 "I was expecting to see another list entry after that last comma:"
3114 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
3116 "I recommend using the following format for lists that span multiple lines:"
3117 , D.indent 4 $ D.vcat $
3124 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
3125 \ This style can be jarring for people coming from C-like syntax, but folks generally\
3126 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3131 toExprReport source (InNode NList startRow startCol context) expr row col
3135 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3136 region = toRegion row col
3138 Report.Report "UNFINISHED LIST" region [] $
3139 Code.toSnippet source surroundings (Just region)
3142 "I am partway through parsing a list, but I got stuck here:"
3146 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
3147 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
3150 "When I get stuck like this, it usually means that there is a missing parenthesis\
3151 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3155 ListIndentOpen row col ->
3157 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3158 region = toRegion row col
3160 Report.Report "UNFINISHED LIST" region [] $
3161 Code.toSnippet source surroundings (Just region)
3164 "I cannot find the end of this list:"
3168 ["You","could","change","it","to","something","like"
3169 ,D.dullyellow "[3,4,5]"
3171 ,D.dullyellow "[]" <> "."
3172 ,"Anything","where","there","is","an","open","and","close","square","brace,"
3173 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
3176 "I may be confused by indentation. For example, if you are trying to define\
3177 \ a list across multiple lines, I recommend using this format:"
3178 , D.indent 4 $ D.vcat $
3185 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
3186 \ This style can be jarring for people coming from C-like syntax, but folks generally\
3187 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3191 ListIndentEnd row col ->
3193 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3194 region = toRegion row col
3196 Report.Report "UNFINISHED LIST" region [] $
3197 Code.toSnippet source surroundings (Just region)
3200 "I cannot find the end of this list:"
3204 ["You","can","just","add","a","closing",D.dullyellow "]"
3205 ,"right","here,","and","I","will","be","all","set!"
3208 "I may be confused by indentation. For example, if you are trying to define\
3209 \ a list across multiple lines, I recommend using this format:"
3210 , D.indent 4 $ D.vcat $
3217 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
3218 \ This style can be jarring for people coming from C-like syntax, but folks generally\
3219 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3223 ListIndentExpr row col ->
3225 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3226 region = toRegion row col
3228 Report.Report "UNFINISHED LIST" region [] $
3229 Code.toSnippet source surroundings (Just region)
3232 "I was expecting to see another list entry after this comma:"
3236 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
3238 "I recommend using the following format for lists that span multiple lines:"
3239 , D.indent 4 $ D.vcat $
3246 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
3247 \ This style can be jarring for people coming from C-like syntax, but folks generally\
3248 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3253toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
3254toFuncReport source context func startRow startCol =
3256 FuncSpace space row col ->
3257 toSpaceReport source space row col
3259 FuncArg pattern row col ->
3260 toPatternReport source PArg pattern row col
3262 FuncBody expr row col ->
3263 toExprReport source (InNode NFunc startRow startCol context) expr row col
3265 FuncArrow row col ->
3266 case Code.whatIsNext source row col of
3267 Code.Keyword keyword ->
3269 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3270 region = toKeywordRegion row col keyword
3272 Report.Report "RESERVED WORD" region [] $
3273 Code.toSnippet source surroundings (Just region)
3276 "I was parsing an anonymous function, but I got stuck here:"
3279 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
3280 \ it is a reserved word in this language. Try using a different argument name!"
3285 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3286 region = toRegion row col
3288 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
3289 Code.toSnippet source surroundings (Just region)
3292 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
3295 ["The","syntax","for","anonymous","functions","is"
3296 ,D.dullyellow "(\\x -> x + 1)"
3297 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
3301 FuncIndentArg row col ->
3303 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3304 region = toRegion row col
3306 Report.Report "MISSING ARGUMENT" region [] $
3307 Code.toSnippet source surroundings (Just region)
3310 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
3314 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
3315 ,"Anything","that","starts","with","a","lower","case","letter!"
3318 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
3319 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
3320 \ like a better idea at the time!"
3324 FuncIndentArrow row col ->
3326 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3327 region = toRegion row col
3329 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
3330 Code.toSnippet source surroundings (Just region)
3333 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
3337 ["The","syntax","for","anonymous","functions","is"
3338 ,D.dullyellow "(\\x -> x + 1)"
3339 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
3342 "It is possible that I am confused about indetation! I generally recommend\
3343 \ switching to named functions if the definition cannot fit inline nicely, so\
3344 \ either (1) try to fit the whole anonymous function on one line or (2) break\
3345 \ the whole thing out into a named function. Things tend to be clearer that way!"
3349 FuncIndentBody row col ->
3351 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3352 region = toRegion row col
3354 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
3355 Code.toSnippet source surroundings (Just region)
3358 "I was expecting to see the body of your anonymous function next:"
3362 ["The","syntax","for","anonymous","functions","is"
3363 ,D.dullyellow "(\\x -> x + 1)"
3364 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
3367 "It is possible that I am confused about indetation! I generally recommend\
3368 \ switching to named functions if the definition cannot fit inline nicely, so\
3369 \ either (1) try to fit the whole anonymous function on one line or (2) break\
3370 \ the whole thing out into a named function. Things tend to be clearer that way!"
3384toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
3385toPatternReport source context pattern startRow startCol =
3387 PRecord record row col ->
3388 toPRecordReport source record row col
3390 PTuple tuple row col ->
3391 toPTupleReport source context tuple row col
3393 PList list row col ->
3394 toPListReport source context list row col
3397 case Code.whatIsNext source row col of
3398 Code.Keyword keyword ->
3400 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3401 region = toKeywordRegion row col keyword
3404 PArg -> "an argument"
3405 PCase -> "a pattern"
3407 Report.Report "RESERVED WORD" region [] $
3408 Code.toSnippet source surroundings (Just region)
3411 "It looks like you are trying to use `" ++ keyword ++ "` as " ++ aThing ++ ":"
3414 "This is a reserved word! Try using some other name?"
3420 PChar char row col ->
3421 toCharReport source char row col
3423 PString string row col ->
3424 toStringReport source string row col
3426 PNumber number row col ->
3427 toNumberReport source number row col
3429 PFloat width row col ->
3431 region = toWiderRegion row col width
3433 Report.Report "UNEXPECTED PATTERN" region [] $
3434 Code.toSnippet source region Nothing
3437 "I cannot pattern match with floating point numbers:"
3440 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
3441 ,"to","check","that","they","are","nearby","with","some","sort","of"
3442 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
3448 region = toRegion row col
3450 Report.Report "UNFINISHED PATTERN" region [] $
3451 Code.toSnippet source region Nothing $
3454 "I was expecting to see a variable name after the `as` keyword:"
3458 ["The","`as`","keyword","lets","you","write","patterns","like"
3459 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
3460 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
3461 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
3462 ,"thing","with",D.dullyellow "point."
3465 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
3466 \ people just want to use `as` as a variable name though. Try using a different name\
3471 PWildcardNotVar name width row col ->
3473 region = toWiderRegion row col (fromIntegral width)
3475 case dropWhile (=='_') (Name.toChars name) of
3476 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
3477 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
3479 Report.Report "UNEXPECTED NAME" region [] $
3480 Code.toSnippet source region Nothing $
3483 "Variable names cannot start with underscores like this:"
3486 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
3487 ,"ignore","the","value,","or","you","can","have","a","name","like"
3488 ] ++ examples ++ ["to","use","the","matched","value." ]
3491 PSpace space row col ->
3492 toSpaceReport source space row col
3494 PIndentStart row col ->
3495 error "TODO PIndentStart" row col
3497 PIndentAlias row col ->
3499 region = toRegion row col
3501 Report.Report "UNFINISHED PATTERN" region [] $
3502 Code.toSnippet source region Nothing $
3505 "I was expecting to see a variable name after the `as` keyword:"
3509 ["The","`as`","keyword","lets","you","write","patterns","like"
3510 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
3511 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
3512 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
3513 ,"thing","with",D.dullyellow "point."
3516 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
3517 \ people just want to use `as` as a variable name though. Try using a different name\
3523toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
3524toPRecordReport source record startRow startCol =
3526 PRecordOpen row col ->
3527 toUnfinishRecordPatternReport source row col startRow startCol $
3528 D.reflow "I was expecting to see a field name next."
3530 PRecordEnd row col ->
3531 toUnfinishRecordPatternReport source row col startRow startCol $
3533 ["I","was","expecting","to","see","a","closing","curly","brace","next."
3534 ,"Try","adding","a",D.dullyellow "}","here?"
3537 PRecordField row col ->
3538 case Code.whatIsNext source row col of
3539 Code.Keyword keyword ->
3541 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3542 region = toKeywordRegion row col keyword
3544 Report.Report "RESERVED WORD" region [] $
3545 Code.toSnippet source surroundings (Just region)
3548 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
3551 "This is a reserved word, not available for variable names. Try another name!"
3555 toUnfinishRecordPatternReport source row col startRow startCol $
3556 D.reflow "I was expecting to see a field name next."
3558 PRecordSpace space row col ->
3559 toSpaceReport source space row col
3561 PRecordIndentOpen row col ->
3562 toUnfinishRecordPatternReport source row col startRow startCol $
3563 D.reflow "I was expecting to see a field name next."
3565 PRecordIndentEnd row col ->
3566 toUnfinishRecordPatternReport source row col startRow startCol $
3568 ["I","was","expecting","to","see","a","closing","curly","brace","next."
3569 ,"Try","adding","a",D.dullyellow "}","here?"
3572 PRecordIndentField row col ->
3573 toUnfinishRecordPatternReport source row col startRow startCol $
3574 D.reflow "I was expecting to see a field name next."
3577toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3578toUnfinishRecordPatternReport source row col startRow startCol message =
3580 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3581 region = toRegion row col
3583 Report.Report "UNFINISHED RECORD PATTERN" region [] $
3584 Code.toSnippet source surroundings (Just region)
3587 "I was partway through parsing a record pattern, but I got stuck here:"
3592 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
3593 ,"where","you","list","the","field","names","you","want","to","access."
3600toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
3601toPTupleReport source context tuple startRow startCol =
3603 PTupleOpen row col ->
3604 case Code.whatIsNext source row col of
3605 Code.Keyword keyword ->
3607 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3608 region = toKeywordRegion row col keyword
3610 Report.Report "RESERVED WORD" region [] $
3611 Code.toSnippet source surroundings (Just region)
3614 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
3617 "This is a reserved word! Try using some other name?"
3622 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3623 region = toRegion row col
3625 Report.Report "UNFINISHED PARENTHESES" region [] $
3626 Code.toSnippet source surroundings (Just region)
3629 "I just saw an open parenthesis, but I got stuck here:"
3632 ["I","was","expecting","so","see","a","pattern","next."
3633 ,"Maybe","it","will","end","up","being","something"
3634 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3638 PTupleEnd row col ->
3640 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3641 region = toRegion row col
3643 Report.Report "UNFINISHED PARENTHESES" region [] $
3644 Code.toSnippet source surroundings (Just region) $
3647 "I was expecting a closing parenthesis next:"
3649 D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3652 PTupleExpr pattern row col ->
3653 toPatternReport source context pattern row col
3655 PTupleSpace space row col ->
3656 toSpaceReport source space row col
3658 PTupleIndentEnd row col ->
3660 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3661 region = toRegion row col
3663 Report.Report "UNFINISHED PARENTHESES" region [] $
3664 Code.toSnippet source surroundings (Just region) $
3667 "I was expecting a closing parenthesis next:"
3670 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3672 "I can get confused by indentation in cases like this, so\
3673 \ maybe you have a closing parenthesis but it is not indented enough?"
3677 PTupleIndentExpr1 row col ->
3679 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3680 region = toRegion row col
3682 Report.Report "UNFINISHED PARENTHESES" region [] $
3683 Code.toSnippet source surroundings (Just region) $
3686 "I just saw an open parenthesis, but then I got stuck here:"
3689 ["I","was","expecting","so","see","a","pattern","next."
3690 ,"Maybe","it","will","end","up","being","something"
3691 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3695 PTupleIndentExprN row col ->
3697 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3698 region = toRegion row col
3700 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
3701 Code.toSnippet source surroundings (Just region) $
3704 "I am partway through parsing a tuple pattern, but I got stuck here:"
3708 ["I","was","expecting","so","see","a","pattern","next."
3709 ,"I","am","expecting","the","final","result","to","be","something"
3710 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
3713 "I can get confused by indentation in cases like this, so the problem\
3714 \ may be that the next part is not indented enough?"
3719toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
3720toPListReport source context list startRow startCol =
3722 PListOpen row col ->
3723 case Code.whatIsNext source row col of
3724 Code.Keyword keyword ->
3726 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3727 region = toKeywordRegion row col keyword
3729 Report.Report "RESERVED WORD" region [] $
3730 Code.toSnippet source surroundings (Just region)
3733 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
3736 "This is a reserved word though! Try using some other name?"
3741 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3742 region = toRegion row col
3744 Report.Report "UNFINISHED LIST PATTERN" region [] $
3745 Code.toSnippet source surroundings (Just region) $
3748 "I just saw an open square bracket, but then I got stuck here:"
3750 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3755 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3756 region = toRegion row col
3758 Report.Report "UNFINISHED LIST PATTERN" region [] $
3759 Code.toSnippet source surroundings (Just region) $
3762 "I was expecting a closing square bracket to end this list pattern:"
3764 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3767 PListExpr pattern row col ->
3768 toPatternReport source context pattern row col
3770 PListSpace space row col ->
3771 toSpaceReport source space row col
3773 PListIndentOpen row col ->
3775 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3776 region = toRegion row col
3778 Report.Report "UNFINISHED LIST PATTERN" region [] $
3779 Code.toSnippet source surroundings (Just region) $
3782 "I just saw an open square bracket, but then I got stuck here:"
3785 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3787 "I can get confused by indentation in cases like this, so\
3788 \ maybe there is something next, but it is not indented enough?"
3792 PListIndentEnd row col ->
3794 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3795 region = toRegion row col
3797 Report.Report "UNFINISHED LIST PATTERN" region [] $
3798 Code.toSnippet source surroundings (Just region) $
3801 "I was expecting a closing square bracket to end this list pattern:"
3804 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3806 "I can get confused by indentation in cases like this, so\
3807 \ maybe you have a closing square bracket but it is not indented enough?"
3811 PListIndentExpr row col ->
3813 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3814 region = toRegion row col
3816 Report.Report "UNFINISHED LIST PATTERN" region [] $
3817 Code.toSnippet source surroundings (Just region) $
3820 "I am partway through parsing a list pattern, but I got stuck here:"
3824 "I was expecting to see another pattern next. Maybe a variable name."
3826 "I can get confused by indentation in cases like this, so\
3827 \ maybe there is more to this pattern but it is not indented enough?"
3836-- TODO add context? say something special if you are in type annotation vs custom type vs type alias?
3838toTypeReport :: Code.Source -> Type -> Row -> Col -> Report.Report
3839toTypeReport source tipe startRow startCol =
3841 TRecord record row col ->
3842 toTRecordReport source record row col
3844 TTuple tuple row col ->
3845 toTTupleReport source tuple row col
3848 error "TODO TArrow" row col
3851 error "TODO TStart" row col startRow startCol
3853 TSpace space row col ->
3854 toSpaceReport source space row col
3856 TIndentStart row col ->
3857 error "TODO TIndentStart" row col
3861toTRecordReport :: Code.Source -> TRecord -> Row -> Col -> Report.Report
3862toTRecordReport source record startRow startCol =
3864 TRecordOpen row col ->
3865 case Code.whatIsNext source row col of
3866 Code.Keyword keyword ->
3868 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3869 region = toKeywordRegion row col keyword
3871 Report.Report "RESERVED WORD" region [] $
3872 Code.toSnippet source surroundings (Just region)
3875 "I just started parsing a record type, but I got stuck on this field name:"
3878 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3879 \ that is a reserved word. Try using a different name!"
3884 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3885 region = toRegion row col
3887 Report.Report "UNFINISHED RECORD TYPE" region [] $
3888 Code.toSnippet source surroundings (Just region)
3891 "I just started parsing a record type, but I got stuck here:"
3894 ["Record","types","look","like",D.dullyellow "{ name : String, age : Int },"
3895 ,"so","I","was","expecting","to","see","a","field","name","next."
3899 TRecordEnd row col ->
3901 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3902 region = toRegion row col
3904 Report.Report "UNFINISHED RECORD TYPE" region [] $
3905 Code.toSnippet source surroundings (Just region)
3908 "I am partway through parsing a record type, but I got stuck here:"
3912 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
3913 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
3916 "When I get stuck like this, it usually means that there is a missing parenthesis\
3917 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3921 TRecordField row col ->
3922 case Code.whatIsNext source row col of
3923 Code.Keyword keyword ->
3925 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3926 region = toKeywordRegion row col keyword
3928 Report.Report "RESERVED WORD" region [] $
3929 Code.toSnippet source surroundings (Just region)
3932 "I am partway through parsing a record type, but I got stuck on this field name:"
3935 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3936 \ that is a reserved word. Try using a different name!"
3941 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3942 region = toRegion row col
3944 Report.Report "UNFINISHED RECORD TYPE" region [] $
3945 Code.toSnippet source surroundings (Just region)
3948 "I am partway through parsing a record type, but I got stuck after that last comma:"
3950 addNoteForRecordTypeError $
3952 "Trailing commas are not allowed in records, so I was expecting to see another\
3953 \ record field defined next. If you are done defining the record, the fix may\
3954 \ be to delete that last comma?"
3957 TRecordColon row col ->
3959 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3960 region = toRegion row col
3962 Report.Report "UNFINISHED RECORD TYPE" region [] $
3963 Code.toSnippet source surroundings (Just region)
3966 "I am partway through parsing a record type, but I got stuck here:"
3968 addNoteForRecordTypeError $
3970 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
3971 ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
3975 TRecordType tipe row col ->
3976 toTypeReport source tipe row col
3978 TRecordSpace space row col ->
3979 toSpaceReport source space row col
3981 TRecordIndentOpen row col ->
3983 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3984 region = toRegion row col
3986 Report.Report "UNFINISHED RECORD TYPE" region [] $
3987 Code.toSnippet source surroundings (Just region)
3990 "I just saw the opening curly brace of a record type, but then I got stuck here:"
3992 addNoteForRecordTypeIndentError $
3994 ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
3995 ,"Try","defining","some","fields","of","your","own?"
3999 TRecordIndentEnd row col ->
4001 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4002 region = toRegion row col
4004 Report.Report "UNFINISHED RECORD TYPE" region [] $
4005 Code.toSnippet source surroundings (Just region)
4008 "I was expecting to see a closing curly brace next:"
4010 addNoteForRecordTypeIndentError $
4012 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
4016 TRecordIndentField row col ->
4018 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4019 region = toRegion row col
4021 Report.Report "UNFINISHED RECORD TYPE" region [] $
4022 Code.toSnippet source surroundings (Just region)
4025 "I am partway through parsing a record type, but I got stuck after that last comma:"
4027 addNoteForRecordTypeIndentError $
4029 "Trailing commas are not allowed in record types, so the fix may be to\
4030 \ delete that last comma? Or maybe you were in the middle of defining\
4031 \ an additional field?"
4034 TRecordIndentColon row col ->
4036 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4037 region = toRegion row col
4039 Report.Report "UNFINISHED RECORD TYPE" region [] $
4040 Code.toSnippet source surroundings (Just region)
4043 "I am partway through parsing a record type. I just saw a record\
4044 \ field, so I was expecting to see a colon next:"
4046 addNoteForRecordTypeIndentError $
4048 ["Try","putting","an",D.green ":","followed","by","a","type?"
4052 TRecordIndentType row col ->
4054 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4055 region = toRegion row col
4057 Report.Report "UNFINISHED RECORD TYPE" region [] $
4058 Code.toSnippet source surroundings (Just region)
4061 "I am partway through parsing a record type, and I was expecting to run into a type next:"
4063 addNoteForRecordTypeIndentError $
4065 ["Try","putting","something,","like"
4066 ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
4071addNoteForRecordTypeError :: D.Doc -> D.Doc
4072addNoteForRecordTypeError normalRecommendation =
4074 normalRecommendation
4077 "If you are trying to define a record type across multiple lines, I recommend using this format:"
4078 , D.indent 4 $ D.vcat $
4081 , ", height : Float"
4085 "Notice that each line starts with some indentation. Usually two or four spaces. I\
4086 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
4087 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4091addNoteForRecordTypeIndentError :: D.Doc -> D.Doc
4092addNoteForRecordTypeIndentError normalRecommendation =
4094 normalRecommendation
4097 "I may be confused by indentation. For example, if you are trying to define\
4098 \ a record type across multiple lines, I recommend using this format:"
4099 , D.indent 4 $ D.vcat $
4102 , ", height : Float"
4106 "Notice that each line starts with some indentation. Usually two or four spaces. I\
4107 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
4108 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4112toTTupleReport :: Code.Source -> TTuple -> Row -> Col -> Report.Report
4113toTTupleReport source tuple startRow startCol =
4115 TTupleOpen row col ->
4116 case Code.whatIsNext source row col of
4117 Code.Keyword keyword ->
4119 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4120 region = toKeywordRegion row col keyword
4122 Report.Report "RESERVED WORD" region [] $
4123 Code.toSnippet source surroundings (Just region)
4126 "I ran into a reserved word unexpectedly:"
4129 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but \
4130 \ it is a reserved word. Try using a different name!"
4135 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4136 region = toRegion row col
4138 Report.Report "UNFINISHED PARENTHESES" region [] $
4139 Code.toSnippet source surroundings (Just region)
4142 "I just saw an open parenthesis, so I was expecting to see a type next."
4145 ["Something","like",D.dullyellow "(Maybe Int)","or"
4146 ,D.dullyellow "(List Person)" <> "."
4147 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
4151 TTupleEnd row col ->
4153 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4154 region = toRegion row col
4156 Report.Report "UNFINISHED PARENTHESES" region [] $
4157 Code.toSnippet source surroundings (Just region)
4160 "I was expecting to see a closing parentheses next, but I got stuck here:"
4163 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
4165 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
4166 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
4167 \ or missing brackets) that is confusing me."
4171 TTupleType tipe row col ->
4172 toTypeReport source tipe row col
4174 TTupleSpace space row col ->
4175 toSpaceReport source space row col
4177 TTupleIndentType1 row col ->
4179 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4180 region = toRegion row col
4182 Report.Report "UNFINISHED PARENTHESES" region [] $
4183 Code.toSnippet source surroundings (Just region)
4186 "I just saw an open parenthesis, so I was expecting to see a type next."
4190 ["Something","like",D.dullyellow "(Maybe Int)","or"
4191 ,D.dullyellow "(List Person)" <> "."
4192 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
4195 "I can get confused by indentation in cases like this, so\
4196 \ maybe you have a type but it is not indented enough?"
4200 TTupleIndentTypeN row col ->
4202 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4203 region = toRegion row col
4205 Report.Report "UNFINISHED TUPLE TYPE" region [] $
4206 Code.toSnippet source surroundings (Just region)
4209 "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."
4213 ["A","tuple","type","looks","like",D.dullyellow "(Float,Float)","or"
4214 ,D.dullyellow "(String,Int)" <> ","
4215 ,"so","I","think","there","is","a","type","missing","here?"
4218 "I can get confused by indentation in cases like this, so\
4219 \ maybe you have an expression but it is not indented enough?"
4223 TTupleIndentEnd row col ->
4225 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4226 region = toRegion row col
4228 Report.Report "UNFINISHED PARENTHESES" region [] $
4229 Code.toSnippet source surroundings (Just region)
4232 "I was expecting to see a closing parenthesis next:"
4235 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4237 "I can get confused by indentation in cases like this, so\
4238 \ 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