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 ->
587 region = toRegion row col
589 Report.Report "EXPECTING END OF FILE" region [] $
590 Code.toSnippet source region Nothing
593 "I was not expecting to see anything more here:"
596 "I think I have read all the declarations in the file and that there is nothing\
597 \ left to see, so whatever I am running into is confusing me a lot!"
600 ModuleProblem row col ->
602 region = toRegion row col
604 Report.Report "UNFINISHED MODULE DECLARATION" region [] $
605 Code.toSnippet source region Nothing
608 "I am parsing an `module` declaration, but I got stuck here:"
612 "Here are some examples of valid `module` declarations:"
613 , D.indent 4 $ D.vcat $
614 [ D.fillSep [D.cyan "module","Main",D.cyan "exposing","(..)"]
615 , D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(Dict, empty, get)"]
618 "I generally recommend using an explicit exposing list. I can skip compiling a bunch\
619 \ of files when the public interface of a module stays the same, so exposing fewer\
620 \ values can help improve compile times!"
624 ModuleName row col ->
626 region = toRegion row col
628 Report.Report "EXPECTING MODULE NAME" region [] $
629 Code.toSnippet source region Nothing
632 "I was parsing an `module` declaration until I got stuck here:"
636 "I was expecting to see the module name next, like in these examples:"
637 , D.indent 4 $ D.vcat $
638 [ D.fillSep [D.cyan "module","Dict",D.cyan "exposing","(..)"]
639 , D.fillSep [D.cyan "module","Maybe",D.cyan "exposing","(..)"]
640 , D.fillSep [D.cyan "module","Html.Attributes",D.cyan "exposing","(..)"]
641 , D.fillSep [D.cyan "module","Json.Decode",D.cyan "exposing","(..)"]
644 "Notice that the module names all start with capital letters. That is required!"
648 ModuleExposing exposing row col ->
649 error "TODO ModuleExposing" exposing row col
651 PortModuleProblem row col ->
653 region = toRegion row col
655 Report.Report "UNFINISHED PORT MODULE DECLARATION" region [] $
656 Code.toSnippet source region Nothing
659 "I am parsing an `port module` declaration, but I got stuck here:"
663 "Here are some examples of valid `port module` declarations:"
664 , D.indent 4 $ D.vcat $
665 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
666 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
668 , D.link "Note" "Read" "ports" "for more help."
672 PortModuleName row col ->
674 region = toRegion row col
676 Report.Report "EXPECTING MODULE NAME" region [] $
677 Code.toSnippet source region Nothing
680 "I was parsing an `module` declaration until I got stuck here:"
684 "I was expecting to see the module name next, like in these examples:"
685 , D.indent 4 $ D.vcat $
686 [ D.fillSep [D.cyan "port",D.cyan "module","WebSockets",D.cyan "exposing","(send, listen, keepAlive)"]
687 , D.fillSep [D.cyan "port",D.cyan "module","Maps",D.cyan "exposing","(Location, goto)"]
690 "Notice that the module names start with capital letters. That is required!"
694 PortModuleExposing exposing row col ->
695 error "TODO PortModuleExposing" exposing row col
699 region = toRegion row col
701 Report.Report "BAD MODULE DECLARATION" region [] $
702 Code.toSnippet source region Nothing
705 "I cannot parse this module declaration:"
708 "This type of module is reserved for the @elm organization. It is used to\
709 \ define certain effects, avoiding building them into the compiler."
714 region = toRegion row col
716 toBadFirstLineReport keyword =
717 Report.Report "TOO MUCH INDENTATION" region [] $
718 Code.toSnippet source region Nothing
721 "This `" ++ keyword ++ "` should not have any spaces before it:"
724 "Delete the spaces before `" ++ keyword ++ "` until there are none left!"
728 case Code.whatIsNext source row col of
729 Code.Keyword "module" -> toBadFirstLineReport "module"
730 Code.Keyword "import" -> toBadFirstLineReport "import"
731 Code.Keyword "type" -> toBadFirstLineReport "type"
732 Code.Keyword "port" -> toBadFirstLineReport "port"
734 Report.Report "SYNTAX PROBLEM" region [] $
735 Code.toSnippet source region Nothing
742 "I am not sure what is going on, but I recommend starting an Elm\
743 \ file with the following lines:"
745 [ D.fillSep [D.cyan "import","Html"]
747 , D.fillSep [D.green "main","="]
748 , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
751 "You should be able to copy those lines directly into your file. Check out\
752 \ some of the examples on https://elm-lang.org for more help getting started!"
754 "This can also happen when something is indented too much!"
758 ImportStart row col ->
759 toImportReport source row col
761 ImportName row col ->
763 region = toRegion row col
765 Report.Report "EXPECTING IMPORT NAME" region [] $
766 Code.toSnippet source region Nothing
769 "I was parsing an `import` until I got stuck here:"
773 "I was expecting to see a module name next, like in these examples:"
774 , D.indent 4 $ D.vcat $
775 [ D.fillSep [D.cyan "import","Dict"]
776 , D.fillSep [D.cyan "import","Maybe"]
777 , D.fillSep [D.cyan "import","Html.Attributes"]
778 , D.fillSep [D.cyan "import","Json.Decode"]
781 "Notice that the module names all start with capital letters. That is required!"
786 toImportReport source row col
788 ImportAlias row col ->
790 region = toRegion row col
792 Report.Report "EXECTING IMPORT ALIAS" region [] $
793 Code.toSnippet source region Nothing
796 "I was parsing an `import` until I got stuck here:"
800 "I was expecting to see an alias next, like in these examples:"
801 , D.indent 4 $ D.vcat $
802 [ D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","Attr"]
803 , D.fillSep [D.cyan "import","WebGL.Texture",D.cyan "as","Texture"]
804 , D.fillSep [D.cyan "import","Json.Decode",D.cyan "as","D"]
807 "Notice that the alias always starts with a capital letter. That is required!"
811 ImportExposing row col ->
812 toImportReport source row col
814 ImportExposingList exposing row col ->
815 error "TODO ImportExposingList" exposing row col
818 toImportReport source row col
820 ImportIndentName row col ->
821 toImportReport source row col
823 ImportIndentAlias row col ->
824 toImportReport source row col
826 ImportIndentExposingList row col ->
828 region = toRegion row col
830 Report.Report "UNFINISHED IMPORT" region [] $
831 Code.toSnippet source region Nothing
834 "I was parsing an `import` until I got stuck here:"
838 "I was expecting to see the list of exposed values next. For example, here\
839 \ are two ways to expose values from the `Html` module:"
840 , D.indent 4 $ D.vcat $
841 [ D.fillSep [D.cyan "import","Html",D.cyan "exposing","(..)"]
842 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
845 "I generally recommend the second style. It is more explicit, making it\
846 \ much easier to figure out where values are coming from in large projects!"
852 region = toRegion row col
854 Report.Report "BAD INFIX" region [] $
855 Code.toSnippet source region Nothing
858 "Something went wrong in this infix operator declaration:"
861 "This feature is used by the @elm organization to define the\
862 \ languages built-in operators."
865 Declarations decl _ _ ->
866 toDeclarationsReport source decl
873toImportReport :: Code.Source -> Row -> Col -> Report.Report
874toImportReport source row col =
876 region = toRegion row col
878 Report.Report "UNFINISHED IMPORT" region [] $
879 Code.toSnippet source region Nothing
882 "I am partway through parsing an import, but I got stuck here:"
886 "Here are some examples of valid `import` declarations:"
887 , D.indent 4 $ D.vcat $
888 [ D.fillSep [D.cyan "import","Html"]
889 , D.fillSep [D.cyan "import","Html",D.cyan "as","H"]
890 , D.fillSep [D.cyan "import","Html",D.cyan "as","H",D.cyan "exposing","(..)"]
891 , D.fillSep [D.cyan "import","Html",D.cyan "exposing","(Html, div, text)"]
894 "You are probably trying to import a different module, but try to make it look like one of these examples!"
903toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
904toSpaceReport source space row col =
908 region = toRegion row col
910 Report.Report "NO TABS" region [] $
911 Code.toSnippet source region Nothing
914 "I ran into a tab, but tabs are not allowed in Elm files."
917 "Replace the tab with spaces."
920 EndlessMultiComment ->
922 region = toWiderRegion row col 2
924 Report.Report "ENDLESS COMMENT" region [] $
925 Code.toSnippet source region Nothing
928 "I cannot find the end of this multi-line comment:"
931 [ D.reflow "Add a -} somewhere after this to end the comment."
933 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
934 \ that happens to contain another comment. Like parentheses and curly braces,\
935 \ the start and end markers must always be balanced. Maybe that is the problem?"
944toRegion :: Row -> Col -> A.Region
947 pos = A.Position row col
952toWiderRegion :: Row -> Col -> Word16 -> A.Region
953toWiderRegion row col extra =
956 (A.Position row (col + extra))
959toKeywordRegion :: Row -> Col -> [Char.Char] -> A.Region
960toKeywordRegion row col keyword =
963 (A.Position row (col + fromIntegral (length keyword)))
966toDeclarationsReport :: Code.Source -> Decl -> Report.Report
967toDeclarationsReport source decl =
970 error "TODO DeclStart" row col
972 DeclSpace space row col ->
973 toSpaceReport source space row col
975 Port port_ row col ->
976 error "TODO Port" port_ row col
978 DeclType declType row col ->
979 toDeclTypeReport source declType row col
981 DeclDef name declDef row col ->
982 toDeclDefReport source name declDef row col
984 DeclFreshLineStart row col ->
985 error "TODO DeclFreshLineStart" row col
987 DeclFreshLineAfterDocComment row col ->
988 error "TODO DeclFreshLineAfterDocComment" row col
995toDeclTypeReport :: Code.Source -> DeclType -> Row -> Col -> Report.Report
996toDeclTypeReport source declType startRow startCol =
998 DT_Space space row col ->
999 toSpaceReport source space row col
1003 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1004 region = toRegion row col
1006 Report.Report "EXPECTING TYPE NAME" region [] $
1007 Code.toSnippet source surroundings (Just region)
1010 "I think I am parsing a type declaration, but I got stuck here:"
1014 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1015 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1021 DT_Alias typeAlias row col ->
1022 toTypeAliasReport source typeAlias row col
1024 DT_Union customType row col ->
1025 toCustomTypeReport source customType row col
1027 DT_IndentName row col ->
1029 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1030 region = toRegion row col
1032 Report.Report "EXPECTING TYPE NAME" region [] $
1033 Code.toSnippet source surroundings (Just region)
1036 "I think I am parsing a type declaration, but I got stuck here:"
1040 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1041 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1048toTypeAliasReport :: Code.Source -> TypeAlias -> Row -> Col -> Report.Report
1049toTypeAliasReport source typeAlias startRow startCol =
1051 AliasSpace space row col ->
1052 toSpaceReport source space row col
1054 AliasName row col ->
1056 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1057 region = toRegion row col
1059 Report.Report "EXPECTING TYPE ALIAS NAME" region [] $
1060 Code.toSnippet source surroundings (Just region)
1063 "I think I am parsing a type alias, but I got stuck here:"
1067 ["I","was","expecting","a","name","like",D.dullyellow "Person","or",D.dullyellow "Point"
1068 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1074 AliasEquals row col ->
1075 error "TODO AliasEquals" row col
1077 AliasBody tipe row col ->
1078 toTypeReport source tipe row col
1080 AliasIndentEquals row col ->
1081 error "TODO AliasIndentEquals" row col
1083 AliasIndentBody row col ->
1085 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1086 region = toRegion row col
1088 Report.Report "UNFINISHED TYPE ALIAS" region [] $
1089 Code.toSnippet source surroundings (Just region)
1092 "I am partway through parsing a type alias, but I got stuck here:"
1096 ["I","was","expecting","to","see","a","type","next.","Something","as","simple"
1097 ,"as",D.dullyellow "Int","or",D.dullyellow "Float","would","work!"
1104typeAliasNote :: D.Doc
1108 "Here is an example of a valid `type alias` for reference:"
1110 [ D.indent 0 $ D.fillSep [D.cyan "type",D.cyan "alias",D.green "Person","="]
1111 , D.indent 2 $ D.vcat $
1119 "This would let us use `Person` as a shorthand for that record type. Using this\
1120 \ shorthand makes type annotations much easier to read, and makes changing code\
1121 \ easier if you decide later that there is more to a person than age and height!"
1125toCustomTypeReport :: Code.Source -> CustomType -> Row -> Col -> Report.Report
1126toCustomTypeReport source customType startRow startCol =
1128 CT_Space space row col ->
1129 toSpaceReport source space row col
1133 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1134 region = toRegion row col
1136 Report.Report "EXPECTING TYPE NAME" region [] $
1137 Code.toSnippet source surroundings (Just region)
1140 "I think I am parsing a type declaration, but I got stuck here:"
1144 ["I","was","expecting","a","name","like",D.dullyellow "Status","or",D.dullyellow "Style"
1145 ,"next.","Just","make","sure","it","is","a","name","that","starts","with","a","capital","letter!"
1151 CT_Equals row col ->
1152 error "TODO CT_Equals" row col
1155 error "TODO CT_Bar" row col
1157 CT_Variant row col ->
1158 error "TODO CT_Variant" row col
1160 CT_VariantArg tipe row col ->
1161 toTypeReport source tipe row col
1163 CT_IndentEquals row col ->
1164 error "TODO CT_IndentEquals" row col
1166 CT_IndentBar row col ->
1167 error "TODO CT_IndentBar" row col
1169 CT_IndentAfterBar row col ->
1170 error "TODO CT_IndentAfterBar" row col
1172 CT_IndentAfterEquals row col ->
1173 error "TODO CT_IndentAfterEquals" row col
1176customTypeNote :: D.Doc
1180 "Here is an example of a valid `type` declaration for reference:"
1182 [ D.indent 0 $ D.fillSep [D.cyan "type",D.green "Status"]
1183 , D.indent 2 $ D.fillSep ["=","Failure"]
1184 , D.indent 2 $ D.fillSep ["|","Waiting"]
1185 , D.indent 2 $ D.fillSep ["|","Success","String"]
1188 "This defines a new `Status` type with three variants. This could be useful if\
1189 \ we are waiting for an HTTP request. Maybe we start with `Waiting` and then\
1190 \ switch to `Failure` or `Success \"message from server\"` depending on how\
1191 \ things go. Notice that the Success variant has some associated data, allowing\
1192 \ us to store a String if the request goes well!"
1200toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
1201toDeclDefReport source name declDef startRow startCol =
1203 DeclDefSpace space row col ->
1204 toSpaceReport source space row col
1206 DeclDefEquals row col ->
1207 case Code.whatIsNext source row col of
1208 Code.Keyword keyword ->
1210 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1211 region = toKeywordRegion row col keyword
1213 Report.Report "RESERVED WORD" region [] $
1214 Code.toSnippet source surroundings (Just region)
1217 "It looks like you are trying to use `" ++ keyword ++ "` as an argument:"
1220 "This is a reserved word! Try using some other name?"
1225 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1226 region = toKeywordRegion row col op
1228 Report.Report "UNEXPECTED SYMBOL" region [] $
1229 Code.toSnippet source surroundings (Just region)
1232 "I was not expecting to see this symbol here:"
1236 "I am not sure what is going wrong exactly, so here is a valid\
1237 \ definition (with an optional type annotation) for reference:"
1239 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1240 , D.fillSep [D.green "add","x","y","="]
1241 , D.fillSep [" ","x","+","y"]
1244 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
1250 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1251 region = toRegion row col
1253 Report.Report "PROBLEM IN DEFINITION" region [] $
1254 Code.toSnippet source surroundings (Just region)
1257 "I got stuck while parsing the `" ++ Name.toChars name ++ "` definition:"
1261 "I am not sure what is going wrong exactly, so here is a valid\
1262 \ definition (with an optional type annotation) for reference:"
1264 [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1265 , D.fillSep [D.green "add","x","y","="]
1266 , D.fillSep [" ","x","+","y"]
1269 "Try to use that format!"
1273 DeclDefType tipe row col ->
1274 toTypeReport source tipe row col
1276 DeclDefArg pattern row col ->
1277 toPatternReport source PArg pattern row col
1279 DeclDefBody expr row col ->
1280 toExprReport source (InDef name startRow startCol) expr row col
1282 DeclDefNameRepeat row col ->
1284 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1285 region = toRegion row col
1287 Report.Report "EXPECTING DEFINITION" region [] $
1288 Code.toSnippet source surroundings (Just region)
1291 "I just saw the type annotation for `" ++ Name.toChars name
1292 ++ "` so I was expecting to see its definition here:"
1295 "Type annotations always appear directly above the relevant\
1296 \ definition, without anything else (even doc comments) in between."
1299 DeclDefNameMatch defName row col ->
1301 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1302 region = toRegion row col
1304 Report.Report "NAME MISMATCH" region [] $
1305 Code.toSnippet source surroundings (Just region)
1308 "I just saw a type annotation for `" ++ Name.toChars name ++ "`, but it is followed by a definition for `" ++ Name.toChars defName ++ "`:"
1312 "These names do not match! Is there a typo?"
1313 , D.indent 4 $ D.fillSep $
1314 [D.dullyellow (D.fromName defName),"->",D.green (D.fromName name)]
1318 DeclDefIndentType row col ->
1319 error "TODO DeclDefIndentType" row col
1321 DeclDefIndentEquals row col ->
1322 error "TODO DeclDefIndentEquals" row col
1324 DeclDefIndentBody row col ->
1325 error "TODO DeclDefIndentBody" row col
1327 DeclDefFreshLineAfterType row col ->
1328 error "TODO DeclDefFreshLineAfterType" row col
1336 = InNode Node Row Col Context
1337 | InDef Name.Name Row Col
1353getDefName :: Context -> Name.Name
1356 InDef name _ _ -> name
1357 InNode _ _ _ c -> getDefName c
1360isWithin :: Node -> Context -> Bool
1361isWithin desiredNode context =
1363 InDef _ _ _ -> False
1364 InNode actualNode _ _ _ -> desiredNode == actualNode
1371toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
1372toExprReport source context expr startRow startCol =
1375 toLetReport source context let_ row col
1377 Case case_ row col ->
1378 toCaseReport source context case_ row col
1381 toIfReport source context if_ row col
1383 List list row col ->
1384 toListReport source context list row col
1386 Record record row col ->
1387 toRecordReport source context record row col
1389 Tuple tuple row col ->
1390 toTupleReport source context tuple row col
1392 Func func row col ->
1393 toFuncReport source context func row col
1396 let region = toRegion row col in
1397 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
1398 Code.toSnippet source region Nothing
1401 "I was expecting to see a record accessor here:"
1404 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
1405 ,"that","accesses","a","value","from","a","record."
1410 let region = toRegion row col in
1411 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
1412 Code.toSnippet source region Nothing
1415 "I am trying to parse a record accessor here:"
1420 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
1421 ,"that","accesses","a","value","from","a","record."
1425 "Record field names must start with a lower case letter!"
1429 OperatorRight op row col ->
1430 let region = toRegion row col in
1431 Report.Report "MISSING EXPRESSION" region [] $
1432 Code.toSnippet source region Nothing
1435 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1439 ["You","can","just","put","anything","for","now,","like"
1440 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1441 ,"Once","there","is","something","there,","I","can","probably"
1442 ,"give","a","more","specific","hint!"
1445 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
1446 \ Or if I run into operators in unexpected spots. Point is, there are a\
1447 \ couple ways I can get confused and give sort of weird advice!"
1451 OperatorReserved operator row col ->
1452 toOperatorReport source context operator row col
1456 (contextRow, contextCol, aThing) =
1458 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
1459 InNode NRecord r c _ -> (r, c, "a record")
1460 InNode NParens r c _ -> (r, c, "some parentheses")
1461 InNode NList r c _ -> (r, c, "a list")
1462 InNode NFunc r c _ -> (r, c, "an anonymous function")
1463 InNode NCond r c _ -> (r, c, "an `if` expression")
1464 InNode NThen r c _ -> (r, c, "an `if` expression")
1465 InNode NElse r c _ -> (r, c, "an `if` expression")
1466 InNode NCase r c _ -> (r, c, "a `case` expression")
1467 InNode NBranch r c _ -> (r, c, "a `case` expression")
1468 -- TODO check if this is actually the best way to get error messages here
1470 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
1471 region = toRegion row col
1473 Report.Report "MISSING EXPRESSION" region [] $
1474 Code.toSnippet source surroundings (Just region)
1477 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
1481 ["I","was","expecting","to","see","an","expression","like"
1482 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1483 ,"Once","there","is","something","there,","I","can","probably"
1484 ,"give","a","more","specific","hint!"
1487 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
1488 \ Or if I run into operators in unexpected spots. Point is, there are a\
1489 \ couple ways I can get confused and give sort of weird advice!"
1493 Char char row col ->
1494 toCharReport source char row col
1496 String string row col ->
1497 toStringReport source string row col
1499 Number number row col ->
1500 toNumberReport source number row col
1502 Space space row col ->
1503 toSpaceReport source space row col
1505 EndlessShader row col ->
1507 region = toWiderRegion row col 6
1509 Report.Report "ENDLESS SHADER" region [] $
1510 Code.toSnippet source region Nothing
1512 D.reflow "I cannot find the end of this shader:"
1514 D.reflow "Add a |] somewhere after this to end the shader."
1517 ShaderProblem problem row col ->
1519 region = toRegion row col
1521 Report.Report "SHADER PROBLEM" region [] $
1522 Code.toSnippet source region Nothing
1525 "I ran into a problem while parsing this GLSL block."
1529 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
1530 , D.indent 4 $ D.vcat $
1531 map D.fromChars (filter (/="") (lines problem))
1535 IndentOperatorRight op row col ->
1537 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1538 region = toRegion row col
1540 Report.Report "MISSING EXPRESSION" region [] $
1541 Code.toSnippet source surroundings (Just region)
1544 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1549 ["You","can","just","put","anything","for","now,","like"
1550 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1551 ,"Once","there","is","something","there,","I","can","probably"
1552 ,"give","a","more","specific","hint!"
1556 "I may be getting confused by your indentation? The easiest way to make sure\
1557 \ this is not an indentation problem is to put the expression on the right of\
1558 \ the " ++ Name.toChars op ++ " operator on the same line."
1562 IndentMoreExpr _ _ ->
1563 error "TODO IndentMoreExpr"
1570toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
1571toCharReport source char row col =
1575 region = toRegion row col
1577 Report.Report "MISSING SINGLE QUOTE" region [] $
1578 Code.toSnippet source region Nothing
1581 "I thought I was parsing a character, but I got to the end of\
1582 \ the line without seeing the closing single quote:"
1585 "Add a closing single quote here!"
1588 CharEscape escape ->
1589 toEscapeReport source escape row col
1591 CharNotString width ->
1593 region = toWiderRegion row col width
1595 Report.Report "NEEDS DOUBLE QUOTES" region [] $
1596 Code.toSnippet source region Nothing
1598 "The following string uses single quotes:"
1601 [ "Please switch to double quotes instead:"
1603 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
1605 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
1606 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
1607 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
1608 \ individual characters."
1617toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
1618toStringReport source string row col =
1620 StringEndless_Single ->
1622 region = toRegion row col
1624 Report.Report "ENDLESS STRING" region [] $
1625 Code.toSnippet source region Nothing
1628 "I got to the end of the line without seeing the closing double quote:"
1632 ["Strings","look","like",D.green "\"this\"","with","double"
1633 ,"quotes","on","each","end.","Is","the","closing","double"
1634 ,"quote","missing","in","your","code?"
1636 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
1640 StringEndless_Multi ->
1642 region = toWiderRegion row col 3
1644 Report.Report "ENDLESS STRING" region [] $
1645 Code.toSnippet source region Nothing
1648 "I cannot find the end of this multi-line string:"
1651 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
1652 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
1656 StringEscape escape ->
1657 toEscapeReport source escape row col
1664toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1665toEscapeReport source escape row col =
1669 region = toWiderRegion row col 2
1671 Report.Report "UNKNOWN ESCAPE" region [] $
1672 Code.toSnippet source region Nothing
1675 "Backslashes always start escaped characters, but I do not recognize this one:"
1679 "Valid escape characters include:"
1680 , D.dullyellow $ D.indent 4 $ D.vcat $
1690 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1692 "The last style lets encode ANY character by its Unicode code\
1693 \ point. That means \\u{0009} and \\t are the same. You can use\
1694 \ that style for anything not covered by the other six escapes!"
1698 BadUnicodeFormat width ->
1700 region = toWiderRegion row col width
1702 Report.Report "BAD UNICODE ESCAPE" region [] $
1703 Code.toSnippet source region Nothing
1706 "I ran into an invalid Unicode escape:"
1710 "Here are some examples of valid Unicode escapes:"
1711 , D.dullyellow $ D.indent 4 $ D.vcat $
1718 "Notice that the code point is always surrounded by curly braces.\
1719 \ Maybe you are missing the opening or closing curly brace?"
1722 BadUnicodeCode width ->
1724 region = toWiderRegion row col width
1726 Report.Report "BAD UNICODE ESCAPE" region [] $
1727 Code.toSnippet source region Nothing
1730 "This is not a valid code point:"
1733 "The valid code points are between 0 and 10FFFF inclusive."
1736 BadUnicodeLength width numDigits badCode ->
1738 region = toWiderRegion row col width
1740 Report.Report "BAD UNICODE ESCAPE" region [] $
1741 Code.toSnippet source region Nothing $
1742 if numDigits < 4 then
1745 "Every code point needs at least four digits:"
1748 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1749 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1751 D.fillSep ["Try",D.green suggestion,"instead?"]
1757 "This code point has too many digits:"
1760 ["Valid","code","points","are","between"
1761 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1762 ,"so","try","trimming","any","leading","zeros","until"
1763 ,"you","have","between","four","and","six","digits."
1772toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1773toNumberReport source number row col =
1775 region = toRegion row col
1779 Report.Report "WEIRD NUMBER" region [] $
1780 Code.toSnippet source region Nothing
1783 "I thought I was reading a number, but I ran into some weird stuff here:"
1787 "I recognize numbers in the following formats:"
1788 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1790 "So is there a way to write it like one of those?"
1795 Report.Report "WEIRD NUMBER" region [] $
1796 Code.toSnippet source region Nothing
1799 "Numbers cannot end with a dot like this:"
1802 ["Switching","to",D.green (D.fromChars (show int))
1803 ,"or",D.green (D.fromChars (show int ++ ".0"))
1804 ,"will","work","though!"
1809 Report.Report "WEIRD HEXIDECIMAL" region [] $
1810 Code.toSnippet source region Nothing
1813 "I thought I was reading a hexidecimal number until I got here:"
1817 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1818 \ only recognize things like this:"
1819 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1823 NumberNoLeadingZero ->
1824 Report.Report "LEADING ZEROS" region [] $
1825 Code.toSnippet source region Nothing
1828 "I do not accept numbers with leading zeros:"
1832 "Just delete the leading zeros and it should work!"
1834 "Some languages let you to specify octal numbers by adding a leading zero.\
1835 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1836 \ that, but others probably want it to equal 111. Either path is going to\
1837 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1847toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
1848toOperatorReport source context operator row col =
1852 region = toRegion row col
1854 Report.Report "UNEXPECTED SYMBOL" region [] $
1855 Code.toSnippet source region Nothing
1857 "I was not expecting this dot:"
1860 "Dots are for record access and decimal points, so\
1861 \ they cannot float around on their own. Maybe\
1862 \ there is some extra whitespace?"
1867 region = toRegion row col
1869 Report.Report "UNEXPECTED SYMBOL" region [] $
1870 Code.toSnippet source region Nothing
1873 "I was not expecting this vertical bar:"
1876 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
1881 region = toWiderRegion row col 2
1883 Report.Report "UNEXPECTED ARROW" region [] $
1884 Code.toSnippet source region Nothing $
1885 if isWithin NBranch context then
1888 "I was not expecting to see an arrow here:"
1893 "I think I am parsing a `case` expression right now, so it makes sense to\
1894 \ see arrows around here. This one is confusing me though!"
1897 "I may be getting confused by the indentation. Every pattern in a `case` must be\
1898 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
1899 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
1900 \ indented too far?"
1907 "I was not expecting an arrow here:"
1910 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
1911 \ you want > or >= instead?"
1916 region = toRegion row col
1917 name = getDefName context
1919 Report.Report "UNEXPECTED EQUALS" region [] $
1920 Code.toSnippet source region Nothing
1923 "I was not expecting to see this equals sign:"
1927 D.reflow "Maybe you want == instead? To check if two values are equal?"
1930 if isWithin NRecord context then
1931 "Records look like { x = 3, y = 4 } with the equals sign right\
1932 \ after the field name. So maybe you forgot a comma?"
1934 "I may be getting confused by your indentation. Is this supposed to be part of\
1935 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1936 \ the problem may be a bit before the equals sign. I need all definitions to\
1937 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1938 \ this new definition is indented a bit too much."
1944 region = toRegion row col
1945 name = getDefName context
1947 Report.Report "UNEXPECTED SYMBOL" region [] $
1948 Code.toSnippet source region Nothing $
1951 "I was not expecting to run into the \"has type\" symbol here:"
1956 ["Maybe","you","want",D.green "::","instead?"
1957 ,"To","put","something","on","the","front","of","a","list?"
1960 "The single colon is reserved for type annotations and record types, but I think\
1961 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
1964 "I may be getting confused by your indentation. Is this supposed to be part of\
1965 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1966 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
1967 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1968 \ this new definition is indented a bit too much."
1977toLetReport :: Code.Source -> Context -> Let -> Row -> Col -> Report.Report
1978toLetReport source context let_ startRow startCol =
1980 LetSpace space row col ->
1981 toSpaceReport source space row col
1985 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1986 region = toRegion row col
1988 Report.Report "LET PROBLEM" region [] $
1989 Code.toSnippet source surroundings (Just region)
1992 "I was partway through parsing a `let` expression, but I got stuck here:"
1996 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
1997 ,"keyword","next.","Is","there","a","typo?"
2000 "This can also happen if you are trying to define another value within the `let` but\
2001 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2002 \ spaces before it. They should line up exactly!"
2006 LetDefAlignment _ row col ->
2008 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2009 region = toRegion row col
2011 Report.Report "LET PROBLEM" region [] $
2012 Code.toSnippet source surroundings (Just region)
2015 "I was partway through parsing a `let` expression, but I got stuck here:"
2019 ["Based","on","the","indentation,","I","was","expecting","to","see","the",D.cyan "in"
2020 ,"keyword","next.","Is","there","a","typo?"
2023 "This can also happen if you are trying to define another value within the `let` but\
2024 \ it is not indented enough. Make sure each definition has exactly the same amount of\
2025 \ spaces before it. The should line up exactly!"
2029 LetDefName row col ->
2030 case Code.whatIsNext source row col of
2031 Code.Keyword keyword ->
2033 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2034 region = toKeywordRegion row col keyword
2036 Report.Report "RESERVED WORD" region [] $
2037 Code.toSnippet source surroundings (Just region)
2040 "I was partway through parsing a `let` expression, but I got stuck here:"
2043 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but\
2044 \ it is a reserved word! Try using a different name instead."
2048 toUnfinishLetReport source row col startRow startCol $
2050 "I was expecting the name of a definition next."
2052 LetDef name def row col ->
2053 error "TODO LetDef" name def row col
2055 LetDestruct destruct row col ->
2056 error "TODO LetDestruct" destruct row col
2058 LetBody expr row col ->
2059 toExprReport source context expr row col
2061 LetIndentDef row col ->
2062 toUnfinishLetReport source row col startRow startCol $
2064 "I was expecting a value to be defined here."
2066 LetIndentIn row col ->
2067 toUnfinishLetReport source row col startRow startCol $
2069 ["I","was","expecting","to","see","the",D.cyan "in","keyword","next."
2070 ,"Or","maybe","more","of","that","expression?"
2073 LetIndentBody row col ->
2074 toUnfinishLetReport source row col startRow startCol $
2076 "I was expecting an expression next. Tell me what should happen with the value you just defined!"
2079toUnfinishLetReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
2080toUnfinishLetReport source row col startRow startCol message =
2082 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2083 region = toRegion row col
2085 Report.Report "UNFINISHED LET" region [] $
2086 Code.toSnippet source surroundings (Just region)
2089 "I was partway through parsing a `let` expression, but I got stuck here:"
2094 "Here is an example with a valid `let` expression for reference:"
2096 [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
2097 , D.indent 2 $ D.fillSep [D.cyan "let"]
2098 , D.indent 4 $ D.fillSep ["fullName","="]
2099 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
2100 , D.indent 2 $ D.fillSep [D.cyan "in"]
2101 , D.indent 2 $ D.fillSep ["div","[]","[","text","fullName","]"]
2104 "Here we defined a `viewPerson` function that turns a person into some HTML. We use\
2105 \ a `let` expression to define the `fullName` we want to show. Notice the indentation! The\
2106 \ `fullName` is indented more than the `let` keyword, and the actual value of `fullName` is\
2107 \ indented a bit more than that. That is important!"
2116toCaseReport :: Code.Source -> Context -> Case -> Row -> Col -> Report.Report
2117toCaseReport source context case_ startRow startCol =
2119 CaseSpace space row col ->
2120 toSpaceReport source space row col
2123 toUnfinishCaseReport source row col startRow startCol $
2124 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
2126 CasePattern pattern row col ->
2127 toPatternReport source PCase pattern row col
2129 CaseArrow row col ->
2130 case Code.whatIsNext source row col of
2131 Code.Keyword keyword ->
2133 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2134 region = toKeywordRegion row col keyword
2136 Report.Report "RESERVED WORD" region [] $
2137 Code.toSnippet source surroundings (Just region)
2140 "I am partway through parsing a `case` expression, but I got stuck here:"
2143 "It looks like you are trying to use `" ++ keyword ++ "` in one of your\
2144 \ patterns, but it is a reserved word. Try using a different name?"
2147 Code.Operator ":" ->
2149 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2150 region = toRegion row col
2152 Report.Report "UNEXPECTED OPERATOR" region [] $
2153 Code.toSnippet source surroundings (Just region)
2156 "I am partway through parsing a `case` expression, but I got stuck here:"
2159 ["I","am","seeing",D.dullyellow ":","but","maybe","you","want",D.green "::","instead?"
2160 ,"For","pattern","matching","on","lists?"
2164 Code.Operator "=" ->
2166 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2167 region = toRegion row col
2169 Report.Report "UNEXPECTED OPERATOR" region [] $
2170 Code.toSnippet source surroundings (Just region)
2173 "I am partway through parsing a `case` expression, but I got stuck here:"
2176 ["I","am","seeing",D.dullyellow "=","but","maybe","you","want",D.green "->","instead?"
2182 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2183 region = toRegion row col
2185 Report.Report "MISSING ARROW" region [] $
2186 Code.toSnippet source surroundings (Just region)
2189 "I am partway through parsing a `case` expression, but I got stuck here:"
2191 addNoteForCaseIndentError $
2193 "I was expecting to see an arrow next."
2196 CaseExpr expr row col ->
2197 toExprReport source (InNode NCase startRow startCol context) expr row col
2199 CaseBranch expr row col ->
2200 toExprReport source (InNode NBranch startRow startCol context) expr row col
2202 CaseIndentOf row col ->
2203 toUnfinishCaseReport source row col startRow startCol $
2204 D.fillSep ["I","was","expecting","to","see","the",D.dullyellow "of","keyword","next."]
2206 CaseIndentExpr row col ->
2207 toUnfinishCaseReport source row col startRow startCol $
2208 D.reflow "I was expecting to see a expression next."
2210 CaseIndentPattern row col ->
2211 toUnfinishCaseReport source row col startRow startCol $
2212 D.reflow "I was expecting to see a pattern next."
2214 CaseIndentArrow row col ->
2215 toUnfinishCaseReport source row col startRow startCol $
2217 ["I","just","saw","a","pattern,","so","I","was","expecting"
2218 ,"to","see","a",D.dullyellow "->","next."
2221 CaseIndentBranch row col ->
2222 toUnfinishCaseReport source row col startRow startCol $
2224 "I was expecting to see an expression next. What should I do when\
2225 \ I run into this particular pattern?"
2227 CasePatternAlignment indent row col ->
2228 toUnfinishCaseReport source row col startRow startCol $
2230 "I suspect this is a pattern that is not indented far enough? (" ++ show indent ++ " spaces)"
2233toUnfinishCaseReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
2234toUnfinishCaseReport source row col startRow startCol message =
2236 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2237 region = toRegion row col
2239 Report.Report "UNFINISHED CASE" region [] $
2240 Code.toSnippet source surroundings (Just region)
2243 "I was partway through parsing a `case` expression, but I got stuck here:"
2248 "Here is an example of a valid `case` expression for reference."
2250 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2251 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2252 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
2254 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2255 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
2258 "Notice the indentation. Each pattern is aligned, and each branch is indented\
2259 \ a bit more than the corresponding pattern. That is important!"
2264addNoteForCaseIndentError :: D.Doc -> D.Doc
2265addNoteForCaseIndentError message =
2270 "Sometimes I get confused by indentation, so try to make your `case` look\
2271 \ something like this:"
2273 [ D.indent 4 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
2274 , D.indent 6 $ D.fillSep [D.green "Just","width","->"]
2275 , D.indent 8 $ D.fillSep ["width","+",D.dullyellow "200"]
2277 , D.indent 6 $ D.fillSep [D.green "Nothing","->"]
2278 , D.indent 8 $ D.fillSep [D.dullyellow "400"]
2281 "Notice the indentation! Each pattern is aligned, and each branch is indented\
2282 \ a bit more than the corresponding pattern. That is important!"
2290toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
2291toIfReport source context if_ startRow startCol =
2293 IfSpace space row col ->
2294 toSpaceReport source space row col
2298 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2299 region = toRegion row col
2301 Report.Report "UNFINISHED IF" region [] $
2302 Code.toSnippet source surroundings (Just region)
2305 "I was expecting to see more of this `if` expression, but I got stuck here:"
2308 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
2314 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2315 region = toRegion row col
2317 Report.Report "UNFINISHED IF" region [] $
2318 Code.toSnippet source surroundings (Just region)
2321 "I was expecting to see more of this `if` expression, but I got stuck here:"
2324 ["I","was","expecting","to","see","the",D.cyan "else","keyword","next."
2328 IfElseBranchStart row col ->
2330 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2331 region = toRegion row col
2333 Report.Report "UNFINISHED IF" region [] $
2334 Code.toSnippet source surroundings (Just region)
2337 "I just saw the start of an `else` branch, but then I got stuck here:"
2340 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2343 IfCondition expr row col ->
2344 toExprReport source (InNode NCond startRow startCol context) expr row col
2346 IfThenBranch expr row col ->
2347 toExprReport source (InNode NThen startRow startCol context) expr row col
2349 IfElseBranch expr row col ->
2350 toExprReport source (InNode NElse startRow startCol context) expr row col
2352 IfIndentCondition row col ->
2354 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2355 region = toRegion row col
2357 Report.Report "UNFINISHED IF" region [] $
2358 Code.toSnippet source surroundings (Just region)
2361 "I was expecting to see more of this `if` expression, but I got stuck here:"
2365 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
2366 ,"that","evaluates","to","True","or","False."
2369 "I can be confused by indentation. Maybe something is not indented enough?"
2373 IfIndentThen row col ->
2375 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2376 region = toRegion row col
2378 Report.Report "UNFINISHED IF" region [] $
2379 Code.toSnippet source surroundings (Just region)
2382 "I was expecting to see more of this `if` expression, but I got stuck here:"
2386 ["I","was","expecting","to","see","the",D.cyan "then","keyword","next."
2389 "I can be confused by indentation. Maybe something is not indented enough?"
2393 IfIndentThenBranch row col ->
2395 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2396 region = toRegion row col
2398 Report.Report "UNFINISHED IF" region [] $
2399 Code.toSnippet source surroundings (Just region)
2402 "I got stuck after the start of this `then` branch:"
2406 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2408 "I can be confused by indentation, so if the `then` branch is already\
2409 \ present, it may not be indented enough for me to recognize it."
2413 IfIndentElseBranch row col ->
2415 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2416 region = toRegion row col
2418 Report.Report "UNFINISHED IF" region [] $
2419 Code.toSnippet source surroundings (Just region)
2422 "I got stuck after the start of this `else` branch:"
2426 "I was expecting to see an expression next. Maybe it is not filled in yet?"
2428 "I can be confused by indentation, so if the `else` branch is already\
2429 \ present, it may not be indented enough for me to recognize it."
2433 IfIndentElse row col ->
2435 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2436 region = toRegion row col
2438 Report.Report "UNFINISHED IF" region [] $
2439 Code.toSnippet source surroundings (Just region)
2442 "I was expecting to see an `else` branch after this:"
2446 "I know what to do when the condition is `True`, but not when it is `False`."
2448 ["Add","an",D.cyan "else","branch","to","handle","that","scenario!"]
2457toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
2458toRecordReport source context record startRow startCol =
2460 RecordOpen row col ->
2461 case Code.whatIsNext source row col of
2462 Code.Keyword keyword ->
2464 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2465 region = toKeywordRegion row col keyword
2467 Report.Report "RESERVED WORD" region [] $
2468 Code.toSnippet source surroundings (Just region)
2471 "I just started parsing a record, but I got stuck on this field name:"
2474 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
2475 \ that is a reserved word. Try using a different name!"
2480 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2481 region = toRegion row col
2483 Report.Report "UNFINISHED RECORD" region [] $
2484 Code.toSnippet source surroundings (Just region)
2487 "I just started parsing a record, but I got stuck here:"
2490 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
2491 ,"so","I","was","expecting","to","see","a","field","name","next."
2495 RecordEnd row col ->
2497 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2498 region = toRegion row col
2500 Report.Report "UNFINISHED RECORD" region [] $
2501 Code.toSnippet source surroundings (Just region)
2504 "I am partway through parsing a record, but I got stuck here:"
2508 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
2509 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
2512 "When I get stuck like this, it usually means that there is a missing parenthesis\
2513 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2517 RecordField row col ->
2518 case Code.whatIsNext source row col of
2519 Code.Keyword keyword ->
2521 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2522 region = toKeywordRegion row col keyword
2524 Report.Report "RESERVED WORD" region [] $
2525 Code.toSnippet source surroundings (Just region)
2528 "I am partway through parsing a record, but I got stuck on this field name:"
2531 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
2532 \ that is a reserved word. Try using a different name!"
2537 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2538 region = toRegion row col
2540 Report.Report "UNFINISHED RECORD" region [] $
2541 Code.toSnippet source surroundings (Just region)
2544 "I am partway through parsing a record, but I got stuck after that last comma:"
2546 addNoteForRecordError $
2548 "Trailing commas are not allowed in records, so I was expecting to see another\
2549 \ record field defined next. If you are done defining the record, the fix may\
2550 \ be to delete that last comma?"
2553 RecordEquals row col ->
2555 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2556 region = toRegion row col
2558 Report.Report "UNFINISHED RECORD" region [] $
2559 Code.toSnippet source surroundings (Just region)
2562 "I am partway through parsing a record, but I got stuck here:"
2564 addNoteForRecordError $
2566 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
2567 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
2571 RecordExpr expr row col ->
2572 toExprReport source (InNode NRecord startRow startCol context) expr row col
2574 RecordSpace space row col ->
2575 toSpaceReport source space row col
2577 RecordIndentOpen row col ->
2579 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2580 region = toRegion row col
2582 Report.Report "UNFINISHED RECORD" region [] $
2583 Code.toSnippet source surroundings (Just region)
2586 "I just saw the opening curly brace of a record, but then I got stuck here:"
2588 addNoteForRecordIndentError $
2590 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
2591 ,"Try","defining","some","fields","of","your","own?"
2595 RecordIndentEnd row col ->
2597 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2598 region = toRegion row col
2600 Report.Report "UNFINISHED RECORD" region [] $
2601 Code.toSnippet source surroundings (Just region)
2604 "I was expecting to see a closing curly brace next:"
2606 addNoteForRecordIndentError $
2608 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
2612 RecordIndentField row col ->
2614 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2615 region = toRegion row col
2617 Report.Report "UNFINISHED RECORD" region [] $
2618 Code.toSnippet source surroundings (Just region)
2621 "I am partway through parsing a record, but I got stuck after that last comma:"
2623 addNoteForRecordError $
2625 "Trailing commas are not allowed in records, so the fix may be to\
2626 \ delete that last comma? Or maybe you were in the middle of defining\
2627 \ an additional field?"
2630 RecordIndentEquals row col ->
2632 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2633 region = toRegion row col
2635 Report.Report "UNFINISHED RECORD" region [] $
2636 Code.toSnippet source surroundings (Just region)
2639 "I am partway through parsing a record. I just saw a record\
2640 \ field, so I was expecting to see an equals sign next:"
2642 addNoteForRecordIndentError $
2644 ["Try","putting","an",D.green "=","followed","by","an","expression?"
2648 RecordIndentExpr row col ->
2650 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2651 region = toRegion row col
2653 Report.Report "UNFINISHED RECORD" region [] $
2654 Code.toSnippet source surroundings (Just region)
2657 "I am partway through parsing a record, and I was expecting to run into an expression next:"
2659 addNoteForRecordIndentError $
2661 ["Try","putting","something,","like"
2662 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
2667addNoteForRecordError :: D.Doc -> D.Doc
2668addNoteForRecordError normalRecommendation =
2670 normalRecommendation
2673 "If you are trying to define a record across multiple lines, I recommend using this format:"
2674 , D.indent 4 $ D.vcat $
2675 [ "{ name = \"Alice\""
2681 "Notice that each line starts with some indentation. Usually two or four spaces. I\
2682 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
2683 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2687addNoteForRecordIndentError :: D.Doc -> D.Doc
2688addNoteForRecordIndentError normalRecommendation =
2690 normalRecommendation
2693 "I may be confused by indentation. For example, if you are trying to define\
2694 \ a record across multiple lines, I recommend using this format:"
2695 , D.indent 4 $ D.vcat $
2696 [ "{ name = \"Alice\""
2702 "Notice that each line starts with some indentation. Usually two or four spaces. I\
2703 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
2704 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2712toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
2713toTupleReport source context tuple startRow startCol =
2715 TupleExpr expr row col ->
2716 toExprReport source (InNode NParens startRow startCol context) expr row col
2718 TupleSpace space row col ->
2719 toSpaceReport source space row col
2723 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2724 region = toRegion row col
2726 Report.Report "UNFINISHED PARENTHESES" region [] $
2727 Code.toSnippet source surroundings (Just region)
2730 "I was expecting to see a closing parentheses next, but I got stuck here:"
2733 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
2735 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
2736 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
2737 \ or missing brackets) that is confusing me."
2741 TupleOperatorClose row col ->
2743 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2744 region = toRegion row col
2746 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
2747 Code.toSnippet source surroundings (Just region)
2749 D.reflow "I was expecting a closing parenthesis here:"
2752 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
2754 "I think I am parsing an operator function right now, so I am expecting to see\
2755 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
2760 TupleOperatorReserved operator row col ->
2762 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2763 region = toRegion row col
2765 Report.Report "UNEXPECTED SYMBOL" region [] $
2766 Code.toSnippet source surroundings (Just region)
2769 "I ran into an unexpected symbol here:"
2773 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
2774 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
2775 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
2776 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
2777 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
2780 TupleIndentExpr1 row col ->
2782 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2783 region = toRegion row col
2785 Report.Report "UNFINISHED PARENTHESES" region [] $
2786 Code.toSnippet source surroundings (Just region)
2789 "I just saw an open parenthesis, so I was expecting to see an expression next."
2793 ["Something","like",D.dullyellow "(4 + 5)","or"
2794 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
2795 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
2798 "I can get confused by indentation in cases like this, so\
2799 \ maybe you have an expression but it is not indented enough?"
2803 TupleIndentExprN row col ->
2805 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2806 region = toRegion row col
2808 Report.Report "UNFINISHED TUPLE" region [] $
2809 Code.toSnippet source surroundings (Just region)
2812 "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."
2816 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
2817 ,D.dullyellow "(\"Tom\",42)" <> ","
2818 ,"so","I","think","there","is","an","expression","missing","here?"
2821 "I can get confused by indentation in cases like this, so\
2822 \ maybe you have an expression but it is not indented enough?"
2826 TupleIndentEnd row col ->
2828 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2829 region = toRegion row col
2831 Report.Report "UNFINISHED PARENTHESES" region [] $
2832 Code.toSnippet source surroundings (Just region)
2835 "I was expecting to see a closing parenthesis next:"
2838 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
2840 "I can get confused by indentation in cases like this, so\
2841 \ maybe you have a closing parenthesis but it is not indented enough?"
2846toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
2847toListReport source context list startRow startCol =
2849 ListSpace space row col ->
2850 toSpaceReport source space row col
2854 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2855 region = toRegion row col
2857 Report.Report "UNFINISHED LIST" region [] $
2858 Code.toSnippet source surroundings (Just region)
2861 "I am partway through parsing a list, but I got stuck here:"
2865 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2866 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2869 "When I get stuck like this, it usually means that there is a missing parenthesis\
2870 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2874 ListExpr expr row col ->
2878 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
2879 region = toRegion r c
2881 Report.Report "UNFINISHED LIST" region [] $
2882 Code.toSnippet source surroundings (Just region)
2885 "I was expecting to see another list entry after that last comma:"
2889 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2891 "I recommend using the following format for lists that span multiple lines:"
2892 , D.indent 4 $ D.vcat $
2899 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2900 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2901 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2906 toExprReport source (InNode NList startRow startCol context) expr row col
2910 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2911 region = toRegion row col
2913 Report.Report "UNFINISHED LIST" region [] $
2914 Code.toSnippet source surroundings (Just region)
2917 "I am partway through parsing a list, but I got stuck here:"
2921 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2922 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2925 "When I get stuck like this, it usually means that there is a missing parenthesis\
2926 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2930 ListIndentOpen row col ->
2932 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2933 region = toRegion row col
2935 Report.Report "UNFINISHED LIST" region [] $
2936 Code.toSnippet source surroundings (Just region)
2939 "I cannot find the end of this list:"
2943 ["You","could","change","it","to","something","like"
2944 ,D.dullyellow "[3,4,5]"
2946 ,D.dullyellow "[]" <> "."
2947 ,"Anything","where","there","is","an","open","and","close","square","brace,"
2948 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
2951 "I may be confused by indentation. For example, if you are trying to define\
2952 \ a list across multiple lines, I recommend using this format:"
2953 , D.indent 4 $ D.vcat $
2960 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2961 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2962 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2966 ListIndentEnd row col ->
2968 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2969 region = toRegion row col
2971 Report.Report "UNFINISHED LIST" region [] $
2972 Code.toSnippet source surroundings (Just region)
2975 "I cannot find the end of this list:"
2979 ["You","can","just","add","a","closing",D.dullyellow "]"
2980 ,"right","here,","and","I","will","be","all","set!"
2983 "I may be confused by indentation. For example, if you are trying to define\
2984 \ a list across multiple lines, I recommend using this format:"
2985 , D.indent 4 $ D.vcat $
2992 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2993 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2994 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2998 ListIndentExpr row col ->
3000 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3001 region = toRegion row col
3003 Report.Report "UNFINISHED LIST" region [] $
3004 Code.toSnippet source surroundings (Just region)
3007 "I was expecting to see another list entry after this comma:"
3011 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
3013 "I recommend using the following format for lists that span multiple lines:"
3014 , D.indent 4 $ D.vcat $
3021 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
3022 \ This style can be jarring for people coming from C-like syntax, but folks generally\
3023 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3028toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
3029toFuncReport source context func startRow startCol =
3031 FuncSpace space row col ->
3032 toSpaceReport source space row col
3034 FuncArg pattern row col ->
3035 toPatternReport source PArg pattern row col
3037 FuncBody expr row col ->
3038 toExprReport source (InNode NFunc startRow startCol context) expr row col
3040 FuncArrow row col ->
3041 case Code.whatIsNext source row col of
3042 Code.Keyword keyword ->
3044 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3045 region = toKeywordRegion row col keyword
3047 Report.Report "RESERVED WORD" region [] $
3048 Code.toSnippet source surroundings (Just region)
3051 "I was parsing an anonymous function, but I got stuck here:"
3054 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
3055 \ it is a reserved word in this language. Try using a different argument name!"
3060 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3061 region = toRegion row col
3063 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
3064 Code.toSnippet source surroundings (Just region)
3067 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
3070 ["The","syntax","for","anonymous","functions","is"
3071 ,D.dullyellow "(\\x -> x + 1)"
3072 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
3076 FuncIndentArg row col ->
3078 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3079 region = toRegion row col
3081 Report.Report "MISSING ARGUMENT" region [] $
3082 Code.toSnippet source surroundings (Just region)
3085 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
3089 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
3090 ,"Anything","that","starts","with","a","lower","case","letter!"
3093 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
3094 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
3095 \ like a better idea at the time!"
3099 FuncIndentArrow row col ->
3101 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3102 region = toRegion row col
3104 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
3105 Code.toSnippet source surroundings (Just region)
3108 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
3112 ["The","syntax","for","anonymous","functions","is"
3113 ,D.dullyellow "(\\x -> x + 1)"
3114 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
3117 "It is possible that I am confused about indetation! I generally recommend\
3118 \ switching to named functions if the definition cannot fit inline nicely, so\
3119 \ either (1) try to fit the whole anonymous function on one line or (2) break\
3120 \ the whole thing out into a named function. Things tend to be clearer that way!"
3124 FuncIndentBody row col ->
3126 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3127 region = toRegion row col
3129 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
3130 Code.toSnippet source surroundings (Just region)
3133 "I was expecting to see the body of your anonymous function next:"
3137 ["The","syntax","for","anonymous","functions","is"
3138 ,D.dullyellow "(\\x -> x + 1)"
3139 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
3142 "It is possible that I am confused about indetation! I generally recommend\
3143 \ switching to named functions if the definition cannot fit inline nicely, so\
3144 \ either (1) try to fit the whole anonymous function on one line or (2) break\
3145 \ the whole thing out into a named function. Things tend to be clearer that way!"
3159toPatternReport :: Code.Source -> PContext -> Pattern -> Row -> Col -> Report.Report
3160toPatternReport source context pattern startRow startCol =
3162 PRecord record row col ->
3163 toPRecordReport source record row col
3165 PTuple tuple row col ->
3166 toPTupleReport source context tuple row col
3168 PList list row col ->
3169 toPListReport source context list row col
3172 case Code.whatIsNext source row col of
3173 Code.Keyword keyword ->
3175 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3176 region = toKeywordRegion row col keyword
3179 PArg -> "an argument"
3180 PCase -> "a pattern"
3182 Report.Report "RESERVED WORD" region [] $
3183 Code.toSnippet source surroundings (Just region)
3186 "It looks like you are trying to use `" ++ keyword ++ "` as " ++ aThing ++ ":"
3189 "This is a reserved word! Try using some other name?"
3195 PChar char row col ->
3196 toCharReport source char row col
3198 PString string row col ->
3199 toStringReport source string row col
3201 PNumber number row col ->
3202 toNumberReport source number row col
3204 PFloat width row col ->
3206 region = toWiderRegion row col width
3208 Report.Report "UNEXPECTED PATTERN" region [] $
3209 Code.toSnippet source region Nothing
3212 "I cannot pattern match with floating point numbers:"
3215 ["Equality","on","floats","can","be","unreliable,","so","you","usually","want"
3216 ,"to","check","that","they","are","nearby","with","some","sort","of"
3217 ,D.dullyellow "(abs (actual - expected) < 0.001)","check."
3223 region = toRegion row col
3225 Report.Report "UNFINISHED PATTERN" region [] $
3226 Code.toSnippet source region Nothing $
3229 "I was expecting to see a variable name after the `as` keyword:"
3233 ["The","`as`","keyword","lets","you","write","patterns","like"
3234 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
3235 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
3236 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
3237 ,"thing","with",D.dullyellow "point."
3240 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
3241 \ people just want to use `as` as a variable name though. Try using a different name\
3246 PWildcardNotVar name width row col ->
3248 region = toWiderRegion row col (fromIntegral width)
3250 case dropWhile (=='_') (Name.toChars name) of
3251 [] -> [D.dullyellow "x","or",D.dullyellow "age"]
3252 c:cs -> [D.dullyellow (D.fromChars (Char.toLower c : cs))]
3254 Report.Report "UNEXPECTED NAME" region [] $
3255 Code.toSnippet source region Nothing $
3258 "Variable names cannot start with underscores like this:"
3261 ["You","can","either","have","an","underscore","like",D.dullyellow "_","to"
3262 ,"ignore","the","value,","or","you","can","have","a","name","like"
3263 ] ++ examples ++ ["to","use","the","matched","value." ]
3266 PSpace space row col ->
3267 toSpaceReport source space row col
3269 PIndentStart row col ->
3270 error "TODO PIndentStart" row col
3272 PIndentAlias row col ->
3274 region = toRegion row col
3276 Report.Report "UNFINISHED PATTERN" region [] $
3277 Code.toSnippet source region Nothing $
3280 "I was expecting to see a variable name after the `as` keyword:"
3284 ["The","`as`","keyword","lets","you","write","patterns","like"
3285 ,"((" <> D.dullyellow "x" <> "," <> D.dullyellow "y" <> ") " <> D.cyan "as" <> D.dullyellow " point" <> ")"
3286 ,"so","you","can","refer","to","individual","parts","of","the","tuple","with"
3287 ,D.dullyellow "x","and",D.dullyellow "y","or","you","refer","to","the","whole"
3288 ,"thing","with",D.dullyellow "point."
3291 "So I was expecting to see a variable name after the `as` keyword here. Sometimes\
3292 \ people just want to use `as` as a variable name though. Try using a different name\
3298toPRecordReport :: Code.Source -> PRecord -> Row -> Col -> Report.Report
3299toPRecordReport source record startRow startCol =
3301 PRecordOpen row col ->
3302 toUnfinishRecordPatternReport source row col startRow startCol $
3303 D.reflow "I was expecting to see a field name next."
3305 PRecordEnd row col ->
3306 toUnfinishRecordPatternReport source row col startRow startCol $
3308 ["I","was","expecting","to","see","a","closing","curly","brace","next."
3309 ,"Try","adding","a",D.dullyellow "}","here?"
3312 PRecordField row col ->
3313 case Code.whatIsNext source row col of
3314 Code.Keyword keyword ->
3316 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3317 region = toKeywordRegion row col keyword
3319 Report.Report "RESERVED WORD" region [] $
3320 Code.toSnippet source surroundings (Just region)
3323 "I was not expecting to see `" ++ keyword ++ "` as a record field name:"
3326 "This is a reserved word, not available for variable names. Try another name!"
3330 toUnfinishRecordPatternReport source row col startRow startCol $
3331 D.reflow "I was expecting to see a field name next."
3333 PRecordSpace space row col ->
3334 toSpaceReport source space row col
3336 PRecordIndentOpen row col ->
3337 toUnfinishRecordPatternReport source row col startRow startCol $
3338 D.reflow "I was expecting to see a field name next."
3340 PRecordIndentEnd row col ->
3341 toUnfinishRecordPatternReport source row col startRow startCol $
3343 ["I","was","expecting","to","see","a","closing","curly","brace","next."
3344 ,"Try","adding","a",D.dullyellow "}","here?"
3347 PRecordIndentField row col ->
3348 toUnfinishRecordPatternReport source row col startRow startCol $
3349 D.reflow "I was expecting to see a field name next."
3352toUnfinishRecordPatternReport :: Code.Source -> Row -> Col -> Row -> Col -> D.Doc -> Report.Report
3353toUnfinishRecordPatternReport source row col startRow startCol message =
3355 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3356 region = toRegion row col
3358 Report.Report "UNFINISHED RECORD PATTERN" region [] $
3359 Code.toSnippet source surroundings (Just region)
3362 "I was partway through parsing a record pattern, but I got stuck here:"
3367 ["A","record","pattern","looks","like",D.dullyellow "{x,y}","or",D.dullyellow "{name,age}"
3368 ,"where","you","list","the","field","names","you","want","to","access."
3375toPTupleReport :: Code.Source -> PContext -> PTuple -> Row -> Col -> Report.Report
3376toPTupleReport source context tuple startRow startCol =
3378 PTupleOpen row col ->
3379 case Code.whatIsNext source row col of
3380 Code.Keyword keyword ->
3382 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3383 region = toKeywordRegion row col keyword
3385 Report.Report "RESERVED WORD" region [] $
3386 Code.toSnippet source surroundings (Just region)
3389 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name:"
3392 "This is a reserved word! Try using some other name?"
3397 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3398 region = toRegion row col
3400 Report.Report "UNFINISHED PARENTHESES" region [] $
3401 Code.toSnippet source surroundings (Just region)
3404 "I just saw an open parenthesis, but I got stuck here:"
3407 ["I","was","expecting","so","see","a","pattern","next."
3408 ,"Maybe","it","will","end","up","being","something"
3409 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3413 PTupleEnd row col ->
3415 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3416 region = toRegion row col
3418 Report.Report "UNFINISHED PARENTHESES" region [] $
3419 Code.toSnippet source surroundings (Just region) $
3422 "I was expecting a closing parenthesis next:"
3424 D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3427 PTupleExpr pattern row col ->
3428 toPatternReport source context pattern row col
3430 PTupleSpace space row col ->
3431 toSpaceReport source space row col
3433 PTupleIndentEnd row col ->
3435 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3436 region = toRegion row col
3438 Report.Report "UNFINISHED PARENTHESES" region [] $
3439 Code.toSnippet source surroundings (Just region) $
3442 "I was expecting a closing parenthesis next:"
3445 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3447 "I can get confused by indentation in cases like this, so\
3448 \ maybe you have a closing parenthesis but it is not indented enough?"
3452 PTupleIndentExpr1 row col ->
3454 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3455 region = toRegion row col
3457 Report.Report "UNFINISHED PARENTHESES" region [] $
3458 Code.toSnippet source surroundings (Just region) $
3461 "I just saw an open parenthesis, but then I got stuck here:"
3464 ["I","was","expecting","so","see","a","pattern","next."
3465 ,"Maybe","it","will","end","up","being","something"
3466 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "?"
3470 PTupleIndentExprN row col ->
3472 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3473 region = toRegion row col
3475 Report.Report "UNFINISHED TUPLE PATTERN" region [] $
3476 Code.toSnippet source surroundings (Just region) $
3479 "I am partway through parsing a tuple pattern, but I got stuck here:"
3483 ["I","was","expecting","so","see","a","pattern","next."
3484 ,"I","am","expecting","the","final","result","to","be","something"
3485 ,"like",D.dullyellow "(x,y)","or",D.dullyellow "(name, _)" <> "."
3488 "I can get confused by indentation in cases like this, so the problem\
3489 \ may be that the next part is not indented enough?"
3494toPListReport :: Code.Source -> PContext -> PList -> Row -> Col -> Report.Report
3495toPListReport source context list startRow startCol =
3497 PListOpen row col ->
3498 case Code.whatIsNext source row col of
3499 Code.Keyword keyword ->
3501 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3502 region = toKeywordRegion row col keyword
3504 Report.Report "RESERVED WORD" region [] $
3505 Code.toSnippet source surroundings (Just region)
3508 "It looks like you are trying to use `" ++ keyword ++ "` to name an element of a list:"
3511 "This is a reserved word though! Try using some other name?"
3516 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3517 region = toRegion row col
3519 Report.Report "UNFINISHED LIST PATTERN" region [] $
3520 Code.toSnippet source surroundings (Just region) $
3523 "I just saw an open square bracket, but then I got stuck here:"
3525 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3530 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3531 region = toRegion row col
3533 Report.Report "UNFINISHED LIST PATTERN" region [] $
3534 Code.toSnippet source surroundings (Just region) $
3537 "I was expecting a closing square bracket to end this list pattern:"
3539 D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3542 PListExpr pattern row col ->
3543 toPatternReport source context pattern row col
3545 PListSpace space row col ->
3546 toSpaceReport source space row col
3548 PListIndentOpen row col ->
3550 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3551 region = toRegion row col
3553 Report.Report "UNFINISHED LIST PATTERN" region [] $
3554 Code.toSnippet source surroundings (Just region) $
3557 "I just saw an open square bracket, but then I got stuck here:"
3560 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3562 "I can get confused by indentation in cases like this, so\
3563 \ maybe there is something next, but it is not indented enough?"
3567 PListIndentEnd row col ->
3569 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3570 region = toRegion row col
3572 Report.Report "UNFINISHED LIST PATTERN" region [] $
3573 Code.toSnippet source surroundings (Just region) $
3576 "I was expecting a closing square bracket to end this list pattern:"
3579 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
3581 "I can get confused by indentation in cases like this, so\
3582 \ maybe you have a closing square bracket but it is not indented enough?"
3586 PListIndentExpr row col ->
3588 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3589 region = toRegion row col
3591 Report.Report "UNFINISHED LIST PATTERN" region [] $
3592 Code.toSnippet source surroundings (Just region) $
3595 "I am partway through parsing a list pattern, but I got stuck here:"
3599 "I was expecting to see another pattern next. Maybe a variable name."
3601 "I can get confused by indentation in cases like this, so\
3602 \ maybe there is more to this pattern but it is not indented enough?"
3611-- TODO add context? say something special if you are in type annotation vs custom type vs type alias?
3613toTypeReport :: Code.Source -> Type -> Row -> Col -> Report.Report
3614toTypeReport source tipe startRow startCol =
3616 TRecord record row col ->
3617 toTRecordReport source record row col
3619 TTuple tuple row col ->
3620 toTTupleReport source tuple row col
3623 error "TODO TArrow" row col
3626 error "TODO TStart" row col startRow startCol
3628 TSpace space row col ->
3629 toSpaceReport source space row col
3631 TIndentStart row col ->
3632 error "TODO TIndentStart" row col
3636toTRecordReport :: Code.Source -> TRecord -> Row -> Col -> Report.Report
3637toTRecordReport source record startRow startCol =
3639 TRecordOpen row col ->
3640 case Code.whatIsNext source row col of
3641 Code.Keyword keyword ->
3643 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3644 region = toKeywordRegion row col keyword
3646 Report.Report "RESERVED WORD" region [] $
3647 Code.toSnippet source surroundings (Just region)
3650 "I just started parsing a record type, but I got stuck on this field name:"
3653 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3654 \ that is a reserved word. Try using a different name!"
3659 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3660 region = toRegion row col
3662 Report.Report "UNFINISHED RECORD TYPE" region [] $
3663 Code.toSnippet source surroundings (Just region)
3666 "I just started parsing a record type, but I got stuck here:"
3669 ["Record","types","look","like",D.dullyellow "{ name : String, age : Int },"
3670 ,"so","I","was","expecting","to","see","a","field","name","next."
3674 TRecordEnd row col ->
3676 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3677 region = toRegion row col
3679 Report.Report "UNFINISHED RECORD TYPE" region [] $
3680 Code.toSnippet source surroundings (Just region)
3683 "I am partway through parsing a record type, but I got stuck here:"
3687 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
3688 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
3691 "When I get stuck like this, it usually means that there is a missing parenthesis\
3692 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
3696 TRecordField row col ->
3697 case Code.whatIsNext source row col of
3698 Code.Keyword keyword ->
3700 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3701 region = toKeywordRegion row col keyword
3703 Report.Report "RESERVED WORD" region [] $
3704 Code.toSnippet source surroundings (Just region)
3707 "I am partway through parsing a record type, but I got stuck on this field name:"
3710 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
3711 \ that is a reserved word. Try using a different name!"
3716 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3717 region = toRegion row col
3719 Report.Report "UNFINISHED RECORD TYPE" region [] $
3720 Code.toSnippet source surroundings (Just region)
3723 "I am partway through parsing a record type, but I got stuck after that last comma:"
3725 addNoteForRecordTypeError $
3727 "Trailing commas are not allowed in records, so I was expecting to see another\
3728 \ record field defined next. If you are done defining the record, the fix may\
3729 \ be to delete that last comma?"
3732 TRecordColon row col ->
3734 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3735 region = toRegion row col
3737 Report.Report "UNFINISHED RECORD TYPE" region [] $
3738 Code.toSnippet source surroundings (Just region)
3741 "I am partway through parsing a record type, but I got stuck here:"
3743 addNoteForRecordTypeError $
3745 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
3746 ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
3750 TRecordType tipe row col ->
3751 toTypeReport source tipe row col
3753 TRecordSpace space row col ->
3754 toSpaceReport source space row col
3756 TRecordIndentOpen row col ->
3758 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3759 region = toRegion row col
3761 Report.Report "UNFINISHED RECORD TYPE" region [] $
3762 Code.toSnippet source surroundings (Just region)
3765 "I just saw the opening curly brace of a record type, but then I got stuck here:"
3767 addNoteForRecordTypeIndentError $
3769 ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
3770 ,"Try","defining","some","fields","of","your","own?"
3774 TRecordIndentEnd row col ->
3776 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3777 region = toRegion row col
3779 Report.Report "UNFINISHED RECORD TYPE" region [] $
3780 Code.toSnippet source surroundings (Just region)
3783 "I was expecting to see a closing curly brace next:"
3785 addNoteForRecordTypeIndentError $
3787 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
3791 TRecordIndentField row col ->
3793 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3794 region = toRegion row col
3796 Report.Report "UNFINISHED RECORD TYPE" region [] $
3797 Code.toSnippet source surroundings (Just region)
3800 "I am partway through parsing a record type, but I got stuck after that last comma:"
3802 addNoteForRecordTypeIndentError $
3804 "Trailing commas are not allowed in record types, so the fix may be to\
3805 \ delete that last comma? Or maybe you were in the middle of defining\
3806 \ an additional field?"
3809 TRecordIndentColon row col ->
3811 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3812 region = toRegion row col
3814 Report.Report "UNFINISHED RECORD TYPE" region [] $
3815 Code.toSnippet source surroundings (Just region)
3818 "I am partway through parsing a record type. I just saw a record\
3819 \ field, so I was expecting to see a colon next:"
3821 addNoteForRecordTypeIndentError $
3823 ["Try","putting","an",D.green ":","followed","by","a","type?"
3827 TRecordIndentType row col ->
3829 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3830 region = toRegion row col
3832 Report.Report "UNFINISHED RECORD TYPE" region [] $
3833 Code.toSnippet source surroundings (Just region)
3836 "I am partway through parsing a record type, and I was expecting to run into a type next:"
3838 addNoteForRecordTypeIndentError $
3840 ["Try","putting","something,","like"
3841 ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
3846addNoteForRecordTypeError :: D.Doc -> D.Doc
3847addNoteForRecordTypeError normalRecommendation =
3849 normalRecommendation
3852 "If you are trying to define a record type across multiple lines, I recommend using this format:"
3853 , D.indent 4 $ D.vcat $
3856 , ", height : Float"
3860 "Notice that each line starts with some indentation. Usually two or four spaces. I\
3861 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
3862 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3866addNoteForRecordTypeIndentError :: D.Doc -> D.Doc
3867addNoteForRecordTypeIndentError normalRecommendation =
3869 normalRecommendation
3872 "I may be confused by indentation. For example, if you are trying to define\
3873 \ a record type across multiple lines, I recommend using this format:"
3874 , D.indent 4 $ D.vcat $
3877 , ", height : Float"
3881 "Notice that each line starts with some indentation. Usually two or four spaces. I\
3882 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
3883 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
3887toTTupleReport :: Code.Source -> TTuple -> Row -> Col -> Report.Report
3888toTTupleReport source tuple startRow startCol =
3890 TTupleOpen row col ->
3891 case Code.whatIsNext source row col of
3892 Code.Keyword keyword ->
3894 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3895 region = toKeywordRegion row col keyword
3897 Report.Report "RESERVED WORD" region [] $
3898 Code.toSnippet source surroundings (Just region)
3901 "I ran into a reserved word unexpectedly:"
3904 "It looks like you are trying to use `" ++ keyword ++ "` as a variable name, but \
3905 \ it is a reserved word. Try using a different name!"
3910 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3911 region = toRegion row col
3913 Report.Report "UNFINISHED PARENTHESES" region [] $
3914 Code.toSnippet source surroundings (Just region)
3917 "I just saw an open parenthesis, so I was expecting to see a type next."
3920 ["Something","like",D.dullyellow "(Maybe Int)","or"
3921 ,D.dullyellow "(List Person)" <> "."
3922 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
3926 TTupleEnd row col ->
3928 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3929 region = toRegion row col
3931 Report.Report "UNFINISHED PARENTHESES" region [] $
3932 Code.toSnippet source surroundings (Just region)
3935 "I was expecting to see a closing parentheses next, but I got stuck here:"
3938 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
3940 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
3941 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
3942 \ or missing brackets) that is confusing me."
3946 TTupleType tipe row col ->
3947 toTypeReport source tipe row col
3949 TTupleSpace space row col ->
3950 toSpaceReport source space row col
3952 TTupleIndentType1 row col ->
3954 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3955 region = toRegion row col
3957 Report.Report "UNFINISHED PARENTHESES" region [] $
3958 Code.toSnippet source surroundings (Just region)
3961 "I just saw an open parenthesis, so I was expecting to see a type next."
3965 ["Something","like",D.dullyellow "(Maybe Int)","or"
3966 ,D.dullyellow "(List Person)" <> "."
3967 ,"Anything","where","you","are","putting","parentheses","around","normal","types."
3970 "I can get confused by indentation in cases like this, so\
3971 \ maybe you have a type but it is not indented enough?"
3975 TTupleIndentTypeN row col ->
3977 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3978 region = toRegion row col
3980 Report.Report "UNFINISHED TUPLE TYPE" region [] $
3981 Code.toSnippet source surroundings (Just region)
3984 "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."
3988 ["A","tuple","type","looks","like",D.dullyellow "(Float,Float)","or"
3989 ,D.dullyellow "(String,Int)" <> ","
3990 ,"so","I","think","there","is","a","type","missing","here?"
3993 "I can get confused by indentation in cases like this, so\
3994 \ maybe you have an expression but it is not indented enough?"
3998 TTupleIndentEnd row col ->
4000 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4001 region = toRegion row col
4003 Report.Report "UNFINISHED PARENTHESES" region [] $
4004 Code.toSnippet source surroundings (Just region)
4007 "I was expecting to see a closing parenthesis next:"
4010 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
4012 "I can get confused by indentation in cases like this, so\
4013 \ 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