1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Syntax
48import Prelude hiding (Char, String)
49import qualified Data.Char as Char
50import qualified Data.Name as Name
51import Data.Word (Word16)
52import Numeric (showHex)
54import qualified Elm.ModuleName as ModuleName
55import Parse.Primitives (Row, Col)
56import 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 Operator 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 Operator 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 Operator 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
513toReport :: Code.Source -> Error -> Report.Report
516 ModuleNameUnspecified name ->
518 region = toRegion 1 1
520 Report.Report "MODULE NAME MISSING" region [] $
523 "I need the module name to be declared at the top of this file, like this:"
524 , D.indent 4 $ D.green $ D.fromChars $
525 "module " ++ ModuleName.toChars name ++ " exposing (..)"
527 "Try adding that as the first line of your file!"
529 "It is best to replace (..) with an explicit list of types and\
530 \ functions you want to expose. When you know a value is only used\
531 \ within this module, you can refactor without worrying about uses\
532 \ elsewhere. Limiting exposed values can also speed up compilation\
533 \ because I can skip a bunch of work if I see that the exposed API\
537 ModuleNameMismatch expectedName (A.At region actualName) ->
538 Report.Report "MODULE NAME MISMATCH" region [ModuleName.toChars expectedName] $
539 Report.toCodeSnippet source region Nothing
541 "It looks like this module name is out of sync:"
545 "I need it to match the file path, so I was expecting it to see `"
546 ++ ModuleName.toChars expectedName
547 ++ "` here. Make the following change, and you should be all set!"
549 D.dullyellow (D.fromName actualName) <> " -> " <> D.green (D.fromName expectedName)
551 "I require that module names correspond to file paths. This makes it much\
552 \ easier to explore unfamiliar codebases! So if you want to keep the current\
553 \ module name, try renaming the file instead."
557 UnexpectedPort region ->
558 error "TODO UnexpectedPort" region
561 error "TODO NoPorts" region
564 toParseErrorReport source modul
567toParseErrorReport :: Code.Source -> Module -> Report.Report
568toParseErrorReport source modul =
570 ModuleSpace space row col ->
571 toSpaceReport source space row col
573 ModuleEndOfFile row col ->
575 region = toRegion row col
577 Report.Report "EXPECTING END OF FILE" region [] $
578 Report.toCodeSnippet source region Nothing
581 "I was not expecting to see anything more here:"
584 "I think I have read all the declarations in the file and that there is nothing\
585 \ left to see, so whatever I am running into is confusing me a lot!"
589 error "TODO Module" row col
591 ModuleName row col ->
592 error "TODO ModuleName" row col
594 ModuleExposing row col ->
595 error "TODO ModuleExposing" row col
597 ModuleExposingList exposing row col ->
598 error "TODO ModuleExposingList" exposing row col
600 ModulePortModule row col ->
601 error "TODO ModulePortModule" row col
603 ModuleEffect row col ->
604 error "TODO ModuleEffect" row col
606 ModuleIndentStart row col ->
607 error "TODO ModuleIndentStart" row col
609 ModuleIndentName row col ->
610 error "TODO ModuleIndentName" row col
612 ModuleIndentExposing row col ->
613 error "TODO ModuleIndentExposing" row col
615 ModuleIndentExposingList row col ->
616 error "TODO ModuleIndentExposingList" row col
618 ModuleIndentPortModule row col ->
619 error "TODO ModuleIndentPortModule" row col
621 FreshLineModuleStart row col ->
622 error "TODO FreshLineModuleStart" row col
624 FreshLineAfterModuleLine row col ->
625 error "TODO FreshLineAfterModuleLine" row col
627 FreshLineAfterDocComment row col ->
628 error "TODO FreshLineAfterDocComment" row col
630 ImportStart row col ->
631 error "TODO ImportStart" row col
633 ImportName row col ->
634 error "TODO ImportName" row col
637 error "TODO ImportAs" row col
639 ImportAlias row col ->
640 error "TODO ImportAlias" row col
642 ImportExposing row col ->
643 error "TODO ImportExposing" row col
645 ImportExposingList exposing row col ->
646 error "TODO ImportExposingList" exposing row col
649 error "TODO ImportEnd" row col
651 ImportIndentName row col ->
652 error "TODO ImportIndentName" row col
654 ImportIndentAlias row col ->
655 error "TODO ImportIndentAlias" row col
657 ImportIndentExposingList row col ->
659 region = toRegion row col
661 Report.Report "UNFINISHED IMPORT" region [] $
662 Report.toCodeSnippet source region Nothing
665 "I was parsing an `import` until I got stuck here:"
669 "I was expecting to see the list of exposed values next. For example, here\
670 \ are two ways to expose values from the `Html` module:"
671 , D.indent 4 $ D.vcat $
672 [ D.fillSep [D.blue "import","Html",D.blue "exposing",D.green "(..)"]
673 , D.fillSep [D.blue "import","Html",D.blue "exposing",D.green "(Html, div, text)"]
676 "I generally recommend the second style. It is more explicit, making it\
677 \ much easier to figure out where values are coming from in large projects!"
683 region = toRegion row col
685 Report.Report "BAD INFIX" region [] $
686 Report.toCodeSnippet source region Nothing
689 "Something went wrong in this infix operator declaration:"
692 "This feature is used by the @elm organization to define the\
693 \ languages built-in operators."
696 Declarations decl _ _ ->
697 toDeclarationsReport source decl
700toSpaceReport :: Code.Source -> Space -> Row -> Col -> Report.Report
701toSpaceReport source space row col =
705 region = toRegion row col
707 Report.Report "NO TABS" region [] $
708 Report.toCodeSnippet source region Nothing
711 "I ran into a tab, but tabs are not allowed in Elm files."
714 "Replace the tab with spaces."
717 EndlessMultiComment ->
719 region = toWiderRegion row col 2
721 Report.Report "ENDLESS COMMENT" region [] $
722 Report.toCodeSnippet source region Nothing
725 "I cannot find the end of this multi-line comment:"
728 [ D.reflow "Add a -} somewhere after this to end the comment."
730 "Multi-line comments can be nested in Elm, so {- {- -} -} is a comment\
731 \ that happens to contain another comment. Like parentheses and curly braces,\
732 \ the start and end markers must always be balanced. Maybe that is the problem?"
737toRegion :: Row -> Col -> A.Region
740 pos = A.Position row col
745toWiderRegion :: Row -> Col -> Word16 -> A.Region
746toWiderRegion row col extra =
749 (A.Position row (col + extra))
752toDeclarationsReport :: Code.Source -> Decl -> Report.Report
753toDeclarationsReport source decl =
756 error "TODO DeclStart" row col
758 DeclSpace space row col ->
759 toSpaceReport source space row col
762 error "TODO Port" port row col
764 DeclType declType row col ->
765 error "TODO DeclType" declType row col
767 DeclDef name declDef row col ->
768 toDeclDefReport source name declDef row col
770 DeclFreshLineStart row col ->
771 error "TODO DeclFreshLineStart" row col
773 DeclFreshLineAfterDocComment row col ->
774 error "TODO DeclFreshLineAfterDocComment" row col
777toDeclDefReport :: Code.Source -> Name.Name -> DeclDef -> Row -> Col -> Report.Report
778toDeclDefReport source name declDef startRow startCol =
780 DeclDefSpace space row col ->
781 toSpaceReport source space row col
783 DeclDefEquals row col ->
784 error "TODO DeclDefEquals" row col
786 DeclDefType tipe row col ->
787 error "TODO DeclDefType" tipe row col
789 DeclDefArg pattern row col ->
790 error "TODO DeclDefArg" pattern row col
792 DeclDefBody expr row col ->
793 toExprReport source (InDef name startRow startCol) expr row col
795 DeclDefNameRepeat row col ->
796 error "TODO DeclDefNameRepeat" name row col
798 DeclDefNameMatch defName row col ->
799 error "TODO DeclDefNameMatch" name defName row col
801 DeclDefIndentType row col ->
802 error "TODO DeclDefIndentType" row col
804 DeclDefIndentEquals row col ->
805 error "TODO DeclDefIndentEquals" row col
807 DeclDefIndentBody row col ->
808 error "TODO DeclDefIndentBody" row col
810 DeclDefFreshLineAfterType row col ->
811 error "TODO DeclDefFreshLineAfterType" row col
819 = InNode Node Row Col Context
820 | InDef Name.Name Row Col
834getDefName :: Context -> Name.Name
837 InDef name _ _ -> name
838 InNode _ _ _ c -> getDefName c
841isWithin :: Node -> Context -> Bool
842isWithin desiredNode context =
845 InNode actualNode _ _ _ -> desiredNode == actualNode
852toExprReport :: Code.Source -> Context -> Expr -> Row -> Col -> Report.Report
853toExprReport source context expr startRow startCol =
862 toIfReport source context if_ row col
865 toListReport source context list row col
867 Record record row col ->
868 toRecordReport source context record row col
870 Tuple tuple row col ->
871 toTupleReport source context tuple row col
874 toFuncReport source context func row col
877 let region = toRegion row col in
878 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
879 Report.toCodeSnippet source region Nothing
882 "I was expecting to see a record accessor here:"
885 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
886 ,"that","accesses","a","value","from","a","record."
891 let region = toRegion row col in
892 Report.Report "EXPECTING RECORD ACCESSOR" region [] $
893 Report.toCodeSnippet source region Nothing
896 "I am trying to parse a record accessor here:"
901 ["Something","like",D.dullyellow".name","or",D.dullyellow".price"
902 ,"that","accesses","a","value","from","a","record."
906 "Record field names must start with a lower case letter!"
910 OperatorRight op row col ->
911 let region = toRegion row col in
912 Report.Report "MISSING EXPRESSION" region [] $
913 Report.toCodeSnippet source region Nothing
916 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
920 ["You","can","just","put","anything","for","now,","like"
921 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
922 ,"Once","there","is","something","there,","I","can","probably"
923 ,"give","a","more","specific","hint!"
926 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
927 \ Or if I run into operators in unexpected spots. Point is, there are a\
928 \ couple ways I can get confused and give sort of weird advice!"
932 OperatorReserved operator row col ->
933 toOperatorReport source context operator row col
937 (contextRow, contextCol, aThing) =
939 InDef name r c -> (r, c, "the `" ++ Name.toChars name ++ "` definition")
940 InNode NRecord r c _ -> (r, c, "a record")
941 InNode NParens r c _ -> (r, c, "some parentheses")
942 InNode NList r c _ -> (r, c, "a list")
943 InNode NFunc r c _ -> (r, c, "an anonymous function")
944 InNode NCond r c _ -> (r, c, "an `if` expression")
945 InNode NThen r c _ -> (r, c, "an `if` expression")
946 InNode NElse r c _ -> (r, c, "an `if` expression")
947 -- TODO check if this is actually the best way to get error messages here
949 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
950 region = toRegion row col
952 Report.Report "MISSING EXPRESSION" region [] $
953 Report.toCodeSnippet source surroundings (Just region)
956 "I am partway through parsing " ++ aThing ++ ", but I got stuck here:"
960 ["I","was","expecting","to","see","an","expression","like"
961 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
962 ,"Once","there","is","something","there,","I","can","probably"
963 ,"give","a","more","specific","hint!"
966 "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
967 \ Or if I run into operators in unexpected spots. Point is, there are a\
968 \ couple ways I can get confused and give sort of weird advice!"
973 toCharReport source char row col
975 String string row col ->
976 toStringReport source string row col
978 Number number row col ->
979 toNumberReport source number row col
981 Space space row col ->
982 toSpaceReport source space row col
984 EndlessShader row col ->
986 region = toWiderRegion row col 6
988 Report.Report "ENDLESS SHADER" region [] $
989 Report.toCodeSnippet source region Nothing
991 D.reflow "I cannot find the end of this shader:"
993 D.reflow "Add a |] somewhere after this to end the shader."
996 ShaderProblem problem row col ->
998 region = toRegion row col
1000 Report.Report "SHADER PROBLEM" region [] $
1001 Report.toCodeSnippet source region Nothing
1004 "I ran into a problem while parsing this GLSL block."
1008 "I use a 3rd party GLSL parser for now, and I did my best to extract their error message:"
1009 , D.indent 4 $ D.vcat $
1010 map D.fromChars (filter (/="") (lines problem))
1014 IndentOperatorRight op row col ->
1016 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1017 region = toRegion row col
1019 Report.Report "MISSING EXPRESSION" region [] $
1020 Report.toCodeSnippet source surroundings (Just region)
1023 "I was expecting to see an expression after this " ++ Name.toChars op ++ " operator:"
1028 ["You","can","just","put","anything","for","now,","like"
1029 ,D.dullyellow "42","or",D.dullyellow"\"hello\"" <> "."
1030 ,"Once","there","is","something","there,","I","can","probably"
1031 ,"give","a","more","specific","hint!"
1035 "I may be getting confused by your indentation? The easiest way to make sure\
1036 \ this is not an indentation problem is to put the expression on the right of\
1037 \ the " ++ Name.toChars op ++ " operator on the same line."
1041 IndentMoreExpr _ _ ->
1042 error "TODO IndentMoreExpr"
1045toCharReport :: Code.Source -> Char -> Row -> Col -> Report.Report
1046toCharReport source char row col =
1050 region = toRegion row col
1052 Report.Report "MISSING SINGLE QUOTE" region [] $
1053 Report.toCodeSnippet source region Nothing
1056 "I thought I was parsing a character, but I got to the end of\
1057 \ the line without seeing the closing single quote:"
1060 "Add a closing single quote here!"
1063 CharEscape escape ->
1064 toEscapeReport source escape row col
1066 CharNotString width ->
1068 region = toWiderRegion row col width
1070 Report.Report "NEEDS DOUBLE QUOTES" region [] $
1071 Report.toCodeSnippet source region Nothing
1073 "The following string uses single quotes:"
1076 [ "Please switch to double quotes instead:"
1078 D.dullyellow "'this'" <> " => " <> D.green "\"this\""
1080 "Elm uses double quotes for strings like \"hello\", whereas it uses single\
1081 \ quotes for individual characters like 'a' and 'ø'. This distinction helps with\
1082 \ code like (String.any (\\c -> c == 'X') \"90210\") where you are inspecting\
1083 \ 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 Report.toCodeSnippet 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 Report.toCodeSnippet 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
1131toEscapeReport :: Code.Source -> Escape -> Row -> Col -> Report.Report
1132toEscapeReport source escape row col =
1136 region = toWiderRegion row col 2
1138 Report.Report "UNKNOWN ESCAPE" region [] $
1139 Report.toCodeSnippet source region Nothing
1142 "Backslashes always start escaped characters, but I do not recognize this one:"
1146 "Valid escape characters include:"
1147 , D.dullyellow $ D.indent 4 $ D.vcat $
1157 "Do you want one of those instead? Maybe you need \\\\ to escape a backslash?"
1159 "The last style lets encode ANY character by its Unicode code\
1160 \ point. That means \\u{0009} and \\t are the same. You can use\
1161 \ that style for anything not covered by the other six escapes!"
1165 BadUnicodeFormat width ->
1167 region = toWiderRegion row col width
1169 Report.Report "BAD UNICODE ESCAPE" region [] $
1170 Report.toCodeSnippet source region Nothing
1173 "I ran into an invalid Unicode escape:"
1177 "Here are some examples of valid Unicode escapes:"
1178 , D.dullyellow $ D.indent 4 $ D.vcat $
1185 "Notice that the code point is always surrounded by curly braces.\
1186 \ Maybe you are missing the opening or closing curly brace?"
1189 BadUnicodeCode width ->
1191 region = toWiderRegion row col width
1193 Report.Report "BAD UNICODE ESCAPE" region [] $
1194 Report.toCodeSnippet source region Nothing
1197 "This is not a valid code point:"
1200 "The valid code points are between 0 and 10FFFF inclusive."
1203 BadUnicodeLength width numDigits badCode ->
1205 region = toWiderRegion row col width
1207 Report.Report "BAD UNICODE ESCAPE" region [] $
1208 Report.toCodeSnippet source region Nothing $
1209 if numDigits < 4 then
1212 "Every code point needs at least four digits:"
1215 goodCode = replicate (4 - numDigits) '0' ++ map Char.toUpper (showHex badCode "")
1216 suggestion = "\\u{" <> D.fromChars goodCode <> "}"
1218 D.fillSep ["Try",D.green suggestion,"instead?"]
1224 "This code point has too many digits:"
1227 ["Valid","code","points","are","between"
1228 ,D.green "\\u{0000}","and",D.green "\\u{10FFFF}" <> ","
1229 ,"so","try","trimming","any","leading","zeros","until"
1230 ,"you","have","between","four","and","six","digits."
1235toNumberReport :: Code.Source -> Number -> Row -> Col -> Report.Report
1236toNumberReport source number row col =
1238 region = toRegion row col
1242 Report.Report "WEIRD NUMBER" region [] $
1243 Report.toCodeSnippet source region Nothing
1246 "I thought I was reading a number, but I ran into some weird stuff here:"
1250 "I recognize numbers in the following formats:"
1251 , D.indent 4 $ D.vcat [ "42", "3.14", "6.022e23", "0x002B" ]
1253 "So is there a way to write it like one of those?"
1258 Report.Report "WEIRD NUMBER" region [] $
1259 Report.toCodeSnippet source region Nothing
1262 "Numbers cannot end with a dot like this:"
1265 ["Switching","to",D.green (D.fromChars (show int))
1266 ,"or",D.green (D.fromChars (show int ++ ".0"))
1267 ,"will","work","though!"
1272 Report.Report "WEIRD HEXIDECIMAL" region [] $
1273 Report.toCodeSnippet source region Nothing
1276 "I thought I was reading a hexidecimal number until I got here:"
1280 "Valid hexidecimal digits include 0123456789abcdefABCDEF, so I can\
1281 \ only recognize things like this:"
1282 , D.indent 4 $ D.vcat [ "0x2B", "0x002B", "0x00ffb3" ]
1286 NumberNoLeadingZero ->
1287 Report.Report "LEADING ZEROS" region [] $
1288 Report.toCodeSnippet source region Nothing
1291 "I do not accept numbers with leading zeros:"
1295 "Just delete the leading zeros and it should work!"
1297 "Some languages let you to specify octal numbers by adding a leading zero.\
1298 \ So in C, writing 0111 is the same as writing 73. Some people are used to\
1299 \ that, but others probably want it to equal 111. Either path is going to\
1300 \ surprise people from certain backgrounds, so Elm tries to avoid this whole\
1306toOperatorReport :: Code.Source -> Context -> Operator -> Row -> Col -> Report.Report
1307toOperatorReport source context operator row col =
1311 region = toRegion row col
1313 Report.Report "UNEXPECTED SYMBOL" region [] $
1314 Report.toCodeSnippet source region Nothing
1316 "I was not expecting this dot:"
1319 "Dots are for record access and decimal points, so\
1320 \ they cannot float around on their own. Maybe\
1321 \ there is some extra whitespace?"
1326 region = toRegion row col
1328 Report.Report "UNEXPECTED SYMBOL" region [] $
1329 Report.toCodeSnippet source region Nothing
1332 "I was not expecting this vertical bar:"
1335 "Vertical bars should only appear in custom type declarations. Maybe you want || instead?"
1340 region = toWiderRegion row col 2
1342 Report.Report "UNEXPECTED ARROW" region [] $
1343 Report.toCodeSnippet source region Nothing $
1344 if error "TODO inCase" then
1347 "I was not expecting to see an arrow here:"
1352 "I think I am parsing a `case` expression right now, so it makes sense to\
1353 \ see arrows around here. This one is confusing me though!"
1356 "I may be getting confused by the indentation. Every pattern in a `case` must be\
1357 \ exactly aligned (with exactly the same amount of indentation) so maybe this arrow\
1358 \ appears after the next `case` pattern (correctly!) but the pattern itself is\
1359 \ indented too far?"
1366 "I was not expecting an arrow here:"
1369 "Arrows should only appear in `case` expressions and anonymous functions. Maybe\
1370 \ you want > or >= instead?"
1375 region = toRegion row col
1376 name = getDefName context
1378 Report.Report "UNEXPECTED EQUALS" region [] $
1379 Report.toCodeSnippet source region Nothing
1382 "I was not expecting to see this equals sign:"
1386 D.reflow "Maybe you want == instead? To check if two values are equal?"
1389 if isWithin NRecord context then
1390 "Records look like { x = 3, y = 4 } with the equals sign right\
1391 \ after the field name. So maybe you forgot a comma?"
1393 "I may be getting confused by your indentation. Is this supposed to be part of\
1394 \ a definition AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1395 \ the problem may be a bit before the equals sign. I need all definitions to\
1396 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1397 \ this new definition is indented a bit too much."
1403 region = toRegion row col
1404 name = getDefName context
1406 Report.Report "UNEXPECTED SYMBOL" region [] $
1407 Report.toCodeSnippet source region Nothing $
1410 "I was not expecting to run into the \"has type\" symbol here:"
1415 ["Maybe","you","want",D.green "::","instead?"
1416 ,"To","put","something","on","the","front","of","a","list?"
1419 "The single colon is reserved for type annotations and record types, but I think\
1420 \ I am parsing the definition of `" ++ Name.toChars name ++ "` right now."
1423 "I may be getting confused by your indentation. Is this supposed to be part of\
1424 \ a type annotation AFTER the `" ++ Name.toChars name ++ "` definition? If so,\
1425 \ the problem may be a bit before the \"has type\" symbol. I need all definitions to\
1426 \ be exactly aligned (with exactly the same indentation) so the problem may be that\
1427 \ this new definition is indented a bit too much."
1436toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
1437toIfReport source context if_ startRow startCol =
1439 IfSpace space row col ->
1440 toSpaceReport source space row col
1444 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1445 region = toRegion row col
1447 Report.Report "UNFINISHED IF" region [] $
1448 Report.toCodeSnippet source surroundings (Just region)
1451 "I was expecting to see more of this `if` expression, but I got stuck here:"
1454 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1460 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1461 region = toRegion row col
1463 Report.Report "UNFINISHED IF" region [] $
1464 Report.toCodeSnippet source surroundings (Just region)
1467 "I was expecting to see more of this `if` expression, but I got stuck here:"
1470 ["I","was","expecting","to","see","the",D.green "else","keyword","next."
1474 IfElseBranchStart row col ->
1476 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1477 region = toRegion row col
1479 Report.Report "UNFINISHED IF" region [] $
1480 Report.toCodeSnippet source surroundings (Just region)
1483 "I just saw the start of an `else` branch, but then I got stuck here:"
1486 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1489 IfCondition expr row col ->
1490 toExprReport source (InNode NCond startRow startCol context) expr row col
1492 IfThenBranch expr row col ->
1493 toExprReport source (InNode NThen startRow startCol context) expr row col
1495 IfElseBranch expr row col ->
1496 toExprReport source (InNode NElse startRow startCol context) expr row col
1498 IfIndentCondition row col ->
1500 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1501 region = toRegion row col
1503 Report.Report "UNFINISHED IF" region [] $
1504 Report.toCodeSnippet source surroundings (Just region)
1507 "I was expecting to see more of this `if` expression, but I got stuck here:"
1511 ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
1512 ,"that","evaluates","to","True","or","False."
1515 "I can be confused by indentation. Maybe something is not indented enough?"
1519 IfIndentThen row col ->
1521 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1522 region = toRegion row col
1524 Report.Report "UNFINISHED IF" region [] $
1525 Report.toCodeSnippet source surroundings (Just region)
1528 "I was expecting to see more of this `if` expression, but I got stuck here:"
1532 ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1535 "I can be confused by indentation. Maybe something is not indented enough?"
1539 IfIndentThenBranch row col ->
1541 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1542 region = toRegion row col
1544 Report.Report "UNFINISHED IF" region [] $
1545 Report.toCodeSnippet source surroundings (Just region)
1548 "I got stuck after the start of this `then` branch:"
1552 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1554 "I can be confused by indentation, so if the `then` branch is already\
1555 \ present, it may not be indented enough for me to recognize it."
1559 IfIndentElseBranch row col ->
1561 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1562 region = toRegion row col
1564 Report.Report "UNFINISHED IF" region [] $
1565 Report.toCodeSnippet source surroundings (Just region)
1568 "I got stuck after the start of this `else` branch:"
1572 "I was expecting to see an expression next. Maybe it is not filled in yet?"
1574 "I can be confused by indentation, so if the `else` branch is already\
1575 \ present, it may not be indented enough for me to recognize it."
1579 IfIndentElse row col ->
1581 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1582 region = toRegion row col
1584 Report.Report "UNFINISHED IF" region [] $
1585 Report.toCodeSnippet source surroundings (Just region)
1588 "I was expecting to see an `else` branch after this:"
1592 "I know what to do when the condition is `True`, but not when it is `False`."
1594 ["Add","an",D.green "else","branch","to","handle","that","scenario!"]
1603toRecordReport :: Code.Source -> Context -> Record -> Row -> Col -> Report.Report
1604toRecordReport source context record startRow startCol =
1606 RecordOpen row col ->
1608 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1609 region = toRegion row col
1611 Report.Report "UNFINISHED PARENTHESES" region [] $
1612 Report.toCodeSnippet source surroundings (Just region)
1615 "I was expecting to see a closing curly brace next, but I got stuck here:"
1618 [ D.fillSep ["Try","adding","a",D.dullyellow "}","to","see","if","that","helps?"]
1620 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1621 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1622 \ parenthesis?) that is confusing me."
1626 RecordEnd row col ->
1628 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1629 region = toRegion row col
1631 Report.Report "UNFINISHED PARENTHESES" region [] $
1632 Report.toCodeSnippet source surroundings (Just region)
1635 "I was expecting to see a closing curly brace next, but I got stuck here:"
1638 [ D.fillSep ["Try","adding","a",D.dullyellow "}","to","see","if","that","helps?"]
1640 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1641 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1642 \ parenthesis?) that is confusing me."
1646 RecordField row col ->
1648 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1649 region = toRegion row col
1651 Report.Report "UNFINISHED RECORD" region [] $
1652 Report.toCodeSnippet source surroundings (Just region)
1655 "I am partway through parsing a record, but I got stuck after that last comma:"
1657 addNoteForRecordError $
1659 "Trailing commas are not allowed in records, so I was expecting to see another\
1660 \ record field defined next. If you are done defining the record, the fix may\
1661 \ be to delete that last comma?"
1664 RecordEquals row col ->
1666 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1667 region = toRegion row col
1669 Report.Report "UNFINISHED RECORD" region [] $
1670 Report.toCodeSnippet source surroundings (Just region)
1673 "I am partway through parsing a record, but I got stuck here:"
1675 addNoteForRecordError $
1677 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
1678 ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
1682 RecordExpr expr row col ->
1683 toExprReport source (InNode NRecord startRow startCol context) expr row col
1685 RecordSpace space row col ->
1686 toSpaceReport source space row col
1688 RecordIndentOpen row col ->
1690 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1691 region = toRegion row col
1693 Report.Report "UNFINISHED RECORD" region [] $
1694 Report.toCodeSnippet source surroundings (Just region)
1697 "I just saw the opening curly brace of a record, but then I got stuck here:"
1699 addNoteForRecordIndentError $
1701 ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
1702 ,"Try","defining","some","fields","of","your","own?"
1706 RecordIndentEnd row col ->
1708 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1709 region = toRegion row col
1711 Report.Report "UNFINISHED RECORD" region [] $
1712 Report.toCodeSnippet source surroundings (Just region)
1715 "I was expecting to see a closing curly brace next:"
1717 addNoteForRecordIndentError $
1719 ["Try","putting","an",D.green "}","and","see","if","that","helps?"
1723 RecordIndentField row col ->
1725 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1726 region = toRegion row col
1728 Report.Report "UNFINISHED RECORD" region [] $
1729 Report.toCodeSnippet source surroundings (Just region)
1732 "I am partway through parsing a record, but I got stuck after that last comma:"
1734 addNoteForRecordError $
1736 "Trailing commas are not allowed in records, so the fix may be to\
1737 \ delete that last comma? Or maybe you were in the middle of defining\
1738 \ an additional field?"
1741 RecordIndentEquals row col ->
1743 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1744 region = toRegion row col
1746 Report.Report "UNFINISHED RECORD" region [] $
1747 Report.toCodeSnippet source surroundings (Just region)
1750 "I am partway through parsing a record. I just saw a record\
1751 \ field, so I was expecting to see an equals sign next:"
1753 addNoteForRecordIndentError $
1755 ["Try","putting","an",D.green "=","followed","by","an","expression?"
1759 RecordIndentExpr row col ->
1761 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1762 region = toRegion row col
1764 Report.Report "UNFINISHED RECORD" region [] $
1765 Report.toCodeSnippet source surroundings (Just region)
1768 "I am partway through parsing a record, and I was expecting to run into an expression next:"
1770 addNoteForRecordIndentError $
1772 ["Try","putting","something,","like"
1773 ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
1778addNoteForRecordError :: D.Doc -> D.Doc
1779addNoteForRecordError normalRecommendation =
1781 normalRecommendation
1784 "If you are trying to define a record across multiple lines, I recommend using this format:"
1785 , D.indent 4 $ D.vcat $
1786 [ "{ name = \"Alice\""
1792 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1793 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1794 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1798addNoteForRecordIndentError :: D.Doc -> D.Doc
1799addNoteForRecordIndentError normalRecommendation =
1801 normalRecommendation
1804 "I may be confused by indentation. For example, if you are trying to define\
1805 \ a record across multiple lines, I recommend using this format:"
1806 , D.indent 4 $ D.vcat $
1813 "Notice that nothing comes directly after a newline. Each line starts with some spaces. I\
1814 \ know this style can be jarring for people coming from C-like syntax, but folks generally\
1815 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
1823toTupleReport :: Code.Source -> Context -> Tuple -> Row -> Col -> Report.Report
1824toTupleReport source context tuple startRow startCol =
1826 TupleExpr expr row col ->
1827 toExprReport source (InNode NParens startRow startCol context) expr row col
1829 TupleSpace space row col ->
1830 toSpaceReport source space row col
1834 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1835 region = toRegion row col
1837 Report.Report "UNFINISHED PARENTHESES" region [] $
1838 Report.toCodeSnippet source surroundings (Just region)
1841 "I was expecting to see a closing parentheses next, but I got stuck here:"
1844 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps?"]
1846 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1847 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1848 \ square bracket?) that is confusing me."
1852 TupleOperatorClose row col ->
1854 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1855 region = toRegion row col
1857 Report.Report "UNFINISHED OPERATOR FUNCTION" region [] $
1858 Report.toCodeSnippet source surroundings (Just region)
1860 D.reflow "I was expecting a closing parenthesis here:"
1863 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
1865 "I think I am parsing an operator function right now, so I am expecting to see\
1866 \ something like (+) or (&&) where an operator is surrounded by parentheses with\
1871 TupleOperatorReserved operator row col ->
1873 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1874 region = toRegion row col
1876 Report.Report "UNEXPECTED SYMBOL" region [] $
1877 Report.toCodeSnippet source surroundings (Just region)
1880 "I ran into an unexpected symbol here:"
1884 OpDot -> ["Maybe","you","wanted","a","record","accessor","like",D.dullyellow ".x","or",D.dullyellow ".name","instead?"]
1885 OpPipe -> ["Try",D.dullyellow "(||)","instead?","To","turn","boolean","OR","into","a","function?"]
1886 OpArrow -> ["Maybe","you","wanted",D.dullyellow "(>)","or",D.dullyellow "(>=)","instead?"]
1887 OpEquals -> ["Try",D.dullyellow "(==)","instead?","To","make","a","function","that","checks","equality?"]
1888 OpHasType -> ["Try",D.dullyellow "(::)","instead?","To","add","values","to","the","front","of","lists?"]
1891 TupleIndentExpr1 row col ->
1893 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1894 region = toRegion row col
1896 Report.Report "UNFINISHED PARENTHESES" region [] $
1897 Report.toCodeSnippet source surroundings (Just region)
1900 "I just saw an open parenthesis, so I was expecting to see an expression next."
1904 ["Something","like",D.dullyellow "(4 + 5)","or"
1905 ,D.dullyellow "(String.reverse \"desserts\")" <> "."
1906 ,"Anything","where","you","are","putting","parentheses","around","normal","expressions."
1909 "I can get confused by indentation in cases like this, so\
1910 \ maybe you have an expression but it is not indented enough?"
1914 TupleIndentExprN row col ->
1916 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1917 region = toRegion row col
1919 Report.Report "UNFINISHED TUPLE" region [] $
1920 Report.toCodeSnippet source surroundings (Just region)
1923 "I think I am in the middle of parsing a tuple. I just saw a comma, so I was expecting to see expression next."
1927 ["A","tuple","looks","like",D.dullyellow "(3,4)","or"
1928 ,D.dullyellow "(\"Tom\",42)" <> ","
1929 ,"so","I","think","there","is","an","expression","missing","here?"
1932 "I can get confused by indentation in cases like this, so\
1933 \ maybe you have an expression but it is not indented enough?"
1937 TupleIndentEnd row col ->
1939 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1940 region = toRegion row col
1942 Report.Report "UNFINISHED PARENTHESES" region [] $
1943 Report.toCodeSnippet source surroundings (Just region)
1946 "I was expecting to see a closing parenthesis next:"
1949 [ D.fillSep ["Try","adding","a",D.dullyellow ")","to","see","if","that","helps!"]
1951 "I can get confused by indentation in cases like this, so\
1952 \ maybe you have a closing parenthesis but it is not indented enough?"
1957toListReport :: Code.Source -> Context -> List -> Row -> Col -> Report.Report
1958toListReport source context list startRow startCol =
1960 ListSpace space row col ->
1961 toSpaceReport source space row col
1965 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1966 region = toRegion row col
1968 Report.Report "UNFINISHED LIST" region [] $
1969 Report.toCodeSnippet source surroundings (Just region)
1972 "I was expecting to see a closing square bracket next, but I got stuck here:"
1975 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
1977 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
1978 \ unexpectedly. So there may be some other syntax trouble (like an extra\
1979 \ parenthesis?) that is confusing me."
1983 ListExpr expr row col ->
1987 surroundings = A.Region (A.Position startRow startCol) (A.Position r c)
1988 region = toRegion r c
1990 Report.Report "UNFINISHED LIST" region [] $
1991 Report.toCodeSnippet source surroundings (Just region)
1994 "I was expecting to see another list entry after that last comma:"
1998 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2000 "I recommend using the following format for lists that span multiple lines:"
2001 , D.indent 4 $ D.vcat $
2008 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2009 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2010 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2015 toExprReport source (InNode NList startRow startCol context) expr row col
2019 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2020 region = toRegion row col
2022 Report.Report "UNFINISHED LIST" region [] $
2023 Report.toCodeSnippet source surroundings (Just region)
2026 "I was expecting to see a closing square bracket next, but I got stuck here:"
2029 [ D.fillSep ["Try","adding","a",D.dullyellow "]","to","see","if","that","helps?"]
2031 "I can get stuck when I run into keywords, operators, parentheses, or brackets\
2032 \ unexpectedly. So there may be some other syntax trouble (like an extra\
2033 \ parenthesis?) that is confusing me."
2037 ListIndentOpen row col ->
2039 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2040 region = toRegion row col
2042 Report.Report "UNFINISHED LIST" region [] $
2043 Report.toCodeSnippet source surroundings (Just region)
2046 "I cannot find the end of this list:"
2050 ["You","could","change","it","to","something","like"
2051 ,D.dullyellow "[3,4,5]"
2053 ,D.dullyellow "[]" <> "."
2054 ,"Anything","where","there","is","an","open","and","close","square","brace,"
2055 ,"and","where","the","elements","of","the","list","are","separated","by","commas."
2058 "I may be confused by indentation. For example, if you are trying to define\
2059 \ a list across multiple lines, I recommend using this format:"
2060 , D.indent 4 $ D.vcat $
2067 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2068 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2069 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2073 ListIndentEnd row col ->
2075 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2076 region = toRegion row col
2078 Report.Report "UNFINISHED LIST" region [] $
2079 Report.toCodeSnippet source surroundings (Just region)
2082 "I cannot find the end of this list:"
2086 ["You","can","just","add","a","closing",D.dullyellow "]"
2087 ,"right","here,","and","I","will","be","all","set!"
2090 "I may be confused by indentation. For example, if you are trying to define\
2091 \ a list across multiple lines, I recommend using this format:"
2092 , D.indent 4 $ D.vcat $
2099 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2100 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2101 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2105 ListIndentExpr row col ->
2107 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2108 region = toRegion row col
2110 Report.Report "UNFINISHED LIST" region [] $
2111 Report.toCodeSnippet source surroundings (Just region)
2114 "I was expecting to see another list entry after this comma:"
2118 "Trailing commas are not allowed in lists, so the fix may be to delete the comma?"
2120 "I recommend using the following format for lists that span multiple lines:"
2121 , D.indent 4 $ D.vcat $
2128 "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
2129 \ This style can be jarring for people coming from C-like syntax, but folks generally\
2130 \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
2135toFuncReport :: Code.Source -> Context -> Func -> Row -> Col -> Report.Report
2136toFuncReport source context func startRow startCol =
2138 FuncSpace space row col ->
2139 toSpaceReport source space row col
2141 FuncArg pattern row col ->
2142 error "TODO FuncArg" pattern row col
2144 FuncBody expr row col ->
2145 toExprReport source (InNode NFunc startRow startCol context) expr row col
2147 FuncArrow row col ->
2149 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2150 region = toRegion row col
2152 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2153 Report.toCodeSnippet source surroundings (Just region)
2156 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2159 ["The","syntax","for","anonymous","functions","is"
2160 ,D.dullyellow "(\\x -> x + 1)"
2161 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2165 FuncIndentArg row col ->
2167 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2168 region = toRegion row col
2170 Report.Report "MISSING ARGUMENT" region [] $
2171 Report.toCodeSnippet source surroundings (Just region)
2174 "I just saw the beginning of an anonymous function, so I was expecting to see an argument next:"
2178 ["Something","like",D.dullyellow"x","or",D.dullyellow "name" <> "."
2179 ,"Anything","that","starts","with","a","lower","case","letter!"
2182 "The syntax for anonymous functions is (\\x -> x + 1) where the backslash\
2183 \ is meant to look a bit like a lambda if you squint. This visual pun seemed\
2184 \ like a better idea at the time!"
2188 FuncIndentArrow row col ->
2190 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2191 region = toRegion row col
2193 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2194 Report.toCodeSnippet source surroundings (Just region)
2197 "I just saw the beginning of an anonymous function, so I was expecting to see an arrow next:"
2201 ["The","syntax","for","anonymous","functions","is"
2202 ,D.dullyellow "(\\x -> x + 1)"
2203 ,"so","I","am","missing","the","arrow","and","the","body","of","the","function."
2206 "It is possible that I am confused about indetation! I generally recommend\
2207 \ switching to named functions if the definition cannot fit inline nicely, so\
2208 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2209 \ the whole thing out into a named function. Things tend to be clearer that way!"
2213 FuncIndentBody row col ->
2215 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
2216 region = toRegion row col
2218 Report.Report "UNFINISHED ANONYMOUS FUNCTION" region [] $
2219 Report.toCodeSnippet source surroundings (Just region)
2222 "I was expecting to see the body of your anonymous function next:"
2226 ["The","syntax","for","anonymous","functions","is"
2227 ,D.dullyellow "(\\x -> x + 1)"
2228 ,"so","I","am","missing","all","the","stuff","after","the","arrow!"
2231 "It is possible that I am confused about indetation! I generally recommend\
2232 \ switching to named functions if the definition cannot fit inline nicely, so\
2233 \ either (1) try to fit the whole anonymous function on one line or (2) break\
2234 \ the whole thing out into a named function. Things tend to be clearer that way!"
2243 CommentOnNothing region ->
2244 Report.Report "STRAY COMMENT" region [] $
2245 Report.toCodeSnippet source region Nothing
2247 "This documentation comment is not followed by anything."
2250 "All documentation comments need to be right above the declaration they\
2251 \ describe. Maybe some code got deleted or commented out by accident? Or\
2252 \ maybe this comment is here by accident?"
2255 UnexpectedPort region ->
2256 Report.Report "UNEXPECTED PORTS" region [] $
2257 Report.toCodeSnippet source region Nothing
2260 "You are declaring ports in a normal module."
2264 ["Switch","this","to","say",D.green "port module","instead,"
2265 ,"marking","that","this","module","contains","port","declarations."
2268 "Ports are not a traditional FFI for calling JS functions directly. They need a different mindset! Read"
2270 "to learn the syntax and how to use it effectively."
2275 Report.Report "NO PORTS" region [] $
2276 Report.toCodeSnippet source region Nothing
2279 "This module does not declare any ports, but it says it will:"
2282 ["Switch","this","to",D.green "module"
2283 ,"and","you","should","be","all","set!"
2287 ParseError row col context expectation ->
2289 pos = A.Position row col
2290 region = A.Region pos pos
2295 Report.Report "EXPECTING DOC COMMENT" region [] $
2296 Report.toCodeSnippet source region Nothing
2299 "I was expecting a doc comment here:"
2302 "Check out" "TODO" "for examples of doc comments."
2308 Report.Report "EXPECTING PRECEDENCE" region [] $
2309 Report.toCodeSnippet source region Nothing
2312 "I was expecting the precedence here:"
2315 "I need a single digit between 0 and 9 inclusive."
2319 Report.Report "EXPECTING A WILDCARD" region [] $
2320 Report.toCodeSnippet source region Nothing
2323 "I was expecting a _ here:"
2326 "An underscore indicates that “I do not care about this value” and is\
2327 \ called a wildcard pattern because it will match with any type of values."
2330 WildcardNotVar startCol endCol ->
2333 A.Region (A.Position row startCol) (A.Position row endCol)
2335 Report.Report "INVALID PATTERN" badRegion [] $
2336 Report.toCodeSnippet source badRegion Nothing
2339 "I was expecting to see an underscore without any additional characters:"
2342 "There are two options. Either (1) remove the extra characters and ignore the\
2343 \ value or (2) remove the starting underscore to give the value a normal name."
2349 Report.Report "INVALID PATTERN" region [] $
2350 Report.toCodeSnippet source region Nothing
2353 "I cannot pattern match with floating point numbers:"
2356 "Equality on floats can be unreliable, so you usually want to check that they\
2357 \ are nearby with some sort of (abs (actual - expected) < 0.001) check."
2362 MatchingName name ->
2363 Report.Report "EXPECTING A DEFINITION" region [] $
2364 Report.toCodeSnippet source region Nothing
2367 "I just saw the type annotation for `" ++ Name.toChars name
2368 ++ "` so I was expecting to see its definition here:"
2371 "Type annotations always appear directly above the relevant\
2372 \ definition, without anything else (even doc comments) in between."
2378 TypeWithBadDefinition region annName defName ->
2379 Report.Report "ANNOTATION MISMATCH" region [] $
2380 Report.toCodeSnippet source region Nothing
2383 "I see a `" <> Name.toChars annName
2384 <> "` annotation, but it is followed by a `"
2385 <> Name.toChars defName <> "` definition."
2388 ["The","annotation","and","definition","names","must","match!"
2389 ,"Is","there","a","typo","between"
2390 , D.dullyellow (D.fromName annName)
2392 , 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