@@ -69,6 +69,9 @@ data Error
6969 | ModuleNameMismatch ModuleName.Raw (A.Located ModuleName.Raw)
7070 | UnexpectedPort A.Region
7171 | NoPorts A.Region
72+ | NoPortsInPackage (A.Located Name.Name)
73+ | NoPortModulesInPackage A.Region
74+ | NoEffectsOutsideKernel A.Region
7275 | ParseError Module
7376
7477
@@ -561,10 +564,84 @@ toReport source err =
561564 ]
562565 )
563566
567+ NoPortsInPackage (A.At region _) ->
568+ Report.Report "PACKAGES CANNOT HAVE PORTS" region [] $
569+ Code.toSnippet source region Nothing
570+ (
571+ D.reflow $
572+ "Packages cannot declare any ports, so I am getting stuck here:"
573+ ,
574+ D.stack
575+ [ D.reflow $
576+ "Remove this port declaration."
577+ , noteForPortsInPackage
578+ ]
579+ )
580+
581+ NoPortModulesInPackage region ->
582+ Report.Report "PACKAGES CANNOT HAVE PORTS" region [] $
583+ Code.toSnippet source region Nothing
584+ (
585+ D.reflow $
586+ "Packages cannot declare any ports, so I am getting stuck here:"
587+ ,
588+ D.stack
589+ [ D.fillSep $
590+ ["Remove","the",D.cyan "port","keyword","and","I"
591+ ,"should","be","able","to","continue."
592+ ]
593+ , noteForPortsInPackage
594+ ]
595+ )
596+
597+ NoEffectsOutsideKernel region ->
598+ Report.Report "INVALID EFFECT MODULE" region [] $
599+ Code.toSnippet source region Nothing
600+ (
601+ D.reflow $
602+ "It is not possible to declare an `effect module` outside the @elm organization,\
603+ \ so I am getting stuck here:"
604+ ,
605+ D.stack
606+ [ D.reflow $
607+ "Switch to a normal module declaration."
608+ , D.toSimpleNote $
609+ "Effect modules are designed to allow certain core functionality to be\
610+ \ defined separately from the compiler. So the @elm organization has access to\
611+ \ this so that certain changes, extensions, and fixes can be introduced without\
612+ \ needing to release new Elm binaries. For example, we want to make it possible\
613+ \ to test effects, but this may require changes to the design of effect modules.\
614+ \ By only having them defined in the @elm organization, that kind of design work\
615+ \ can proceed much more smoothly."
616+ ]
617+ )
618+
564619 ParseError modul ->
565620 toParseErrorReport source modul
566621
567622
623+noteForPortsInPackage :: D.Doc
624+noteForPortsInPackage =
625+ D.stack
626+ [ D.toSimpleNote $
627+ "One of the major goals of the package ecosystem is to be completely written\
628+ \ in Elm. This means when you install an Elm package, you can be sure you are safe\
629+ \ from security issues on install and that you are not going to get any runtime\
630+ \ exceptions coming from your new dependency. This design also sets the ecosystem\
631+ \ up to target other platforms more easily (like mobile phones, WebAssembly, etc.)\
632+ \ since no community code explicitly depends on JavaScript even existing."
633+ , D.reflow $
634+ "Given that overall goal, allowing ports in packages would lead to some pretty\
635+ \ surprising behavior. If ports were allowed in packages, you could install a\
636+ \ package but not realize that it brings in an indirect dependency that defines a\
637+ \ port. Now you have a program that does not work and the fix is to realize that\
638+ \ some JavaScript needs to be added for a dependency you did not even know about.\
639+ \ That would be extremely frustrating! \"So why not allow the package author to\
640+ \ include the necessary JS code as well?\" Now we are back in conflict with our\
641+ \ overall goal to keep all community packages free from runtime exceptions."
642+ ]
643+
644+
568645toParseErrorReport :: Code.Source -> Module -> Report.Report
569646toParseErrorReport source modul =
570647 case modul of
@@ -572,156 +649,9 @@ toParseErrorReport source modul =
572649 toSpaceReport source space row col
573650
574651 ModuleBadEnd row col ->
575− case Code.whatIsNext source row col of
576− Code.Keyword keyword ->
577− let
578− region = toKeywordRegion row col keyword
579− in
580− Report.Report "RESERVED WORD" region [] $
581− Code.toSnippet source region Nothing
582− (
583− D.reflow $
584− "I got stuck on this reserved word:"
585− ,
586− D.reflow $
587− "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
588− )
589−
590− Code.Operator op ->
591− let
592− region = toKeywordRegion row col op
593− in
594− Report.Report "UNEXPECTED SYMBOL" region [] $
595− Code.toSnippet source region Nothing
596− (
597− D.reflow $
598− "I ran into an unexpected symbol:"
599− ,
600− D.reflow $
601− "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
602− \ I can give a better hint from there?"
603− )
604−
605− Code.Close term bracket ->
606− let
607− region = toRegion row col
608− in
609− Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
610− Code.toSnippet source region Nothing
611− (
612− D.reflow $
613− "I ran into an unexpected " ++ term ++ ":"
614− ,
615− D.reflow $
616− "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
617− )
618−
619− Code.Other maybeChar ->
620− let
621− region = toRegion row col
622− in
623− case maybeChar of
624− Just ';' ->
625− Report.Report "UNEXPECTED SEMICOLON" region [] $
626− Code.toSnippet source region Nothing
627− (
628− D.reflow $
629− "I got stuck on this semicolon:"
630− ,
631− D.stack
632− [ D.reflow $ "Try removing it?"
633− , D.toSimpleNote $
634− "Some languages require semicolons at the end of each statement. These are\
635− \ often called C-like languages, and they usually share a lot of language design\
636− \ choices. (E.g. side-effects, for loops, etc.) Elm manages effects with commands\
637− \ and subscriptions instead, so there is no special syntax for \"statements\" and\
638− \ therefore no need to use semicolons to separate them. I think this will make\
639− \ more sense as you work through <https://guide.elm-lang.org> though!"
640− ]
641− )
642−
643− Just ',' ->
644− Report.Report "UNEXPECTED COMMA" region [] $
645− Code.toSnippet source region Nothing
646− (
647− D.reflow $
648− "I got stuck on this comma:"
649− ,
650− D.stack
651− [ D.reflow $
652− "I do not think I am parsing a list or tuple right now. Try deleting the comma?"
653− , D.toSimpleNote $
654− "If this is supposed to be part of a list, the problem may be a bit earlier.\
655− \ Perhaps the opening [ is missing? Or perhaps some value in the list has an extra\
656− \ closing ] that is making me think the list ended earlier? The same kinds of\
657− \ things could be going wrong if this is supposed to be a tuple."
658− ]
659− )
660−
661− Just '`' ->
662− Report.Report "UNEXPECTED CHARACTER" region [] $
663− Code.toSnippet source region Nothing
664− (
665− D.reflow $
666− "I got stuck on this character:"
667− ,
668− D.stack
669− [ D.reflow $
670− "It is not used for anything in Elm syntax. It is used for multi-line strings in\
671− \ some languages though, so if you want a string that spans multiple lines, you\
672− \ can use Elm's multi-line string syntax like this:"
673− , D.vcat
674− [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
675− , mempty
676− , D.dullyellow "# Multi-line Strings"
677− , mempty
678− , D.dullyellow "- start with triple double quotes"
679− , D.dullyellow "- write whatever you want"
680− , D.dullyellow "- no need to escape newlines or double quotes"
681− , D.dullyellow "- end with triple double quotes"
682− , mempty
683− , D.dullyellow "\"\"\""
684− ]
685− , D.reflow $
686− "Otherwise I do not know what is going on! Try removing the character?"
687− ]
688− )
689−
690− Just '$' ->
691− Report.Report "UNEXPECTED SYMBOL" region [] $
692− Code.toSnippet source region Nothing
693− (
694− D.reflow $
695− "I got stuck on this dollar sign:"
696− ,
697− D.reflow $
698− "It is not used for anything in Elm syntax. Are you coming from a language where\
699− \ dollar signs can be used in variable names? If so, try a name that (1) starts\
700− \ with a letter and (2) only contains letters, numbers, and underscores."
701− )
702−
703− Just c | elem c ['#','@','!','%','~'] ->
704− Report.Report "UNEXPECTED SYMBOL" region [] $
705− Code.toSnippet source region Nothing
706− (
707− D.reflow $
708− "I got stuck on this symbol:"
709− ,
710− D.reflow $
711− "It is not used for anything in Elm syntax. Try removing it?"
712− )
713−
714− _ ->
715− Report.Report "SYNTAX PROBLEM" region [] $
716− Code.toSnippet source region Nothing
717− (
718− D.reflow $
719− "I got stuck here:"
720− ,
721− D.reflow $
722− "Whatever I am running into is confusing me a lot! Normally I can give fairly\
723− \ specific hints, but something is really tripping me up this time."
724− )
652+ if col == 1
653+ then toDeclStartReport source row col
654+ else toWeirdEndReport source row col
725655
726656 ModuleProblem row col ->
727657 let
@@ -867,11 +797,11 @@ toParseErrorReport source modul =
867797 [ D.reflow $
868798 "I am not sure what is going on, but I recommend starting an Elm\
869799 \ file with the following lines:"
870− , D.vcat
800+ , D.indent 4 $ D.vcat $
871801 [ D.fillSep [D.cyan "import","Html"]
872802 , ""
873− , D.fillSep [D.green "main","="]
874− , D.indent 2 $ D.fillSep [D.cyan "Html" <> ".text",D.dullyellow "\"Hello!\""]
803+ , "main ="
804+ , " Html.text " <> D.dullyellow "\"Hello!\""
875805 ]
876806 , D.reflow $
877807 "You should be able to copy those lines directly into your file. Check out the\
@@ -900,11 +830,12 @@ toParseErrorReport source modul =
900830 , D.indent 4 $ D.vcat $
901831 [ D.fillSep [D.cyan "import","Dict"]
902832 , D.fillSep [D.cyan "import","Maybe"]
903− , D.fillSep [D.cyan "import","Html.Attributes"]
904− , D.fillSep [D.cyan "import","Json.Decode"]
833+ , D.fillSep [D.cyan "import","Html.Attributes",D.cyan "as","A"]
834+ , D.fillSep [D.cyan "import","Json.Decode",D.cyan "exposing","(..)"]
905835 ]
906836 , D.reflow $
907837 "Notice that the module names all start with capital letters. That is required!"
838+ , D.reflowLink "Read" "imports" "to learn more."
908839 ]
909840 )
910841
@@ -931,6 +862,7 @@ toParseErrorReport source modul =
931862 ]
932863 , D.reflow $
933864 "Notice that the alias always starts with a capital letter. That is required!"
865+ , D.reflowLink "Read" "imports" "to learn more."
934866 ]
935867 )
936868
@@ -993,6 +925,192 @@ toParseErrorReport source modul =
993925
994926
995927
928+-- WEIRD END
929+
930+
931+toWeirdEndReport :: Code.Source -> Row -> Col -> Report.Report
932+toWeirdEndReport source row col =
933+ case Code.whatIsNext source row col of
934+ Code.Keyword keyword ->
935+ let
936+ region = toKeywordRegion row col keyword
937+ in
938+ Report.Report "RESERVED WORD" region [] $
939+ Code.toSnippet source region Nothing
940+ (
941+ D.reflow $
942+ "I got stuck on this reserved word:"
943+ ,
944+ D.reflow $
945+ "The name `" ++ keyword ++ "` is reserved, so try using a different name?"
946+ )
947+
948+ Code.Operator op ->
949+ let
950+ region = toKeywordRegion row col op
951+ in
952+ Report.Report "UNEXPECTED SYMBOL" region [] $
953+ Code.toSnippet source region Nothing
954+ (
955+ D.reflow $
956+ "I ran into an unexpected symbol:"
957+ ,
958+ D.reflow $
959+ "I was not expecting to see a " ++ op ++ " here. Try deleting it? Maybe\
960+ \ I can give a better hint from there?"
961+ )
962+
963+ Code.Close term bracket ->
964+ let
965+ region = toRegion row col
966+ in
967+ Report.Report ("UNEXPECTED " ++ map Char.toUpper term) region [] $
968+ Code.toSnippet source region Nothing
969+ (
970+ D.reflow $
971+ "I ran into an unexpected " ++ term ++ ":"
972+ ,
973+ D.reflow $
974+ "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
975+ )
976+
977+ Code.Lower c cs ->
978+ let
979+ region = toKeywordRegion row col (c:cs)
980+ in
981+ Report.Report "UNEXPECTED NAME" region [] $
982+ Code.toSnippet source region Nothing
983+ (
984+ D.reflow $
985+ "I got stuck on this name:"
986+ ,
987+ D.reflow $
988+ "It is confusing me a lot! Normally I can give fairly specific hints, but\
989+ \ something is really tripping me up this time."
990+ )
991+
992+ Code.Upper c cs ->
993+ let
994+ region = toKeywordRegion row col (c:cs)
995+ in
996+ Report.Report "UNEXPECTED NAME" region [] $
997+ Code.toSnippet source region Nothing
998+ (
999+ D.reflow $
1000+ "I got stuck on this name:"
1001+ ,
1002+ D.reflow $
1003+ "It is confusing me a lot! Normally I can give fairly specific hints, but\
1004+ \ something is really tripping me up this time."
1005+ )
1006+
1007+ Code.Other maybeChar ->
1008+ let
1009+ region = toRegion row col
1010+ in
1011+ case maybeChar of
1012+ Just ';' ->
1013+ Report.Report "UNEXPECTED SEMICOLON" region [] $
1014+ Code.toSnippet source region Nothing
1015+ (
1016+ D.reflow $
1017+ "I got stuck on this semicolon:"
1018+ ,
1019+ D.stack
1020+ [ D.reflow $ "Try removing it?"
1021+ , D.toSimpleNote $
1022+ "Some languages require semicolons at the end of each statement. These are\
1023+ \ often called C-like languages, and they usually share a lot of language design\
1024+ \ choices. (E.g. side-effects, for loops, etc.) Elm manages effects with commands\
1025+ \ and subscriptions instead, so there is no special syntax for \"statements\" and\
1026+ \ therefore no need to use semicolons to separate them. I think this will make\
1027+ \ more sense as you work through <https://guide.elm-lang.org> though!"
1028+ ]
1029+ )
1030+
1031+ Just ',' ->
1032+ Report.Report "UNEXPECTED COMMA" region [] $
1033+ Code.toSnippet source region Nothing
1034+ (
1035+ D.reflow $
1036+ "I got stuck on this comma:"
1037+ ,
1038+ D.stack
1039+ [ D.reflow $
1040+ "I do not think I am parsing a list or tuple right now. Try deleting the comma?"
1041+ , D.toSimpleNote $
1042+ "If this is supposed to be part of a list, the problem may be a bit earlier.\
1043+ \ Perhaps the opening [ is missing? Or perhaps some value in the list has an extra\
1044+ \ closing ] that is making me think the list ended earlier? The same kinds of\
1045+ \ things could be going wrong if this is supposed to be a tuple."
1046+ ]
1047+ )
1048+
1049+ Just '`' ->
1050+ Report.Report "UNEXPECTED CHARACTER" region [] $
1051+ Code.toSnippet source region Nothing
1052+ (
1053+ D.reflow $
1054+ "I got stuck on this character:"
1055+ ,
1056+ D.stack
1057+ [ D.reflow $
1058+ "It is not used for anything in Elm syntax. It is used for multi-line strings in\
1059+ \ some languages though, so if you want a string that spans multiple lines, you\
1060+ \ can use Elm's multi-line string syntax like this:"
1061+ , D.dullyellow $ D.indent 4 $ D.vcat $
1062+ [ "\"\"\""
1063+ , "# Multi-line Strings"
1064+ , ""
1065+ , "- start with triple double quotes"
1066+ , "- write whatever you want"
1067+ , "- no need to escape newlines or double quotes"
1068+ , "- end with triple double quotes"
1069+ , "\"\"\""
1070+ ]
1071+ , D.reflow $
1072+ "Otherwise I do not know what is going on! Try removing the character?"
1073+ ]
1074+ )
1075+
1076+ Just '$' ->
1077+ Report.Report "UNEXPECTED SYMBOL" region [] $
1078+ Code.toSnippet source region Nothing
1079+ (
1080+ D.reflow $
1081+ "I got stuck on this dollar sign:"
1082+ ,
1083+ D.reflow $
1084+ "It is not used for anything in Elm syntax. Are you coming from a language where\
1085+ \ dollar signs can be used in variable names? If so, try a name that (1) starts\
1086+ \ with a letter and (2) only contains letters, numbers, and underscores."
1087+ )
1088+
1089+ Just c | elem c ['#','@','!','%','~'] ->
1090+ Report.Report "UNEXPECTED SYMBOL" region [] $
1091+ Code.toSnippet source region Nothing
1092+ (
1093+ D.reflow $
1094+ "I got stuck on this symbol:"
1095+ ,
1096+ D.reflow $
1097+ "It is not used for anything in Elm syntax. Try removing it?"
1098+ )
1099+
1100+ _ ->
1101+ Report.Report "SYNTAX PROBLEM" region [] $
1102+ Code.toSnippet source region Nothing
1103+ (
1104+ D.reflow $
1105+ "I got stuck here:"
1106+ ,
1107+ D.reflow $
1108+ "Whatever I am running into is confusing me a lot! Normally I can give fairly\
1109+ \ specific hints, but something is really tripping me up this time."
1110+ )
1111+
1112+
1113+
9961114-- IMPORTS
9971115
9981116
@@ -1018,6 +1136,7 @@ toImportReport source row col =
10181136 ]
10191137 , D.reflow $
10201138 "You are probably trying to import a different module, but try to make it look like one of these examples!"
1139+ , D.reflowLink "Read" "imports" "to learn more."
10211140 ]
10221141 )
10231142
@@ -1324,114 +1443,7 @@ toDeclarationsReport :: Code.Source -> Decl -> Report.Report
13241443toDeclarationsReport source decl =
13251444 case decl of
13261445 DeclStart row col ->
1327− case Code.whatIsNext source row col of
1328− Code.Close term bracket ->
1329− let
1330− region = toRegion row col
1331− in
1332− Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1333− Code.toSnippet source region Nothing
1334− (
1335− D.reflow $
1336− "I was not expecting to see a " ++ term ++ " here:"
1337− , D.reflow $
1338− "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1339− )
1340−
1341− Code.Keyword keyword ->
1342− let
1343− region = toKeywordRegion row col keyword
1344− in
1345− Report.Report "RESERVED WORD" region [] $
1346− Code.toSnippet source region Nothing
1347− (
1348− D.reflow $
1349− "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1350− ,
1351− case keyword of
1352− "import" ->
1353− D.reflow $
1354− "It is reserved for declaring imports at the top of your module. If you want\
1355− \ another import, try moving it up top with the other imports. If you want to\
1356− \ define a value or function, try changing the name to something else!"
1357−
1358− "case" ->
1359− D.stack
1360− [ D.reflow $
1361− "It is reserved for writing `case` expressions. Try using a different name?"
1362− , D.toSimpleNote $
1363− "If you are trying to write a `case` expression, it needs to be part of a\
1364− \ definition. So you could write something like this instead:"
1365− , D.vcat $
1366− [ D.indent 0 $ D.fillSep [D.green "getWidth","maybeWidth","="]
1367− , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1368− , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1369− , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1370− , ""
1371− , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1372− , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1373− ]
1374− , D.reflow $
1375− "This defines a `getWidth` function that we can use elsewhere in our program."
1376− ]
1377−
1378− "if" ->
1379− D.stack
1380− [ D.reflow $
1381− "It is reserved for writing `if` expressions. Try using a different name?"
1382− , D.toSimpleNote $
1383− "If you are trying to write an `if` expression, it needs to be part of a\
1384− \ definition. So you could write something like this instead:"
1385− , D.vcat $
1386− [ D.indent 0 $ D.fillSep [D.green "reviewPowerLevel","powerLevel","="]
1387− , D.indent 2 $ D.fillSep $
1388− [D.cyan "if","powerLevel",">",D.dullyellow "9000"
1389− ,D.cyan "then",D.dullyellow "\"OVER 9000!!!\""
1390− ,D.cyan "else",D.dullyellow "\"not bad\""
1391− ]
1392− ]
1393− , D.reflow $
1394− "This defines a `reviewPowerLevel` function that we can use elsewhere in our program."
1395− ]
1396−
1397− _ ->
1398− D.reflow $
1399− "It is a reserved word. Try changing the name to something else?"
1400− )
1401−
1402− _ ->
1403− let
1404− region = toRegion row col
1405− in
1406− Report.Report "SYNTAX PROBLEM" region [] $
1407− Code.toSnippet source region Nothing
1408− (
1409− D.reflow $
1410− "I was expecting to see a declaration, but I am getting stuck here:"
1411− ,
1412− D.stack
1413− [ case Code.whatIsNext source row col of
1414− Code.Other (Just char) | Char.isUpper char ->
1415− D.reflow $
1416− "All declarations start with lower-case letters in Elm, so maybe this letter can\
1417− \ be changed to lower-case?"
1418−
1419− _ ->
1420− D.reflow $
1421− "Declarations normally start with a lower-case name or the `type` keyword."
1422− , D.toSimpleHint $
1423− "Here are a couple valid declarations for reference:"
1424− , D.vcat
1425− [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
1426− , D.fillSep [D.green "add","x","y","="]
1427− , D.fillSep [" ","x","+","y"]
1428− ]
1429− , D.fillSep [D.cyan "type",D.green "User","=","Anonymous","|","LoggedIn String"]
1430− , D.reflow $
1431− "Notice that these declarations start with lower-case letters. Capitalization\
1432− \ makes a difference in Elm!"
1433− ]
1434− )
1446+ toDeclStartReport source row col
14351447
14361448 DeclSpace space row col ->
14371449 toSpaceReport source space row col
@@ -1445,21 +1457,180 @@ toDeclarationsReport source decl =
14451457 DeclDef name declDef row col ->
14461458 toDeclDefReport source name declDef row col
14471459
1448− DeclFreshLineAfterDocComment row col ->
1460+ DeclFreshLineAfterDocComment row col ->
1461+ let
1462+ region = toRegion row col
1463+ in
1464+ Report.Report "EXPECTING DECLARATION" region [] $
1465+ Code.toSnippet source region Nothing
1466+ (
1467+ D.reflow $
1468+ "I just saw a doc comment, but then I got stuck here:"
1469+ ,
1470+ D.reflow $
1471+ "I was expecting to see the corresponding declaration next, starting on a fresh\
1472+ \ line with no indentation."
1473+ )
1474+
1475+
1476+toDeclStartReport :: Code.Source -> Row -> Col -> Report.Report
1477+toDeclStartReport source row col =
1478+ case Code.whatIsNext source row col of
1479+ Code.Close term bracket ->
1480+ let
1481+ region = toRegion row col
1482+ in
1483+ Report.Report ("STRAY " ++ map Char.toUpper term) region [] $
1484+ Code.toSnippet source region Nothing
1485+ (
1486+ D.reflow $
1487+ "I was not expecting to see a " ++ term ++ " here:"
1488+ , D.reflow $
1489+ "This " ++ bracket : " does not match up with an earlier open " ++ term ++ ". Try deleting it?"
1490+ )
1491+
1492+ Code.Keyword keyword ->
1493+ let
1494+ region = toKeywordRegion row col keyword
1495+ in
1496+ Report.Report "RESERVED WORD" region [] $
1497+ Code.toSnippet source region Nothing
1498+ (
1499+ D.reflow $
1500+ "I was not expecting to run into the `" ++ keyword ++ "` keyword here:"
1501+ ,
1502+ case keyword of
1503+ "import" ->
1504+ D.reflow $
1505+ "It is reserved for declaring imports at the top of your module. If you want\
1506+ \ another import, try moving it up top with the other imports. If you want to\
1507+ \ define a value or function, try changing the name to something else!"
1508+
1509+ "case" ->
1510+ D.stack
1511+ [ D.reflow $
1512+ "It is reserved for writing `case` expressions. Try using a different name?"
1513+ , D.toSimpleNote $
1514+ "If you are trying to write a `case` expression, it needs to be part of a\
1515+ \ definition. So you could write something like this instead:"
1516+ , D.indent 4 $ D.vcat $
1517+ [ D.indent 0 $ D.fillSep ["getWidth","maybeWidth","="]
1518+ , D.indent 2 $ D.fillSep [D.cyan "case","maybeWidth",D.cyan "of"]
1519+ , D.indent 4 $ D.fillSep [D.blue "Just","width","->"]
1520+ , D.indent 6 $ D.fillSep ["width","+",D.dullyellow "200"]
1521+ , ""
1522+ , D.indent 4 $ D.fillSep [D.blue "Nothing","->"]
1523+ , D.indent 6 $ D.fillSep [D.dullyellow "400"]
1524+ ]
1525+ , D.reflow $
1526+ "This defines a `getWidth` function that you can use elsewhere in your program."
1527+ ]
1528+
1529+ "if" ->
1530+ D.stack
1531+ [ D.reflow $
1532+ "It is reserved for writing `if` expressions. Try using a different name?"
1533+ , D.toSimpleNote $
1534+ "If you are trying to write an `if` expression, it needs to be part of a\
1535+ \ definition. So you could write something like this instead:"
1536+ , D.indent 4 $ D.vcat $
1537+ [ "greet name ="
1538+ , D.fillSep $
1539+ [" "
1540+ ,D.cyan "if","name","==",D.dullyellow "\"Abraham Lincoln\""
1541+ ,D.cyan "then",D.dullyellow "\"Greetings Mr. President.\""
1542+ ,D.cyan "else",D.dullyellow "\"Hey!\""
1543+ ]
1544+ ]
1545+ , D.reflow $
1546+ "This defines a `reviewPowerLevel` function that you can use elsewhere in your program."
1547+ ]
1548+
1549+ _ ->
1550+ D.reflow $
1551+ "It is a reserved word. Try changing the name to something else?"
1552+ )
1553+
1554+ Code.Upper c cs ->
1555+ let
1556+ region = toRegion row col
1557+ in
1558+ Report.Report "UNEXPECTED CAPITAL LETTER" region [] $
1559+ Code.toSnippet source region Nothing
1560+ (
1561+ D.reflow $
1562+ "Declarations always start with a lower-case letter, so I am getting stuck here:"
1563+ ,
1564+ D.stack
1565+ [ D.fillSep $
1566+ ["Try","a","name","like"
1567+ ,D.green (D.fromChars (Char.toLower c : cs))
1568+ ,"instead?"
1569+ ]
1570+ , D.toSimpleNote $
1571+ "Here are a couple valid declarations for reference:"
1572+ , D.indent 4 $ D.vcat $
1573+ [ "greet : String -> String"
1574+ , "greet name ="
1575+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1576+ , ""
1577+ , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1578+ ]
1579+ , D.reflow $
1580+ "Notice that they always start with a lower-case letter. Capitalization matters!"
1581+ ]
1582+ )
1583+
1584+ Code.Other (Just char) | elem char ['(', '{', '[', '+', '-', '*', '/', '^', '&', '|', '"', '\'', '!', '@', '#', '$', '%'] ->
14491585 let
14501586 region = toRegion row col
14511587 in
1452− Report.Report "EXPECTING DECLARATION" region [] $
1588+ Report.Report "UNEXPECTED SYMBOL" region [] $
14531589 Code.toSnippet source region Nothing
14541590 (
14551591 D.reflow $
1456− "I just saw a doc comment, but then I got stuck here:"
1592+ "I am getting stuck because this line starts with the " ++ [char] ++ " symbol:"
14571593 ,
1458− D.reflow $
1459− "I was expecting to see the corresponding declaration next, starting on a fresh\
1460− \ line with no indentation."
1594+ D.stack
1595+ [ D.reflow $
1596+ "When a line has no spaces at the beginning, I expect it to be a declaration like one of these:"
1597+ , D.indent 4 $ D.vcat $
1598+ [ "greet : String -> String"
1599+ , "greet name ="
1600+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1601+ , ""
1602+ , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1603+ ]
1604+ , D.reflow $
1605+ "If this is not supposed to be a declaration, try adding some spaces before it?"
1606+ ]
14611607 )
14621608
1609+ _ ->
1610+ let
1611+ region = toRegion row col
1612+ in
1613+ Report.Report "WEIRD DECLARATION" region [] $
1614+ Code.toSnippet source region Nothing
1615+ (
1616+ D.reflow $
1617+ "I am trying to parse a declaration, but I am getting stuck here:"
1618+ ,
1619+ D.stack
1620+ [ D.reflow $
1621+ "When a line has no spaces at the beginning, I expect it to be a declaration like one of these:"
1622+ , D.indent 4 $ D.vcat $
1623+ [ "greet : String -> String"
1624+ , "greet name ="
1625+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
1626+ , ""
1627+ , D.cyan "type" <> " User = Anonymous | LoggedIn String"
1628+ ]
1629+ , D.reflow $
1630+ "Try to make your declaration look like one of those? Or if this is not\
1631+ \ supposed to be a declaration, try adding some spaces before it?"
1632+ ]
1633+ )
14631634
14641635
14651636-- PORT
@@ -1587,7 +1758,7 @@ toPortReport source port_ startRow startCol =
15871758 [ D.reflow $
15881759 "I was expecting to see a type next. Here are examples of outgoing and\
15891760 \ incoming ports for reference:"
1590− , D.vcat
1761+ , D.indent 4 $ D.vcat $
15911762 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
15921763 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
15931764 ]
@@ -1606,7 +1777,7 @@ portNote =
16061777 D.stack
16071778 [ D.toSimpleNote $
16081779 "Here are some example `port` declarations for reference:"
1609− , D.vcat
1780+ , D.indent 4 $ D.vcat $
16101781 [ D.fillSep [D.cyan "port","send",":","String -> Cmd msg"]
16111782 , D.fillSep [D.cyan "port","receive",":","(String -> msg) -> Sub msg"]
16121783 ]
@@ -1789,8 +1960,8 @@ typeAliasNote =
17891960 [ D.toSimpleNote $
17901961 "Here is an example of a valid `type alias` for reference:"
17911962 , D.vcat $
1792− [ D.indent 0 $ D.fillSep [D.cyan "type",D.cyan "alias",D.green "Person","="]
1793− , D.indent 2 $ D.vcat $
1963+ [ D.indent 4 $ D.fillSep [D.cyan "type",D.cyan "alias","Person","="]
1964+ , D.indent 6 $ D.vcat $
17941965 ["{ name : String"
17951966 ,", age : Int"
17961967 ,", height : Float"
@@ -1990,10 +2161,10 @@ customTypeNote =
19902161 [ D.toSimpleNote $
19912162 "Here is an example of a valid `type` declaration for reference:"
19922163 , D.vcat $
1993− [ D.indent 0 $ D.fillSep [D.cyan "type",D.green "Status"]
1994− , D.indent 2 $ D.fillSep ["=","Failure"]
1995− , D.indent 2 $ D.fillSep ["|","Waiting"]
1996− , D.indent 2 $ D.fillSep ["|","Success","String"]
2164+ [ D.indent 4 $ D.fillSep [D.cyan "type","Status"]
2165+ , D.indent 6 $ D.fillSep ["=","Failure"]
2166+ , D.indent 6 $ D.fillSep ["|","Waiting"]
2167+ , D.indent 6 $ D.fillSep ["|","Success","String"]
19972168 ]
19982169 , D.reflow $
19992170 "This defines a new `Status` type with three variants. This could be useful if\
@@ -2065,10 +2236,10 @@ toDeclDefReport source name declDef startRow startCol =
20652236 ,"a","type","annotation.","It","could","be","something","else","though,","so"
20662237 ,"here","is","a","valid","definition","for","reference:"
20672238 ]
2068− , D.vcat
2069− [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2070− , D.fillSep [D.green "add","x","y","="]
2071− , D.fillSep [" ","x","+","y"]
2239+ , D.indent 4 $ D.vcat $
2240+ [ "greet : String -> String"
2241+ , "greet name ="
2242+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
20722243 ]
20732244 , D.reflow $
20742245 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -2090,10 +2261,10 @@ toDeclDefReport source name declDef startRow startCol =
20902261 [ D.reflow $
20912262 "I am not sure what is going wrong exactly, so here is a valid\
20922263 \ definition (with an optional type annotation) for reference:"
2093− , D.vcat
2094− [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2095− , D.fillSep [D.green "add","x","y","="]
2096− , D.fillSep [" ","x","+","y"]
2264+ , D.indent 4 $ D.vcat $
2265+ [ "greet : String -> String"
2266+ , "greet name ="
2267+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
20972268 ]
20982269 , D.reflow $
20992270 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -2115,10 +2286,10 @@ toDeclDefReport source name declDef startRow startCol =
21152286 [ D.reflow $
21162287 "I am not sure what is going wrong exactly, so here is a valid\
21172288 \ definition (with an optional type annotation) for reference:"
2118− , D.vcat
2119− [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2120− , D.fillSep [D.green "add","x","y","="]
2121− , D.fillSep [" ","x","+","y"]
2289+ , D.indent 4 $ D.vcat $
2290+ [ "greet : String -> String"
2291+ , "greet name ="
2292+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
21222293 ]
21232294 , D.reflow $
21242295 "Try to use that format!"
@@ -2233,10 +2404,10 @@ declDefNote =
22332404 D.stack
22342405 [ D.reflow $
22352406 "Here is a valid definition (with a type annotation) for reference:"
2236− , D.vcat
2237− [ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
2238− , D.fillSep [D.green "add","x","y","="]
2239− , D.fillSep [" ","x","+","y"]
2407+ , D.indent 4 $ D.vcat $
2408+ [ "greet : String -> String"
2409+ , "greet name ="
2410+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
22402411 ]
22412412 , D.reflow $
22422413 "The top line (called a \"type annotation\") is optional. You can leave it off\
@@ -2420,7 +2591,7 @@ toExprReport source context expr startRow startCol =
24202591 ,"give","a","more","specific","hint!"
24212592 ]
24222593 , D.toSimpleNote $
2423− "This can also happen if run into reserved words like `let` or `as` unexpectedly.\
2594+ "This can also happen if I run into reserved words like `let` or `as` unexpectedly.\
24242595 \ Or if I run into operators in unexpected spots. Point is, there are a\
24252596 \ couple ways I can get confused and give sort of weird advice!"
24262597 ]
@@ -2569,17 +2740,15 @@ toStringReport source string row col =
25692740 , D.toSimpleNote $
25702741 "For a string that spans multiple lines, you can use the multi-line string\
25712742 \ syntax like this:"
2572− , D.vcat
2573− [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2574− , mempty
2575− , D.dullyellow "# Multi-line Strings"
2576− , mempty
2577− , D.dullyellow "- start with triple double quotes"
2578− , D.dullyellow "- write whatever you want"
2579− , D.dullyellow "- no need to escape newlines or double quotes"
2580− , D.dullyellow "- end with triple double quotes"
2581− , mempty
2582− , D.dullyellow "\"\"\""
2743+ , D.dullyellow $ D.indent 4 $ D.vcat $
2744+ [ "\"\"\""
2745+ , "# Multi-line Strings"
2746+ , ""
2747+ , "- start with triple double quotes"
2748+ , "- write whatever you want"
2749+ , "- no need to escape newlines or double quotes"
2750+ , "- end with triple double quotes"
2751+ , "\"\"\""
25832752 ]
25842753 ]
25852754 )
@@ -2598,17 +2767,15 @@ toStringReport source string row col =
25982767 [ D.reflow "Add a \"\"\" somewhere after this to end the string."
25992768 , D.toSimpleNote $
26002769 "Here is a valid multi-line string for reference:"
2601− , D.vcat
2602− [ D.fillSep [D.green "markdown","=",D.dullyellow "\"\"\""]
2603− , mempty
2604− , D.dullyellow "# Multi-line Strings"
2605− , mempty
2606− , D.dullyellow "- start with triple double quotes"
2607− , D.dullyellow "- write whatever you want"
2608− , D.dullyellow "- no need to escape newlines or double quotes"
2609− , D.dullyellow "- end with triple double quotes"
2610− , mempty
2611− , D.dullyellow "\"\"\""
2770+ , D.dullyellow $ D.indent 4 $ D.vcat $
2771+ [ "\"\"\""
2772+ , "# Multi-line Strings"
2773+ , ""
2774+ , "- start with triple double quotes"
2775+ , "- write whatever you want"
2776+ , "- no need to escape newlines or double quotes"
2777+ , "- end with triple double quotes"
2778+ , "\"\"\""
26122779 ]
26132780 ]
26142781 )
@@ -2875,7 +3042,7 @@ toOperatorReport source context operator row col =
28753042 \Maybe it was supposed to be a > sign instead?"
28763043 , D.toSimpleNote $
28773044 "The syntax for anonymous functions is (\\x -> x + 1) so the arguments all appear\
2878− \ after the backslash and before the arrow. Maybe you forgot the backslash earlier?"
3045+ \ after the backslash and before the arrow. Maybe a backslash is missing earlier?"
28793046 ]
28803047 )
28813048
@@ -3073,8 +3240,8 @@ toUnfinishLetReport source row col startRow startCol message =
30733240 [ message
30743241 , D.toSimpleNote $
30753242 "Here is an example with a valid `let` expression for reference:"
3076− , D.vcat $
3077− [ D.indent 0 $ D.fillSep [D.green "viewPerson","person","="]
3243+ , D.indent 4 $ D.vcat $
3244+ [ D.indent 0 $ D.fillSep ["viewPerson","person","="]
30783245 , D.indent 2 $ D.fillSep [D.cyan "let"]
30793246 , D.indent 4 $ D.fillSep ["fullName","="]
30803247 , D.indent 6 $ D.fillSep ["person.firstName","++",D.dullyellow "\" \"","++","person.lastName"]
@@ -3192,10 +3359,10 @@ toLetDefReport source name def startRow startCol =
31923359 ,"a","type","annotation.","It","could","be","something","else","though,","so"
31933360 ,"here","is","a","valid","definition","for","reference:"
31943361 ]
3195− , D.vcat
3196− [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3197− , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3198− , D.indent 6 $ D.fillSep ["x","+","y"]
3362+ , D.indent 4 $ D.vcat $
3363+ [ "greet : String -> String"
3364+ , "greet name ="
3365+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
31993366 ]
32003367 , D.reflow $
32013368 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -3217,10 +3384,10 @@ toLetDefReport source name def startRow startCol =
32173384 [ D.reflow $
32183385 "I am not sure what is going wrong exactly, so here is a valid\
32193386 \ definition (with an optional type annotation) for reference:"
3220− , D.vcat
3221− [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3222− , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3223− , D.indent 6 $ D.fillSep ["x","+","y"]
3387+ , D.indent 4 $ D.vcat $
3388+ [ "greet : String -> String"
3389+ , "greet name ="
3390+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
32243391 ]
32253392 , D.reflow $
32263393 "Try to use that format with your `" ++ Name.toChars name ++ "` definition!"
@@ -3242,10 +3409,10 @@ toLetDefReport source name def startRow startCol =
32423409 [ D.reflow $
32433410 "I am not sure what is going wrong exactly, so here is a valid\
32443411 \ definition (with an optional type annotation) for reference:"
3245− , D.vcat
3246− [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3247− , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3248− , D.indent 4 $ D.fillSep ["x","+","y"]
3412+ , D.indent 4 $ D.vcat $
3413+ [ "greet : String -> String"
3414+ , "greet name ="
3415+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
32493416 ]
32503417 , D.reflow $
32513418 "Try to use that format!"
@@ -3335,10 +3502,10 @@ defNote =
33353502 D.stack
33363503 [ D.reflow $
33373504 "Here is a valid definition (with a type annotation) for reference:"
3338− , D.vcat
3339− [ D.indent 4 $ D.fillSep [D.green "add",":","Int","->","Int","->","Int"]
3340− , D.indent 4 $ D.fillSep [D.green "add","x","y","="]
3341− , D.indent 6 $ D.fillSep ["x","+","y"]
3505+ , D.indent 4 $ D.vcat $
3506+ [ "greet : String -> String"
3507+ , "greet name ="
3508+ , " " <> D.dullyellow "\"Hello \"" <> " ++ name ++ " <> D.dullyellow "\"!\""
33423509 ]
33433510 , D.reflow $
33443511 "The top line (called a \"type annotation\") is optional. You can leave it off\
@@ -3820,15 +3987,22 @@ toRecordReport source context record startRow startCol =
38203987 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
38213988 region = toRegion row col
38223989 in
3823− Report.Report "UNFINISHED RECORD" region [] $
3990+ Report.Report "PROBLEM IN RECORD" region [] $
38243991 Code.toSnippet source surroundings (Just region)
38253992 (
38263993 D.reflow $
38273994 "I just started parsing a record, but I got stuck here:"
38283995 ,
3829− D.fillSep
3830− ["Records","look","like",D.dullyellow "{ x = 3, y = 4 },"
3831− ,"so","I","was","expecting","to","see","a","field","name","next."
3996+ D.stack
3997+ [ D.fillSep
3998+ ["I","was","expecting","to","see","a","record","field","defined","next,"
3999+ ,"so","I","am","looking","for","a","name","like"
4000+ ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
4001+ ]
4002+ , D.toSimpleNote $
4003+ "Field names must start with a lower-case letter. After that, you can use\
4004+ \ any sequence of letters, numbers, and underscores."
4005+ , noteForRecordError
38324006 ]
38334007 )
38344008
@@ -3837,7 +4011,7 @@ toRecordReport source context record startRow startCol =
38374011 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
38384012 region = toRegion row col
38394013 in
3840− Report.Report "UNFINISHED RECORD" region [] $
4014+ Report.Report "PROBLEM IN RECORD" region [] $
38414015 Code.toSnippet source surroundings (Just region)
38424016 (
38434017 D.reflow $
@@ -3872,22 +4046,67 @@ toRecordReport source context record startRow startCol =
38724046 \ that is a reserved word. Try using a different name!"
38734047 )
38744048
4049+ Code.Other (Just ',') ->
4050+ let
4051+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4052+ region = toRegion row col
4053+ in
4054+ Report.Report "EXTRA COMMA" region [] $
4055+ Code.toSnippet source surroundings (Just region)
4056+ (
4057+ D.reflow $
4058+ "I am partway through parsing a record, but I got stuck here:"
4059+ ,
4060+ D.stack
4061+ [ D.reflow $
4062+ "I am seeing two commas in a row. This is the second one!"
4063+ , D.reflow $
4064+ "Just delete one of the commas and you should be all set!"
4065+ , noteForRecordError
4066+ ]
4067+ )
4068+
4069+ Code.Close _ '}' ->
4070+ let
4071+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4072+ region = toRegion row col
4073+ in
4074+ Report.Report "EXTRA COMMA" region [] $
4075+ Code.toSnippet source surroundings (Just region)
4076+ (
4077+ D.reflow $
4078+ "I am partway through parsing a record, but I got stuck here:"
4079+ ,
4080+ D.stack
4081+ [ D.reflow $
4082+ "Trailing commas are not allowed in records. Try deleting the comma that appears\
4083+ \ before this closing curly brace."
4084+ , noteForRecordError
4085+ ]
4086+ )
4087+
38754088 _ ->
38764089 let
38774090 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
38784091 region = toRegion row col
38794092 in
3880− Report.Report "UNFINISHED RECORD" region [] $
4093+ Report.Report "PROBLEM IN RECORD" region [] $
38814094 Code.toSnippet source surroundings (Just region)
38824095 (
38834096 D.reflow $
3884− "I am partway through parsing a record, but I got stuck after that last comma:"
4097+ "I am partway through parsing a record, but I got stuck here:"
38854098 ,
3886− addNoteForRecordError $
3887− D.reflow $
3888− "Trailing commas are not allowed in records, so I was expecting to see another\
3889− \ record field defined next. If you are done defining the record, the fix may\
3890− \ be to delete that last comma?"
4099+ D.stack
4100+ [ D.fillSep
4101+ ["I","was","expecting","to","see","another","record","field","defined","next,"
4102+ ,"so","I","am","looking","for","a","name","like"
4103+ ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
4104+ ]
4105+ , D.toSimpleNote $
4106+ "Field names must start with a lower-case letter. After that, you can use\
4107+ \ any sequence of letters, numbers, and underscores."
4108+ , noteForRecordError
4109+ ]
38914110 )
38924111
38934112 RecordEquals row col ->
@@ -3895,17 +4114,19 @@ toRecordReport source context record startRow startCol =
38954114 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
38964115 region = toRegion row col
38974116 in
3898− Report.Report "UNFINISHED RECORD" region [] $
4117+ Report.Report "PROBLEM IN RECORD" region [] $
38994118 Code.toSnippet source surroundings (Just region)
39004119 (
39014120 D.reflow $
39024121 "I am partway through parsing a record, but I got stuck here:"
39034122 ,
3904− addNoteForRecordError $
3905− D.fillSep $
3906− ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
3907− ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
3908− ]
4123+ D.stack
4124+ [ D.fillSep $
4125+ ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
4126+ ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
4127+ ]
4128+ , noteForRecordError
4129+ ]
39094130 )
39104131
39114132 RecordExpr expr row col ->
@@ -3925,29 +4146,54 @@ toRecordReport source context record startRow startCol =
39254146 D.reflow $
39264147 "I just saw the opening curly brace of a record, but then I got stuck here:"
39274148 ,
3928− addNoteForRecordIndentError $
3929− D.fillSep $
3930− ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
3931− ,"Try","defining","some","fields","of","your","own?"
3932− ]
4149+ D.stack
4150+ [ D.fillSep $
4151+ ["I","am","expecting","a","record","like",D.dullyellow "{ x = 3, y = 4 }","here."
4152+ ,"Try","defining","some","fields","of","your","own?"
4153+ ]
4154+ , noteForRecordIndentError
4155+ ]
39334156 )
39344157
39354158 RecordIndentEnd row col ->
3936− let
3937− surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
3938− region = toRegion row col
3939− in
3940− Report.Report "UNFINISHED RECORD" region [] $
3941− Code.toSnippet source surroundings (Just region)
3942− (
3943− D.reflow $
3944− "I was expecting to see a closing curly brace next:"
3945− ,
3946− addNoteForRecordIndentError $
3947− D.fillSep $
3948− ["Try","putting","an",D.green "}","and","see","if","that","helps?"
3949− ]
3950− )
4159+ case Code.nextLineStartsWithCloseCurly source row of
4160+ Just (curlyRow, curlyCol) ->
4161+ let
4162+ surroundings = A.Region (A.Position startRow startCol) (A.Position curlyRow curlyCol)
4163+ region = toRegion curlyRow curlyCol
4164+ in
4165+ Report.Report "NEED MORE INDENTATION" region [] $
4166+ Code.toSnippet source surroundings (Just region)
4167+ (
4168+ D.reflow $
4169+ "I was partway through parsing a record, but I got stuck here:"
4170+ ,
4171+ D.stack
4172+ [ D.reflow $
4173+ "I need this curly brace to be indented more. Try adding some spaces before it!"
4174+ , noteForRecordError
4175+ ]
4176+ )
4177+
4178+ Nothing ->
4179+ let
4180+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
4181+ region = toRegion row col
4182+ in
4183+ Report.Report "UNFINISHED RECORD" region [] $
4184+ Code.toSnippet source surroundings (Just region)
4185+ (
4186+ D.reflow $
4187+ "I was partway through parsing a record, but I got stuck here:"
4188+ ,
4189+ D.stack
4190+ [ D.fillSep $
4191+ ["I","was","expecting","to","see","a","closing","curly","brace","next."
4192+ ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
4193+ ]
4194+ , noteForRecordIndentError
4195+ ]
4196+ )
39514197
39524198 RecordIndentField row col ->
39534199 let
@@ -3960,11 +4206,13 @@ toRecordReport source context record startRow startCol =
39604206 D.reflow $
39614207 "I am partway through parsing a record, but I got stuck after that last comma:"
39624208 ,
3963− addNoteForRecordError $
3964− D.reflow $
3965− "Trailing commas are not allowed in records, so the fix may be to\
3966− \ delete that last comma? Or maybe you were in the middle of defining\
3967− \ an additional field?"
4209+ D.stack
4210+ [ D.reflow $
4211+ "Trailing commas are not allowed in records, so the fix may be to\
4212+ \ delete that last comma? Or maybe you were in the middle of defining\
4213+ \ an additional field?"
4214+ , noteForRecordError
4215+ ]
39684216 )
39694217
39704218 RecordIndentEquals row col ->
@@ -3979,10 +4227,12 @@ toRecordReport source context record startRow startCol =
39794227 "I am partway through parsing a record. I just saw a record\
39804228 \ field, so I was expecting to see an equals sign next:"
39814229 ,
3982− addNoteForRecordIndentError $
3983− D.fillSep $
3984− ["Try","putting","an",D.green "=","followed","by","an","expression?"
3985− ]
4230+ D.stack
4231+ [ D.fillSep $
4232+ ["Try","putting","an",D.green "=","followed","by","an","expression?"
4233+ ]
4234+ , noteForRecordIndentError
4235+ ]
39864236 )
39874237
39884238 RecordIndentExpr row col ->
@@ -3996,52 +4246,48 @@ toRecordReport source context record startRow startCol =
39964246 D.reflow $
39974247 "I am partway through parsing a record, and I was expecting to run into an expression next:"
39984248 ,
3999− addNoteForRecordIndentError $
4000− D.fillSep $
4001− ["Try","putting","something","like"
4002− ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
4003− ]
4249+ D.stack
4250+ [ D.fillSep $
4251+ ["Try","putting","something","like"
4252+ ,D.dullyellow "42","or",D.dullyellow"\"hello\"","for","now?"
4253+ ]
4254+ , noteForRecordIndentError
4255+ ]
40044256 )
40054257
40064258
4007−addNoteForRecordError :: D.Doc -> D.Doc
4008−addNoteForRecordError normalRecommendation =
4259+noteForRecordError :: D.Doc
4260+noteForRecordError =
40094261 D.stack $
4010− normalRecommendation
4011− :
40124262 [ D.toSimpleNote
40134263 "If you are trying to define a record across multiple lines, I recommend using this format:"
40144264 , D.indent 4 $ D.vcat $
4015− [ "{ name = \"Alice\""
4016− , ", age = 42"
4017− , ", height = 1.75"
4265+ [ "{ name = " <> D.dullyellow "\"Alice\""
4266+ , ", age = " <> D.dullyellow "42"
4267+ , ", height = " <> D.dullyellow "1.75"
40184268 , "}"
40194269 ]
40204270 , D.reflow $
4021− "Notice that each line starts with some indentation. Usually two or four spaces. I\
4022− \ know this style can be jarring for people coming from C-like syntax, but folks generally\
4023− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4271+ "Notice that each line starts with some indentation. Usually two or four spaces.\
4272+ \ This is the stylistic convention in the Elm ecosystem."
40244273 ]
40254274
40264275
4027−addNoteForRecordIndentError :: D.Doc -> D.Doc
4028−addNoteForRecordIndentError normalRecommendation =
4029− D.stack $
4030− normalRecommendation
4031− :
4276+noteForRecordIndentError :: D.Doc
4277+noteForRecordIndentError =
4278+ D.stack
40324279 [ D.toSimpleNote
40334280 "I may be confused by indentation. For example, if you are trying to define\
40344281 \ a record across multiple lines, I recommend using this format:"
40354282 , D.indent 4 $ D.vcat $
4036− [ "{ name = \"Alice\""
4037− , ", age = 42"
4038− , ", height = 1.75"
4283+ [ "{ name = " <> D.dullyellow "\"Alice\""
4284+ , ", age = " <> D.dullyellow "42"
4285+ , ", height = " <> D.dullyellow "1.75"
40394286 , "}"
40404287 ]
40414288 , D.reflow $
4042− "Notice that each line starts with some indentation. Usually two or four spaces. I\
4043− \ know this style can be jarring for people coming from C-like syntax, but folks generally\
4044− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4289+ "Notice that each line starts with some indentation. Usually two or four spaces.\
4290+ \ This is the stylistic convention in the Elm ecosystem!"
40454291 ]
40464292
40474293
@@ -4230,15 +4476,14 @@ toListReport source context list startRow startCol =
42304476 , D.toSimpleNote
42314477 "I recommend using the following format for lists that span multiple lines:"
42324478 , D.indent 4 $ D.vcat $
4233− [ "[ \"Alice\""
4234− , ", \"Bob\""
4235− , ", \"Chuck\""
4479+ [ "[ " <> D.dullyellow "\"Alice\""
4480+ , ", " <> D.dullyellow "\"Bob\""
4481+ , ", " <> D.dullyellow "\"Chuck\""
42364482 , "]"
42374483 ]
42384484 , D.reflow $
4239− "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4240− \ This style can be jarring for people coming from C-like syntax, but folks generally\
4241− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4485+ "Notice that each line starts with some indentation. Usually two or four spaces.\
4486+ \ This is the stylistic convention in the Elm ecosystem."
42424487 ]
42434488 )
42444489
@@ -4291,15 +4536,14 @@ toListReport source context list startRow startCol =
42914536 "I may be confused by indentation. For example, if you are trying to define\
42924537 \ a list across multiple lines, I recommend using this format:"
42934538 , D.indent 4 $ D.vcat $
4294− [ "[ \"Alice\""
4295− , ", \"Bob\""
4296− , ", \"Chuck\""
4539+ [ "[ " <> D.dullyellow "\"Alice\""
4540+ , ", " <> D.dullyellow "\"Bob\""
4541+ , ", " <> D.dullyellow "\"Chuck\""
42974542 , "]"
42984543 ]
42994544 , D.reflow $
4300− "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4301− \ This style can be jarring for people coming from C-like syntax, but folks generally\
4302− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4545+ "Notice that each line starts with some indentation. Usually two or four spaces.\
4546+ \ This is the stylistic convention in the Elm ecosystem."
43034547 ]
43044548 )
43054549
@@ -4323,15 +4567,14 @@ toListReport source context list startRow startCol =
43234567 "I may be confused by indentation. For example, if you are trying to define\
43244568 \ a list across multiple lines, I recommend using this format:"
43254569 , D.indent 4 $ D.vcat $
4326− [ "[ \"Alice\""
4327− , ", \"Bob\""
4328− , ", \"Chuck\""
4570+ [ "[ " <> D.dullyellow "\"Alice\""
4571+ , ", " <> D.dullyellow "\"Bob\""
4572+ , ", " <> D.dullyellow "\"Chuck\""
43294573 , "]"
43304574 ]
43314575 , D.reflow $
4332− "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4333− \ This style can be jarring for people coming from C-like syntax, but folks generally\
4334− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4576+ "Notice that each line starts with some indentation. Usually two or four spaces.\
4577+ \ This is the stylistic convention in the Elm ecosystem."
43354578 ]
43364579 )
43374580
@@ -4352,15 +4595,14 @@ toListReport source context list startRow startCol =
43524595 , D.toSimpleNote
43534596 "I recommend using the following format for lists that span multiple lines:"
43544597 , D.indent 4 $ D.vcat $
4355− [ "[ \"Alice\""
4356− , ", \"Bob\""
4357− , ", \"Chuck\""
4598+ [ "[ " <> D.dullyellow "\"Alice\""
4599+ , ", " <> D.dullyellow "\"Bob\""
4600+ , ", " <> D.dullyellow "\"Chuck\""
43584601 , "]"
43594602 ]
43604603 , D.reflow $
4361− "Notice that nothing comes directly after a newline. Each line starts with some spaces.\
4362− \ This style can be jarring for people coming from C-like syntax, but folks generally\
4363− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
4604+ "Notice that each line starts with some indentation. Usually two or four spaces.\
4605+ \ This is the stylistic convention in the Elm ecosystem."
43644606 ]
43654607 )
43664608
@@ -5233,22 +5475,64 @@ toTRecordReport source context record startRow startCol =
52335475 \ that is a reserved word. Try using a different name!"
52345476 )
52355477
5478+ Code.Other (Just ',') ->
5479+ let
5480+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5481+ region = toRegion row col
5482+ in
5483+ Report.Report "EXTRA COMMA" region [] $
5484+ Code.toSnippet source surroundings (Just region)
5485+ (
5486+ D.reflow $
5487+ "I am partway through parsing a record type, but I got stuck here:"
5488+ ,
5489+ D.stack
5490+ [ D.reflow $
5491+ "I am seeing two commas in a row. This is the second one!"
5492+ , D.reflow $
5493+ "Just delete one of the commas and you should be all set!"
5494+ , noteForRecordTypeError
5495+ ]
5496+ )
5497+
5498+ Code.Close _ '}' ->
5499+ let
5500+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5501+ region = toRegion row col
5502+ in
5503+ Report.Report "EXTRA COMMA" region [] $
5504+ Code.toSnippet source surroundings (Just region)
5505+ (
5506+ D.reflow $
5507+ "I am partway through parsing a record type, but I got stuck here:"
5508+ ,
5509+ D.stack
5510+ [ D.reflow $
5511+ "Trailing commas are not allowed in record types. Try deleting the comma that\
5512+ \ appears before this closing curly brace."
5513+ , noteForRecordTypeError
5514+ ]
5515+ )
5516+
52365517 _ ->
52375518 let
52385519 surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
52395520 region = toRegion row col
52405521 in
5241− Report.Report "UNFINISHED RECORD TYPE" region [] $
5522+ Report.Report "PROBLEM IN RECORD TYPE" region [] $
52425523 Code.toSnippet source surroundings (Just region)
52435524 (
52445525 D.reflow $
5245− "I am partway through parsing a record type, but I got stuck after that last comma:"
5526+ "I am partway through parsing a record type, but I got stuck here:"
52465527 ,
5247− addNoteForRecordTypeError $
5248− D.reflow $
5249− "Trailing commas are not allowed in records, so I was expecting to see another\
5250− \ record field defined next. If you are done defining the record, the fix may\
5251− \ be to delete that last comma?"
5528+ D.stack
5529+ [ D.fillSep
5530+ ["I","was","expecting","to","see","another","record","field","defined","next,"
5531+ ,"so","I","am","looking","for","a","name","like"
5532+ ,D.dullyellow "userName","or",D.dullyellow "plantHeight" <> "."
5533+ ]
5534+ , noteForRecordTypeError
5535+ ]
52525536 )
52535537
52545538 TRecordColon row col ->
@@ -5262,11 +5546,13 @@ toTRecordReport source context record startRow startCol =
52625546 D.reflow $
52635547 "I am partway through parsing a record type, but I got stuck here:"
52645548 ,
5265− addNoteForRecordTypeError $
5266− D.fillSep $
5267− ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
5268− ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
5269− ]
5549+ D.stack
5550+ [ D.fillSep $
5551+ ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
5552+ ,"a","colon","next.","So","try","putting","an",D.green ":","sign","here?"
5553+ ]
5554+ , noteForRecordTypeError
5555+ ]
52705556 )
52715557
52725558 TRecordType tipe row col ->
@@ -5286,29 +5572,54 @@ toTRecordReport source context record startRow startCol =
52865572 D.reflow $
52875573 "I just saw the opening curly brace of a record type, but then I got stuck here:"
52885574 ,
5289− addNoteForRecordTypeIndentError $
5290− D.fillSep $
5291− ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
5292− ,"Try","defining","some","fields","of","your","own?"
5293− ]
5575+ D.stack
5576+ [ D.fillSep $
5577+ ["I","am","expecting","a","record","like",D.dullyellow "{ name : String, age : Int }","here."
5578+ ,"Try","defining","some","fields","of","your","own?"
5579+ ]
5580+ , noteForRecordTypeIndentError
5581+ ]
52945582 )
52955583
52965584 TRecordIndentEnd row col ->
5297− let
5298− surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5299− region = toRegion row col
5300− in
5301− Report.Report "UNFINISHED RECORD TYPE" region [] $
5302− Code.toSnippet source surroundings (Just region)
5303− (
5304− D.reflow $
5305− "I was expecting to see a closing curly brace next:"
5306− ,
5307− addNoteForRecordTypeIndentError $
5308− D.fillSep $
5309− ["Try","putting","an",D.green "}","and","see","if","that","helps?"
5310− ]
5311− )
5585+ case Code.nextLineStartsWithCloseCurly source row of
5586+ Just (curlyRow, curlyCol) ->
5587+ let
5588+ surroundings = A.Region (A.Position startRow startCol) (A.Position curlyRow curlyCol)
5589+ region = toRegion curlyRow curlyCol
5590+ in
5591+ Report.Report "NEED MORE INDENTATION" region [] $
5592+ Code.toSnippet source surroundings (Just region)
5593+ (
5594+ D.reflow $
5595+ "I was partway through parsing a record type, but I got stuck here:"
5596+ ,
5597+ D.stack
5598+ [ D.reflow $
5599+ "I need this curly brace to be indented more. Try adding some spaces before it!"
5600+ , noteForRecordTypeError
5601+ ]
5602+ )
5603+
5604+ Nothing ->
5605+ let
5606+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
5607+ region = toRegion row col
5608+ in
5609+ Report.Report "UNFINISHED RECORD TYPE" region [] $
5610+ Code.toSnippet source surroundings (Just region)
5611+ (
5612+ D.reflow $
5613+ "I was partway through parsing a record type, but I got stuck here:"
5614+ ,
5615+ D.stack
5616+ [ D.fillSep $
5617+ ["I","was","expecting","to","see","a","closing","curly","brace","next."
5618+ ,"Try","putting","a",D.green "}","next","and","see","if","that","helps?"
5619+ ]
5620+ , noteForRecordTypeIndentError
5621+ ]
5622+ )
53125623
53135624 TRecordIndentField row col ->
53145625 let
@@ -5321,11 +5632,13 @@ toTRecordReport source context record startRow startCol =
53215632 D.reflow $
53225633 "I am partway through parsing a record type, but I got stuck after that last comma:"
53235634 ,
5324− addNoteForRecordTypeIndentError $
5325− D.reflow $
5326− "Trailing commas are not allowed in record types, so the fix may be to\
5327− \ delete that last comma? Or maybe you were in the middle of defining\
5328− \ an additional field?"
5635+ D.stack
5636+ [ D.reflow $
5637+ "Trailing commas are not allowed in record types, so the fix may be to\
5638+ \ delete that last comma? Or maybe you were in the middle of defining\
5639+ \ an additional field?"
5640+ , noteForRecordTypeIndentError
5641+ ]
53295642 )
53305643
53315644 TRecordIndentColon row col ->
@@ -5340,10 +5653,12 @@ toTRecordReport source context record startRow startCol =
53405653 "I am partway through parsing a record type. I just saw a record\
53415654 \ field, so I was expecting to see a colon next:"
53425655 ,
5343− addNoteForRecordTypeIndentError $
5344− D.fillSep $
5345− ["Try","putting","an",D.green ":","followed","by","a","type?"
5346− ]
5656+ D.stack
5657+ [ D.fillSep $
5658+ ["Try","putting","an",D.green ":","followed","by","a","type?"
5659+ ]
5660+ , noteForRecordTypeIndentError
5661+ ]
53475662 )
53485663
53495664 TRecordIndentType row col ->
@@ -5357,19 +5672,19 @@ toTRecordReport source context record startRow startCol =
53575672 D.reflow $
53585673 "I am partway through parsing a record type, and I was expecting to run into a type next:"
53595674 ,
5360− addNoteForRecordTypeIndentError $
5361− D.fillSep $
5362− ["Try","putting","something","like"
5363− ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5364− ]
5675+ D.stack
5676+ [ D.fillSep $
5677+ ["Try","putting","something","like"
5678+ ,D.dullyellow "Int","or",D.dullyellow "String","for","now?"
5679+ ]
5680+ , noteForRecordTypeIndentError
5681+ ]
53655682 )
53665683
53675684
5368−addNoteForRecordTypeError :: D.Doc -> D.Doc
5369−addNoteForRecordTypeError normalRecommendation =
5685+noteForRecordTypeError :: D.Doc
5686+noteForRecordTypeError =
53705687 D.stack $
5371− normalRecommendation
5372− :
53735688 [ D.toSimpleNote
53745689 "If you are trying to define a record type across multiple lines, I recommend using this format:"
53755690 , D.indent 4 $ D.vcat $
@@ -5379,17 +5694,14 @@ addNoteForRecordTypeError normalRecommendation =
53795694 , "}"
53805695 ]
53815696 , D.reflow $
5382− "Notice that each line starts with some indentation. Usually two or four spaces. I\
5383− \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5384− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5697+ "Notice that each line starts with some indentation. Usually two or four spaces.\
5698+ \ This is the stylistic convention in the Elm ecosystem."
53855699 ]
53865700
53875701
5388−addNoteForRecordTypeIndentError :: D.Doc -> D.Doc
5389−addNoteForRecordTypeIndentError normalRecommendation =
5702+noteForRecordTypeIndentError :: D.Doc
5703+noteForRecordTypeIndentError =
53905704 D.stack $
5391− normalRecommendation
5392− :
53935705 [ D.toSimpleNote
53945706 "I may be confused by indentation. For example, if you are trying to define\
53955707 \ a record type across multiple lines, I recommend using this format:"
@@ -5400,9 +5712,8 @@ addNoteForRecordTypeIndentError normalRecommendation =
54005712 , "}"
54015713 ]
54025714 , D.reflow $
5403− "Notice that each line starts with some indentation. Usually two or four spaces. I\
5404− \ know this style can be jarring for people coming from C-like syntax, but folks generally\
5405− \ report that they are used to it (and often prefer it!) after a week or two of using Elm."
5715+ "Notice that each line starts with some indentation. Usually two or four spaces.\
5716+ \ This is the stylistic convention in the Elm ecosystem."
54065717 ]
54075718
54085719