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
83 | ModuleExposing Row Col
84 | ModuleExposingList Exposing Row Col
86 | ModulePortModule Row Col
87 | ModuleEffect Row Col
89 | ModuleIndentStart Row Col
90 | ModuleIndentName Row Col
91 | ModuleIndentExposing Row Col
92 | ModuleIndentExposingList Row Col
93 | ModuleIndentPortModule Row Col
95 | FreshLineModuleStart Row Col
96 | FreshLineAfterModuleLine Row Col
97 | FreshLineAfterDocComment Row Col
102 | ImportAlias Row Col
103 | ImportExposing Row Col
104 | ImportExposingList Exposing Row Col
105 | ImportEnd Row Col -- different based on col=1 or if greater
107 | ImportIndentName Row Col
108 | ImportIndentAlias Row Col
109 | ImportIndentExposingList Row Col
113 | Declarations Decl Row Col
117 = ExposingSpace Space Row Col
118 | ExposingStart Row Col
119 | ExposingValue Row Col
120 | ExposingOperator Row Col
121 | ExposingOperatorReserved BadOperator Row Col
122 | ExposingOperatorRightParen Row Col
123 | ExposingEnd Row Col
125 | ExposingTypePrivacy Row Col
126 | ExposingTypePrivacyDots Row Col
127 | ExposingTypePrivacyEnd Row Col
129 | ExposingIndentEnd Row Col
130 | ExposingIndentValue Row Col
131 | ExposingIndentValueEnd Row Col
132 | ExposingIndentTypePrivacy Row Col
133 | ExposingIndentTypePrivacyDots Row Col
134 | ExposingIndentTypePrivacyEnd Row Col
143 | DeclSpace Space Row Col
146 | DeclType DeclType Row Col
147 | DeclDef Name.Name DeclDef Row Col
149 | DeclFreshLineStart Row Col
150 | DeclFreshLineAfterDocComment Row Col
154 = DeclDefSpace Space Row Col
155 | DeclDefEquals Row Col
156 | DeclDefType Type Row Col
157 | DeclDefArg Pattern Row Col
158 | DeclDefBody Expr Row Col
159 | DeclDefNameRepeat Row Col
160 | DeclDefNameMatch Name.Name Row Col
162 | DeclDefIndentType Row Col
163 | DeclDefIndentEquals Row Col
164 | DeclDefIndentBody Row Col
166 | DeclDefFreshLineAfterType Row Col
170 = PortSpace Space Row Col
173 | PortType Type Row Col
174 | PortIndentName Row Col
175 | PortIndentColon Row Col
176 | PortIndentType Row Col
184 = DT_Space Space Row Col
186 | DT_Alias TypeAlias Row Col
187 | DT_Union CustomType Row Col
189 | DT_IndentName Row Col
193 = AliasSpace Space Row Col
195 | AliasEquals Row Col
196 | AliasBody Type Row Col
198 | AliasIndentEquals Row Col
199 | AliasIndentBody Row Col
203 = CT_Space Space Row Col
208 | CT_VariantArg Type Row Col
210 | CT_IndentEquals Row Col
211 | CT_IndentBar Row Col
212 | CT_IndentAfterBar Row Col
213 | CT_IndentAfterEquals Row Col
225 | Record Record Row Col
226 | Tuple Tuple Row Col
231 | OperatorRight Name.Name Row Col
232 | OperatorReserved BadOperator Row Col
236 | String String Row Col
237 | Number Number Row Col
238 | Space Space Row Col
239 | EndlessShader Row Col
240 | ShaderProblem [Char.Char] Row Col
241 | IndentOperatorRight Name.Name Row Col
242 | IndentMoreExpr Row Col
248 | RecordField Row Col
249 | RecordEquals Row Col
250 | RecordExpr Expr Row Col
251 | RecordSpace Space Row Col
253 | RecordIndentOpen Row Col
254 | RecordIndentEnd Row Col
255 | RecordIndentField Row Col
256 | RecordIndentEquals Row Col
257 | RecordIndentExpr Row Col
261 = TupleExpr Expr Row Col
262 | TupleSpace Space Row Col
264 | TupleOperatorClose Row Col
265 | TupleOperatorReserved BadOperator Row Col
267 | TupleIndentExpr1 Row Col
268 | TupleIndentExprN Row Col
269 | TupleIndentEnd Row Col
273 = ListSpace Space Row Col
275 | ListExpr Expr Row Col
278 | ListIndentOpen Row Col
279 | ListIndentEnd Row Col
280 | ListIndentExpr Row Col
284 = FuncSpace Space Row Col
285 | FuncArg Pattern Row Col
286 | FuncBody Expr Row Col
289 | FuncIndentArg Row Col
290 | FuncIndentArrow Row Col
291 | FuncIndentBody Row Col
295 = CaseSpace Space Row Col
297 | CasePattern Pattern Row Col
299 | CaseExpr Expr Row Col
300 | CaseBranch Expr Row Col
302 | CaseIndentOf Row Col
303 | CaseIndentExpr Row Col
304 | CaseIndentPattern Row Col
305 | CaseIndentArrow Row Col
306 | CaseIndentBranch Row Col
307 | CasePatternAlignment Word16 Row Col
311 = IfSpace Space Row Col
314 | IfElseBranchStart Row Col
316 | IfCondition Expr Row Col
317 | IfThenBranch Expr Row Col
318 | IfElseBranch Expr Row Col
320 | IfIndentCondition Row Col
321 | IfIndentThen Row Col
322 | IfIndentThenBranch Row Col
323 | IfIndentElseBranch Row Col
324 | IfIndentElse Row Col
328 = LetSpace Space Row Col
330 | LetDefAlignment Word16 Row Col
332 | LetDef Name.Name Def Row Col
333 | LetDestruct Destruct Row Col
334 | LetBody Expr Row Col
335 | LetIndentDef Row Col
336 | LetIndentIn Row Col
337 | LetIndentBody Row Col
341 = DefSpace Space Row Col
342 | DefType Type Row Col
343 | DefNameRepeat Name.Name Row Col
344 | DefNameMatch Name.Name Name.Name Row Col
345 | DefArg Pattern Row Col
347 | DefBody Expr Row Col
348 | DefIndentEquals Row Col
349 | DefIndentType Row Col
350 | DefIndentBody Row Col
351 | DefAlignment Word16 Row Col
355 = DestructSpace Space Row Col
356 | DestructPattern Pattern Row Col
357 | DestructEquals Row Col
358 | DestructBody Expr Row Col
359 | DestructIndentEquals Row Col
360 | DestructIndentBody Row Col
368 = PRecord PRecord Row Col
369 | PTuple PTuple Row Col
370 | PList PList Row Col
374 | PString String Row Col
375 | PNumber Number Row Col
378 | PWildcardNotVar Int Row Col
379 | PSpace Space Row Col
381 | PIndentStart Row Col
382 | PIndentAlias Row Col
386 = PRecordOpen Row Col
388 | PRecordField Row Col
389 | PRecordSpace Space Row Col
391 | PRecordIndentOpen Row Col
392 | PRecordIndentEnd Row Col
393 | PRecordIndentField Row Col
399 | PTupleExpr Pattern Row Col
400 | PTupleSpace Space Row Col
402 | PTupleIndentOpen Row Col
403 | PTupleIndentEnd Row Col
404 | PTupleIndentExpr Row Col
410 | PListExpr Pattern Row Col
411 | PListSpace Space Row Col
413 | PListIndentOpen Row Col
414 | PListIndentEnd Row Col
415 | PListIndentExpr Row Col
423 = TRecord TRecord Row Col
424 | TTuple TTuple Row Col
429 | TSpace Space Row Col
431 | TIndentStart Row Col
435 = TRecordOpen Row Col
438 | TRecordField Row Col
439 | TRecordColon Row Col
440 | TRecordType Type Row Col
442 | TRecordSpace Space Row Col
444 | TRecordIndentOpen Row Col
445 | TRecordIndentField Row Col
446 | TRecordIndentColon Row Col
447 | TRecordIndentType Row Col
448 | TRecordIndentEnd Row Col
454 | TTupleType Type Row Col
455 | TTupleSpace Space Row Col
457 | TTupleIndentOpen Row Col
458 | TTupleIndentType Row Col
459 | TTupleIndentEnd Row Col
469 | CharNotString Word16
473 = StringEndless_Single
474 | StringEndless_Multi
475 | StringEscape Escape
480 | BadUnicodeFormat Word16
481 | BadUnicodeCode Word16
482 | BadUnicodeLength Word16 Int Int
489 | NumberNoLeadingZero
498 | EndlessMultiComment
505toReport :: Code.Source -> Error -> Report.Report
508 ModuleNameUnspecified name ->
510 region = toRegion 1 1
512 Report.Report "MODULE NAME MISSING" region [] $
515 "I need the module name to be declared at the top of this file, like this:"
516 , D.indent 4 $ D.green $ D.fromChars $
517 "module " ++ ModuleName.toChars name ++ " exposing (..)"
519 "Try adding that as the first line of your file!"
521 "It is best to replace (..) with an explicit list of types and\
522 \ functions you want to expose. When you know a value is only used\
523 \ within this module, you can refactor without worrying about uses\
524 \ elsewhere. Limiting exposed values can also speed up compilation\
525 \ because I can skip a bunch of work if I see that the exposed API\
529 ModuleNameMismatch expectedName (A.At region actualName) ->
530 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
531 Code.toSnippet source region Nothing
533 "It looks like this module name is out of sync:"
537 "I need it to match the file path, so I was expecting it to see `"
538 ++ ModuleName.toChars expectedName
539 ++ "` here. Make the following change, and you should be all set!"
541 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
543 "I require that module names correspond to file paths. This makes it much\
544 \ easier to explore unfamiliar codebases! So if you want to keep the current\
545 \ module name, try renaming the file instead."
549 UnexpectedPort region ->
550 error "TODO UnexpectedPort" region
553 error "TODO NoPorts" region
556 toParseErrorReport source modul
559toParseErrorReport :: Code.Source -> Module -> Report.Report
560toParseErrorReport source modul =
562 ModuleSpace space row col ->
563 toSpaceReport source space row col
565 ModuleEndOfFile row col ->
567 region = toRegion row col
569 Report.Report "EXPECTING END OF FILE" region [] $
570 Code.toSnippet source region Nothing
573 "I was not expecting to see anything more here:"
576 "I think I have read all the declarations in the file and that there is nothing\
577 \ left to see, so whatever I am running into is confusing me a lot!"
581 error "TODO Module" row col
583 ModuleName row col ->
584 error "TODO ModuleName" row col
586 ModuleExposing row col ->
587 error "TODO ModuleExposing" row col
589 ModuleExposingList exposing row col ->
590 error "TODO ModuleExposingList" exposing row col
592 ModulePortModule row col ->
593 error "TODO ModulePortModule" row col
595 ModuleEffect row col ->
596 error "TODO ModuleEffect" row col
598 ModuleIndentStart row col ->
599 error "TODO ModuleIndentStart" row col
601 ModuleIndentName row col ->
602 error "TODO ModuleIndentName" row col
604 ModuleIndentExposing row col ->
605 error "TODO ModuleIndentExposing" row col
607 ModuleIndentExposingList row col ->
608 error "TODO ModuleIndentExposingList" row col
610 ModuleIndentPortModule row col ->
611 error "TODO ModuleIndentPortModule" row col
613 FreshLineModuleStart row col ->
614 error "TODO FreshLineModuleStart" row col
616 FreshLineAfterModuleLine row col ->
617 error "TODO FreshLineAfterModuleLine" row col
619 FreshLineAfterDocComment row col ->
620 error "TODO FreshLineAfterDocComment" row col
622 ImportStart row col ->
623 error "TODO ImportStart" row col
625 ImportName row col ->
626 error "TODO ImportName" row col
629 error "TODO ImportAs" row col
631 ImportAlias row col ->
632 error "TODO ImportAlias" row col
634 ImportExposing row col ->
635 error "TODO ImportExposing" row col
637 ImportExposingList exposing row col ->
638 error "TODO ImportExposingList" exposing row col
641 error "TODO ImportEnd" row col
643 ImportIndentName row col ->
644 error "TODO ImportIndentName" row col
646 ImportIndentAlias row col ->
647 error "TODO ImportIndentAlias" row col
649 ImportIndentExposingList row col ->
651 region = toRegion row col
653 Report.Report "UNFINISHED IMPORT" region [] $
654 Code.toSnippet source region Nothing
657 "I was parsing an `import` until I got stuck here:"
661 "I was expecting to see the list of exposed values next. For example, here\
662 \ are two ways to expose values from the `Html` module:"
663 , D.indent 4 $ D.vcat $
664 [ D.fillSep [D.blue "import","Html",D.blue "exposing",D.green "(..)"]
665 , D.fillSep [D.blue "import","Html",D.blue "exposing",D.green "(Html, div, text)"]
668 "I generally recommend the second style. It is more explicit, making it\
669 \ much easier to figure out where values are coming from in large projects!"
675 region = toRegion row col
677 Report.Report "BAD INFIX" region [] $
678 Code.toSnippet source region Nothing
681 "Something went wrong in this infix operator declaration:"
684 "This feature is used by the @elm organization to define the\
685 \ languages built-in operators."
688 Declarations decl _ _ ->
689 toDeclarationsReport source decl
692toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
693toSpaceReport source space row col =
697 region = toRegion row col
699 Report.Report "NO TABS" region [] $
700 Code.toSnippet source region Nothing
703 "I ran into a tab, but tabs are not allowed in Elm files."
706 "Replace the tab with spaces."
709 EndlessMultiComment ->
711 region = toWiderRegion row col 2
713 Report.Report "ENDLESS COMMENT" region [] $
714 Code.toSnippet source region Nothing
717 "I cannot find the end of this multi-line comment:"
720 [ D.reflow "Add a -} somewhere after this to end the comment."
722 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
723 \ that happens to contain another comment. Like parentheses and curly braces,\
724 \ the start and end markers must always be balanced. Maybe that is the problem?"
729toRegion :: Row -> Col -> A.Region
732 pos = A.Position row col
737toWiderRegion :: Row -> Col -> Word16 -> A.Region
738toWiderRegion row col extra =
741 (A.Position row (col + extra))
744toDeclarationsReport :: Code.Source -> Decl -> Report.Report
745toDeclarationsReport source decl =
748 error "TODO DeclStart" row col
750 DeclSpace space row col ->
751 toSpaceReport source space row col
754 error "TODO Port" port row col
756 DeclType declType row col ->
757 error "TODO DeclType" declType row col
759 DeclDef name declDef row col ->
760 toDeclDefReport source name declDef row col
762 DeclFreshLineStart row col ->
763 error "TODO DeclFreshLineStart" row col
765 DeclFreshLineAfterDocComment row col ->
766 error "TODO DeclFreshLineAfterDocComment" row col
769toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
770toDeclDefReport source name declDef startRow startCol =
772 DeclDefSpace space row col ->
773 toSpaceReport source space row col
775 DeclDefEquals row col ->
776 error "TODO DeclDefEquals" row col
778 DeclDefType tipe row col ->
779 error "TODO DeclDefType" tipe row col
781 DeclDefArg pattern row col ->
782 error "TODO DeclDefArg" pattern row col
784 DeclDefBody expr row col ->
785 toExprReport source (InDef name startRow startCol) expr row col
787 DeclDefNameRepeat row col ->
788 error "TODO DeclDefNameRepeat" name row col
790 DeclDefNameMatch defName row col ->
791 error "TODO DeclDefNameMatch" name defName row col
793 DeclDefIndentType row col ->
794 error "TODO DeclDefIndentType" row col
796 DeclDefIndentEquals row col ->
797 error "TODO DeclDefIndentEquals" row col
799 DeclDefIndentBody row col ->
800 error "TODO DeclDefIndentBody" row col
802 DeclDefFreshLineAfterType row col ->
803 error "TODO DeclDefFreshLineAfterType" row col
811 = InNode Node Row Col Context
812 | InDef Name.Name Row Col
826getDefName :: Context -> Name.Name
829 InDef name _ _ -> name
830 InNode _ _ _ c -> getDefName c
833isWithin :: Node -> Context -> Bool
834isWithin desiredNode context =
837 InNode actualNode _ _ _ -> desiredNode == actualNode
844toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
845toExprReport source context expr startRow startCol =
854 toIfReport source context if_ row col
857 toListReport source context list row col
859 Record record row col ->
860 toRecordReport source context record row col
862 Tuple tuple row col ->
863 toTupleReport source context tuple row col
866 toFuncReport source context func row col
869 let region = toRegion row col in
870 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
871 Code.toSnippet source region Nothing
874 "I was expecting to see a record accessor here:"
877 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
878 ,"that","accesses","a","value","from","a","record."
883 let region = toRegion row col in
884 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
885 Code.toSnippet source region Nothing
888 "I am trying to parse a record accessor here:"
893 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
894 ,"that","accesses","a","value","from","a","record."
898 "Record field names must start with a lower case letter!"
902 OperatorRight op row col ->
903 let region = toRegion row col in
904 Report.Report "MISSING EXPRESSION" region [] $
905 Code.toSnippet source region Nothing
908 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
912 ["You","can","just","put","anything","for","now,","like"
913 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
914 ,"Once","there","is","something","there,","I","can","probably"
915 ,"give","a","more","specific","hint!"
918 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
919 \ Or if I run into operators in unexpected spots. Point is, there are a\
920 \ couple ways I can get confused and give sort of weird advice!"
924 OperatorReserved operator row col ->
925 toOperatorReport source context operator row col
929 (contextRow, contextCol, aThing) =
931 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
932 InNode NRecord r c _ -> (r, c, "a record")
933 InNode NParens r c _ -> (r, c, "some parentheses")
934 InNode NList r c _ -> (r, c, "a list")
935 InNode NFunc r c _ -> (r, c, "an anonymous function")
936 InNode NCond r c _ -> (r, c, "an `if` expression")
937 InNode NThen r c _ -> (r, c, "an `if` expression")
938 InNode NElse r c _ -> (r, c, "an `if` expression")
939 -- TODO check if this is actually the best way to get error messages here
941 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
942 region = toRegion row col
944 Report.Report "MISSING EXPRESSION" region [] $
945 Code.toSnippet source surroundings (Just region)
948 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
952 ["I","was","expecting","to","see","an","expression","like"
953 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
954 ,"Once","there","is","something","there,","I","can","probably"
955 ,"give","a","more","specific","hint!"
958 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
959 \ Or if I run into operators in unexpected spots. Point is, there are a\
960 \ couple ways I can get confused and give sort of weird advice!"
965 toCharReport source char row col
967 String string row col ->
968 toStringReport source string row col
970 Number number row col ->
971 toNumberReport source number row col
973 Space space row col ->
974 toSpaceReport source space row col
976 EndlessShader row col ->
978 region = toWiderRegion row col 6
980 Report.Report "ENDLESS SHADER" region [] $
981 Code.toSnippet source region Nothing
983 D.reflow "I cannot find the end of this shader:"
985 D.reflow "Add a |] somewhere after this to end the shader."
988 ShaderProblem problem row col ->
990 region = toRegion row col
992 Report.Report "SHADER PROBLEM" region [] $
993 Code.toSnippet source region Nothing
996 "I ran into a problem while parsing this GLSL block."
1000 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
1001 , D.indent 4 $ D.vcat $
1002 map D.fromChars (filter (/="") (lines problem))
1006 IndentOperatorRight op row col ->
1008 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1009 region = toRegion row col
1011 Report.Report "MISSING EXPRESSION" region [] $
1012 Code.toSnippet source surroundings (Just region)
1015 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1020 ["You","can","just","put","anything","for","now,","like"
1021 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1022 ,"Once","there","is","something","there,","I","can","probably"
1023 ,"give","a","more","specific","hint!"
1027 "I may be getting confused by your indentation? The easiest way to make sure\
1028 \ this is not an indentation problem is to put the expression on the right of\
1029 \ the " ++ Name.toChars op ++ " operator on the same line."
1033 IndentMoreExpr _ _ ->
1034 error "TODO IndentMoreExpr"
1041toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
1042toCharReport source char row col =
1046 region = toRegion row col
1048 Report.Report "MISSING SINGLE QUOTE" region [] $
1049 Code.toSnippet source region Nothing
1052 "I thought I was parsing a character, but I got to the end of\
1053 \ the line without seeing the closing single quote:"
1056 "Add a closing single quote here!"
1059 CharEscape escape ->
1060 toEscapeReport source escape row col
1062 CharNotString width ->
1064 region = toWiderRegion row col width
1066 Report.Report "NEEDS DOUBLE QUOTES" region [] $
1067 Code.toSnippet source region Nothing
1069 "The following string uses single quotes:"
1072 [ "Please switch to double quotes instead:"
1074 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
1076 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
1077 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
1078 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
1079 \ individual characters."
1088toStringReport :: Code.Source -> String -> Row -> Col -> Report.Report
1089toStringReport source string row col =
1091 StringEndless_Single ->
1093 region = toRegion row col
1095 Report.Report "ENDLESS STRING" region [] $
1096 Code.toSnippet source region Nothing
1099 "I got to the end of the line without seeing the closing double quote:"
1103 ["Strings","look","like",D.green "\"this\"","with","double"
1104 ,"quotes","on","each","end.","Is","the","closing","double"
1105 ,"quote","missing","in","your","code?"
1107 , D.link "Note" "Read" "TODO" "if you want a string that spans multiple lines."
1111 StringEndless_Multi ->
1113 region = toWiderRegion row col 3
1115 Report.Report "ENDLESS STRING" region [] $
1116 Code.toSnippet source region Nothing
1119 "I cannot find the end of this multi-line string:"
1122 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
1123 , D.link "Hint" "Read" "TODO" "for more information on strings and multi-line strings."
1127 StringEscape escape ->
1128 toEscapeReport source escape row col
1135toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1136toEscapeReport source escape row col =
1140 region = toWiderRegion row col 2
1142 Report.Report "UNKNOWN ESCAPE" region [] $
1143 Code.toSnippet source region Nothing
1146 "Backslashes always start escaped characters, but I do not recognize this one:"
1150 "Valid escape characters include:"
1151 , D.dullyellow $ D.indent 4 $ D.vcat $
1161 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1163 "The last style lets encode ANY character by its Unicode code\
1164 \ point. That means \\u{0009} and \\t are the same. You can use\
1165 \ that style for anything not covered by the other six escapes!"
1169 BadUnicodeFormat width ->
1171 region = toWiderRegion row col width
1173 Report.Report "BAD UNICODE ESCAPE" region [] $
1174 Code.toSnippet source region Nothing
1177 "I ran into an invalid Unicode escape:"
1181 "Here are some examples of valid Unicode escapes:"
1182 , D.dullyellow $ D.indent 4 $ D.vcat $
1189 "Notice that the code point is always surrounded by curly braces.\
1190 \ Maybe you are missing the opening or closing curly brace?"
1193 BadUnicodeCode width ->
1195 region = toWiderRegion row col width
1197 Report.Report "BAD UNICODE ESCAPE" region [] $
1198 Code.toSnippet source region Nothing
1201 "This is not a valid code point:"
1204 "The valid code points are between 0 and 10FFFF inclusive."
1207 BadUnicodeLength width numDigits badCode ->
1209 region = toWiderRegion row col width
1211 Report.Report "BAD UNICODE ESCAPE" region [] $
1212 Code.toSnippet source region Nothing $
1213 if numDigits < 4 then
1216 "Every code point needs at least four digits:"
1219 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1220 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1222 D.fillSep ["Try",D.green suggestion,"instead?"]
1228 "This code point has too many digits:"
1231 ["Valid","code","points","are","between"
1232 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1233 ,"so","try","trimming","any","leading","zeros","until"
1234 ,"you","have","between","four","and","six","digits."
1243toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1244toNumberReport source number row col =
1246 region = toRegion row col
1250 Report.Report "WEIRD NUMBER" region [] $
1251 Code.toSnippet source region Nothing
1254 "I thought I was reading a number, but I ran into some weird stuff here:"
1258 "I recognize numbers in the following formats:"
1259 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1261 "So is there a way to write it like one of those?"
1266 Report.Report "WEIRD NUMBER" region [] $
1267 Code.toSnippet source region Nothing
1270 "Numbers cannot end with a dot like this:"
1273 ["Switching","to",D.green (D.fromChars (show int))
1274 ,"or",D.green (D.fromChars (show int ++ ".0"))
1275 ,"will","work","though!"
1280 Report.Report "WEIRD HEXIDECIMAL" region [] $
1281 Code.toSnippet source region Nothing
1284 "I thought I was reading a hexidecimal number until I got here:"
1288 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1289 \ only recognize things like this:"
1290 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1294 NumberNoLeadingZero ->
1295 Report.Report "LEADING ZEROS" region [] $
1296 Code.toSnippet source region Nothing
1299 "I do not accept numbers with leading zeros:"
1303 "Just delete the leading zeros and it should work!"
1305 "Some languages let you to specify octal numbers by adding a leading zero.\
1306 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1307 \ that, but others probably want it to equal 111. Either path is going to\
1308 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1318toOperatorReport :: Code.Source -> Context -> BadOperator -> Row -> Col -> Report.Report
1319toOperatorReport source context operator row col =
1323 region = toRegion row col
1325 Report.Report "UNEXPECTED SYMBOL" region [] $
1326 Code.toSnippet source region Nothing
1328 "I was not expecting this dot:"
1331 "Dots are for record access and decimal points, so\
1332 \ they cannot float around on their own. Maybe\
1333 \ there is some extra whitespace?"
1338 region = toRegion row col
1340 Report.Report "UNEXPECTED SYMBOL" region [] $
1341 Code.toSnippet source region Nothing
1344 "I was not expecting this vertical bar:"
1347 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
1352 region = toWiderRegion row col 2
1354 Report.Report "UNEXPECTED ARROW" region [] $
1355 Code.toSnippet source region Nothing $
1356 if error "TODO inCase" then
1359 "I was not expecting to see an arrow here:"
1364 "I think I am parsing a `case` expression right now, so it makes sense to\
1365 \ see arrows around here. This one is confusing me though!"
1368 "I may be getting confused by the indentation. Every pattern in a `case` must be\
1369 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
1370 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
1371 \ indented too far?"
1378 "I was not expecting an arrow here:"
1381 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
1382 \ you want > or >= instead?"
1387 region = toRegion row col
1388 name = getDefName context
1390 Report.Report "UNEXPECTED EQUALS" region [] $
1391 Code.toSnippet source region Nothing
1394 "I was not expecting to see this equals sign:"
1398 D.reflow "Maybe you want == instead? To check if two values are equal?"
1401 if isWithin NRecord context then
1402 "Records look like { x = 3, y = 4 } with the equals sign right\
1403 \ after the field name. So maybe you forgot a comma?"
1405 "I may be getting confused by your indentation. Is this supposed to be part of\
1406 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1407 \ the problem may be a bit before the equals sign. I need all definitions to\
1408 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1409 \ this new definition is indented a bit too much."
1415 region = toRegion row col
1416 name = getDefName context
1418 Report.Report "UNEXPECTED SYMBOL" region [] $
1419 Code.toSnippet source region Nothing $
1422 "I was not expecting to run into the \"has type\" symbol here:"
1427 ["Maybe","you","want",D.green "::","instead?"
1428 ,"To","put","something","on","the","front","of","a","list?"
1431 "The single colon is reserved for type annotations and record types, but I think\
1432 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
1435 "I may be getting confused by your indentation. Is this supposed to be part of\
1436 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1437 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
1438 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1439 \ this new definition is indented a bit too much."
1448toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
1449toIfReport source context if_ startRow startCol =
1451 IfSpace space row col ->
1452 toSpaceReport source space row col
1456 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1457 region = toRegion row col
1459 Report.Report "UNFINISHED IF" region [] $
1460 Code.toSnippet source surroundings (Just region)
1463 "I was expecting to see more of this `if` expression, but I got stuck here:"
1466 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1472 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1473 region = toRegion row col
1475 Report.Report "UNFINISHED IF" region [] $
1476 Code.toSnippet source surroundings (Just region)
1479 "I was expecting to see more of this `if` expression, but I got stuck here:"
1482 ["I","was","expecting","to","see","the",D.green "else","keyword","next."
1486 IfElseBranchStart row col ->
1488 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1489 region = toRegion row col
1491 Report.Report "UNFINISHED IF" region [] $
1492 Code.toSnippet source surroundings (Just region)
1495 "I just saw the start of an `else` branch, but then I got stuck here:"
1498 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1501 IfCondition expr row col ->
1502 toExprReport source (InNode NCond startRow startCol context) expr row col
1504 IfThenBranch expr row col ->
1505 toExprReport source (InNode NThen startRow startCol context) expr row col
1507 IfElseBranch expr row col ->
1508 toExprReport source (InNode NElse startRow startCol context) expr row col
1510 IfIndentCondition row col ->
1512 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1513 region = toRegion row col
1515 Report.Report "UNFINISHED IF" region [] $
1516 Code.toSnippet source surroundings (Just region)
1519 "I was expecting to see more of this `if` expression, but I got stuck here:"
1523 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
1524 ,"that","evaluates","to","True","or","False."
1527 "I can be confused by indentation. Maybe something is not indented enough?"
1531 IfIndentThen row col ->
1533 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1534 region = toRegion row col
1536 Report.Report "UNFINISHED IF" region [] $
1537 Code.toSnippet source surroundings (Just region)
1540 "I was expecting to see more of this `if` expression, but I got stuck here:"
1544 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1547 "I can be confused by indentation. Maybe something is not indented enough?"
1551 IfIndentThenBranch row col ->
1553 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1554 region = toRegion row col
1556 Report.Report "UNFINISHED IF" region [] $
1557 Code.toSnippet source surroundings (Just region)
1560 "I got stuck after the start of this `then` branch:"
1564 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1566 "I can be confused by indentation, so if the `then` branch is already\
1567 \ present, it may not be indented enough for me to recognize it."
1571 IfIndentElseBranch row col ->
1573 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1574 region = toRegion row col
1576 Report.Report "UNFINISHED IF" region [] $
1577 Code.toSnippet source surroundings (Just region)
1580 "I got stuck after the start of this `else` branch:"
1584 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1586 "I can be confused by indentation, so if the `else` branch is already\
1587 \ present, it may not be indented enough for me to recognize it."
1591 IfIndentElse row col ->
1593 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1594 region = toRegion row col
1596 Report.Report "UNFINISHED IF" region [] $
1597 Code.toSnippet source surroundings (Just region)
1600 "I was expecting to see an `else` branch after this:"
1604 "I know what to do when the condition is `True`, but not when it is `False`."
1606 ["Add","an",D.green "else","branch","to","handle","that","scenario!"]
1615toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
1616toRecordReport source context record startRow startCol =
1618 RecordOpen row col ->
1620 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1621 region = toRegion row col
1623 case Code.whatIsNext source row col of
1625 Report.Report "RESERVED WORD" region [] $
1626 Code.toSnippet source surroundings (Just region)
1629 "I just started parsing a record, but I got stuck on this field name:"
1632 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
1633 \ that is a reserved word. Try using a different name!"
1637 Report.Report "UNFINISHED RECORD" region [] $
1638 Code.toSnippet source surroundings (Just region)
1641 "I just started parsing a record, but I got stuck here:"
1644 ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
1645 ,"so","I","was","expecting","to","see","a","field","name","next."
1649 RecordEnd row col ->
1651 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1652 region = toRegion row col
1654 Report.Report "UNFINISHED RECORD" region [] $
1655 Code.toSnippet source surroundings (Just region)
1658 "I am partway through parsing a record, but I got stuck here:"
1662 ["I","was","expecting","to","see","a","closing","curly","brace","before","this,"
1663 ,"so","try","adding","a",D.dullyellow "}","and","see","if","that","helps?"
1666 "When I get stuck like this, it usually means that there is a missing parenthesis\
1667 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
1671 RecordField row col ->
1673 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1674 region = toRegion row col
1676 case Code.whatIsNext source row col of
1677 Code.Keyword keyword ->
1678 Report.Report "RESERVED WORD" region [] $
1679 Code.toSnippet source surroundings (Just region)
1682 "I am partway through parsing a record, but I got stuck on this field name:"
1685 "It looks like you are trying to use `" ++ keyword ++ "` as a field name, but \
1686 \ that is a reserved word. Try using a different name!"
1690 Report.Report "UNFINISHED RECORD" region [] $
1691 Code.toSnippet source surroundings (Just region)
1694 "I am partway through parsing a record, but I got stuck after that last comma:"
1696 addNoteForRecordError $
1698 "Trailing commas are not allowed in records, so I was expecting to see another\
1699 \ record field defined next. If you are done defining the record, the fix may\
1700 \ be to delete that last comma?"
1703 RecordEquals row col ->
1705 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1706 region = toRegion row col
1708 Report.Report "UNFINISHED RECORD" region [] $
1709 Code.toSnippet source surroundings (Just region)
1712 "I am partway through parsing a record, but I got stuck here:"
1714 addNoteForRecordError $
1716 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
1717 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
1721 RecordExpr expr row col ->
1722 toExprReport source (InNode NRecord startRow startCol context) expr row col
1724 RecordSpace space row col ->
1725 toSpaceReport source space row col
1727 RecordIndentOpen row col ->
1729 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1730 region = toRegion row col
1732 Report.Report "UNFINISHED RECORD" region [] $
1733 Code.toSnippet source surroundings (Just region)
1736 "I just saw the opening curly brace of a record, but then I got stuck here:"
1738 addNoteForRecordIndentError $
1740 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
1741 ,"Try","defining","some","fields","of","your","own?"
1745 RecordIndentEnd row col ->
1747 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1748 region = toRegion row col
1750 Report.Report "UNFINISHED RECORD" region [] $
1751 Code.toSnippet source surroundings (Just region)
1754 "I was expecting to see a closing curly brace next:"
1756 addNoteForRecordIndentError $
1758 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
1762 RecordIndentField row col ->
1764 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1765 region = toRegion row col
1767 Report.Report "UNFINISHED RECORD" region [] $
1768 Code.toSnippet source surroundings (Just region)
1771 "I am partway through parsing a record, but I got stuck after that last comma:"
1773 addNoteForRecordError $
1775 "Trailing commas are not allowed in records, so the fix may be to\
1776 \ delete that last comma? Or maybe you were in the middle of defining\
1777 \ an additional field?"
1780 RecordIndentEquals row col ->
1782 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1783 region = toRegion row col
1785 Report.Report "UNFINISHED RECORD" region [] $
1786 Code.toSnippet source surroundings (Just region)
1789 "I am partway through parsing a record. I just saw a record\
1790 \ field, so I was expecting to see an equals sign next:"
1792 addNoteForRecordIndentError $
1794 ["Try","putting","an",D.green "=","followed","by","an","expression?"
1798 RecordIndentExpr row col ->
1800 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1801 region = toRegion row col
1803 Report.Report "UNFINISHED RECORD" region [] $
1804 Code.toSnippet source surroundings (Just region)
1807 "I am partway through parsing a record, and I was expecting to run into an expression next:"
1809 addNoteForRecordIndentError $
1811 ["Try","putting","something,","like"
1812 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
1817addNoteForRecordError :: D.Doc -> D.Doc
1818addNoteForRecordError normalRecommendation =
1820 normalRecommendation
1823 "If you are trying to define a record across multiple lines, I recommend using this format:"
1824 , D.indent 4 $ D.vcat $
1825 [ "{ name = \"Alice\""
1831 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1832 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1833 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1837addNoteForRecordIndentError :: D.Doc -> D.Doc
1838addNoteForRecordIndentError normalRecommendation =
1840 normalRecommendation
1843 "I may be confused by indentation. For example, if you are trying to define\
1844 \ a record across multiple lines, I recommend using this format:"
1845 , D.indent 4 $ D.vcat $
1852 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1853 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1854 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1862toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
1863toTupleReport source context tuple startRow startCol =
1865 TupleExpr expr row col ->
1866 toExprReport source (InNode NParens startRow startCol context) expr row col
1868 TupleSpace space row col ->
1869 toSpaceReport source space row col
1873 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1874 region = toRegion row col
1876 Report.Report "UNFINISHED PARENTHESES" region [] $
1877 Code.toSnippet source surroundings (Just region)
1880 "I was expecting to see a closing parentheses next, but I got stuck here:"
1883 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
1885 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1886 \ unexpectedly. So there may be some earlier syntax trouble (like extra parenthesis\
1887 \ or missing brackets) that is confusing me."
1891 TupleOperatorClose row col ->
1893 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1894 region = toRegion row col
1896 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
1897 Code.toSnippet source surroundings (Just region)
1899 D.reflow "I was expecting a closing parenthesis here:"
1902 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
1904 "I think I am parsing an operator function right now, so I am expecting to see\
1905 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
1910 TupleOperatorReserved operator row col ->
1912 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1913 region = toRegion row col
1915 Report.Report "UNEXPECTED SYMBOL" region [] $
1916 Code.toSnippet source surroundings (Just region)
1919 "I ran into an unexpected symbol here:"
1923 BadDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
1924 BadPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
1925 BadArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
1926 BadEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
1927 BadHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
1930 TupleIndentExpr1 row col ->
1932 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1933 region = toRegion row col
1935 Report.Report "UNFINISHED PARENTHESES" region [] $
1936 Code.toSnippet source surroundings (Just region)
1939 "I just saw an open parenthesis, so I was expecting to see an expression next."
1943 ["Something","like",D.dullyellow "(4 + 5)","or"
1944 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
1945 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
1948 "I can get confused by indentation in cases like this, so\
1949 \ maybe you have an expression but it is not indented enough?"
1953 TupleIndentExprN row col ->
1955 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1956 region = toRegion row col
1958 Report.Report "UNFINISHED TUPLE" region [] $
1959 Code.toSnippet source surroundings (Just region)
1962 "I think I am in the middle of parsing a tuple. I just saw a comma, so I was expecting to see expression next."
1966 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
1967 ,D.dullyellow "(\"Tom\",42)" <> ","
1968 ,"so","I","think","there","is","an","expression","missing","here?"
1971 "I can get confused by indentation in cases like this, so\
1972 \ maybe you have an expression but it is not indented enough?"
1976 TupleIndentEnd row col ->
1978 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1979 region = toRegion row col
1981 Report.Report "UNFINISHED PARENTHESES" region [] $
1982 Code.toSnippet source surroundings (Just region)
1985 "I was expecting to see a closing parenthesis next:"
1988 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
1990 "I can get confused by indentation in cases like this, so\
1991 \ maybe you have a closing parenthesis but it is not indented enough?"
1996toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
1997toListReport source context list startRow startCol =
1999 ListSpace space row col ->
2000 toSpaceReport source space row col
2004 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2005 region = toRegion row col
2007 Report.Report "UNFINISHED LIST" region [] $
2008 Code.toSnippet source surroundings (Just region)
2011 "I am partway through parsing a list, but I got stuck here:"
2015 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2016 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2019 "When I get stuck like this, it usually means that there is a missing parenthesis\
2020 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2024 ListExpr expr row col ->
2028 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
2029 region = toRegion r c
2031 Report.Report "UNFINISHED LIST" region [] $
2032 Code.toSnippet source surroundings (Just region)
2035 "I was expecting to see another list entry after that last comma:"
2039 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2041 "I recommend using the following format for lists that span multiple lines:"
2042 , D.indent 4 $ D.vcat $
2049 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2050 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2051 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2056 toExprReport source (InNode NList startRow startCol context) expr row col
2060 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2061 region = toRegion row col
2063 Report.Report "UNFINISHED LIST" region [] $
2064 Code.toSnippet source surroundings (Just region)
2067 "I am partway through parsing a list, but I got stuck here:"
2071 ["I","was","expecting","to","see","a","closing","square","bracket","before","this,"
2072 ,"so","try","adding","a",D.dullyellow "]","and","see","if","that","helps?"
2075 "When I get stuck like this, it usually means that there is a missing parenthesis\
2076 \ or bracket somewhere earlier. It could also be a stray keyword or operator."
2080 ListIndentOpen row col ->
2082 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2083 region = toRegion row col
2085 Report.Report "UNFINISHED LIST" region [] $
2086 Code.toSnippet source surroundings (Just region)
2089 "I cannot find the end of this list:"
2093 ["You","could","change","it","to","something","like"
2094 ,D.dullyellow "[3,4,5]"
2096 ,D.dullyellow "[]" <> "."
2097 ,"Anything","where","there","is","an","open","and","close","square","brace,"
2098 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
2101 "I may be confused by indentation. For example, if you are trying to define\
2102 \ a list across multiple lines, I recommend using this format:"
2103 , D.indent 4 $ D.vcat $
2110 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2111 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2112 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2116 ListIndentEnd row col ->
2118 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2119 region = toRegion row col
2121 Report.Report "UNFINISHED LIST" region [] $
2122 Code.toSnippet source surroundings (Just region)
2125 "I cannot find the end of this list:"
2129 ["You","can","just","add","a","closing",D.dullyellow "]"
2130 ,"right","here,","and","I","will","be","all","set!"
2133 "I may be confused by indentation. For example, if you are trying to define\
2134 \ a list across multiple lines, I recommend using this format:"
2135 , D.indent 4 $ D.vcat $
2142 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2143 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2144 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2148 ListIndentExpr row col ->
2150 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2151 region = toRegion row col
2153 Report.Report "UNFINISHED LIST" region [] $
2154 Code.toSnippet source surroundings (Just region)
2157 "I was expecting to see another list entry after this comma:"
2161 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2163 "I recommend using the following format for lists that span multiple lines:"
2164 , D.indent 4 $ D.vcat $
2171 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2172 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2173 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2178toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
2179toFuncReport source context func startRow startCol =
2181 FuncSpace space row col ->
2182 toSpaceReport source space row col
2184 FuncArg pattern row col ->
2185 error "TODO FuncArg" pattern row col
2187 FuncBody expr row col ->
2188 toExprReport source (InNode NFunc startRow startCol context) expr row col
2190 FuncArrow row col ->
2192 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2193 region = toRegion row col
2195 case Code.whatIsNext source row col of
2196 Code.Keyword keyword ->
2197 Report.Report "RESERVED WORD" region [] $
2198 Code.toSnippet source surroundings (Just region)
2201 "I was parsing an anonymous function, but I got stuck here:"
2204 "It looks like you are trying to use `" ++ keyword ++ "` as an argument, but\
2205 \ it is a reserved word in this language. Try using a different argument name!"
2209 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2210 Code.toSnippet source surroundings (Just region)
2213 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2216 ["The","syntax","for","anonymous","functions","is"
2217 ,D.dullyellow "(\\x -> x + 1)"
2218 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2222 FuncIndentArg row col ->
2224 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2225 region = toRegion row col
2227 Report.Report "MISSING ARGUMENT" region [] $
2228 Code.toSnippet source surroundings (Just region)
2231 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
2235 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
2236 ,"Anything","that","starts","with","a","lower","case","letter!"
2239 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
2240 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
2241 \ like a better idea at the time!"
2245 FuncIndentArrow row col ->
2247 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2248 region = toRegion row col
2250 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2251 Code.toSnippet source surroundings (Just region)
2254 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2258 ["The","syntax","for","anonymous","functions","is"
2259 ,D.dullyellow "(\\x -> x + 1)"
2260 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2263 "It is possible that I am confused about indetation! I generally recommend\
2264 \ switching to named functions if the definition cannot fit inline nicely, so\
2265 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2266 \ the whole thing out into a named function. Things tend to be clearer that way!"
2270 FuncIndentBody row col ->
2272 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2273 region = toRegion row col
2275 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2276 Code.toSnippet source surroundings (Just region)
2279 "I was expecting to see the body of your anonymous function next:"
2283 ["The","syntax","for","anonymous","functions","is"
2284 ,D.dullyellow "(\\x -> x + 1)"
2285 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
2288 "It is possible that I am confused about indetation! I generally recommend\
2289 \ switching to named functions if the definition cannot fit inline nicely, so\
2290 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2291 \ the whole thing out into a named function. Things tend to be clearer that way!"
2300 CommentOnNothing region ->
2301 Report.Report "STRAY COMMENT" region [] $
2302 Code.toSnippet source region Nothing
2304 "This documentation comment is not followed by anything."
2307 "All documentation comments need to be right above the declaration they\
2308 \ describe. Maybe some code got deleted or commented out by accident? Or\
2309 \ maybe this comment is here by accident?"
2312 UnexpectedPort region ->
2313 Report.Report "UNEXPECTED PORTS" region [] $
2314 Code.toSnippet source region Nothing
2317 "You are declaring ports in a normal module."
2321 ["Switch","this","to","say",D.green "port module","instead,"
2322 ,"marking","that","this","module","contains","port","declarations."
2325 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
2327 "to learn the syntax and how to use it effectively."
2332 Report.Report "NO PORTS" region [] $
2333 Code.toSnippet source region Nothing
2336 "This module does not declare any ports, but it says it will:"
2339 ["Switch","this","to",D.green "module"
2340 ,"and","you","should","be","all","set!"
2344 ParseError row col context expectation ->
2346 pos = A.Position row col
2347 region = A.Region pos pos
2352 Report.Report "EXPECTING DOC COMMENT" region [] $
2353 Code.toSnippet source region Nothing
2356 "I was expecting a doc comment here:"
2359 "Check out" "TODO" "for examples of doc comments."
2365 Report.Report "EXPECTING PRECEDENCE" region [] $
2366 Code.toSnippet source region Nothing
2369 "I was expecting the precedence here:"
2372 "I need a single digit between 0 and 9 inclusive."
2376 Report.Report "EXPECTING A WILDCARD" region [] $
2377 Code.toSnippet source region Nothing
2380 "I was expecting a _ here:"
2383 "An underscore indicates that “I do not care about this value” and is\
2384 \ called a wildcard pattern because it will match with any type of values."
2387 WildcardNotVar startCol endCol ->
2390 A.Region (A.Position row startCol) (A.Position row endCol)
2392 Report.Report "INVALID PATTERN" badRegion [] $
2393 Code.toSnippet source badRegion Nothing
2396 "I was expecting to see an underscore without any additional characters:"
2399 "There are two options. Either (1) remove the extra characters and ignore the\
2400 \ value or (2) remove the starting underscore to give the value a normal name."
2406 Report.Report "INVALID PATTERN" region [] $
2407 Code.toSnippet source region Nothing
2410 "I cannot pattern match with floating point numbers:"
2413 "Equality on floats can be unreliable, so you usually want to check that they\
2414 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
2419 MatchingName name ->
2420 Report.Report "EXPECTING A DEFINITION" region [] $
2421 Code.toSnippet source region Nothing
2424 "I just saw the type annotation for `" ++ Name.toChars name
2425 ++ "` so I was expecting to see its definition here:"
2428 "Type annotations always appear directly above the relevant\
2429 \ definition, without anything else (even doc comments) in between."
2435 TypeWithBadDefinition region annName defName ->
2436 Report.Report "ANNOTATION MISMATCH" region [] $
2437 Code.toSnippet source region Nothing
2440 "I see a `" <> Name.toChars annName
2441 <> "` annotation, but it is followed by a `"
2442 <> Name.toChars defName <> "` definition."
2445 ["The","annotation","and","definition","names","must","match!"
2446 ,"Is","there","a","typo","between"
2447 , D.dullyellow (D.fromName annName)
2449 , D.dullyellow (D.fromName defName) <> "?"
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