@@ -801,6 +801,10 @@ data Node
801801 | NParens
802802 | NList
803803 | NFunc
804+ | NCond
805+ | NThen
806+ | NElse
807+ deriving (Eq)
804808
805809
806810getDefName :: Context -> Name.Name
@@ -810,6 +814,13 @@ getDefName context =
810814 InNode _ _ _ c -> getDefName c
811815
812816
817+isWithin :: Node -> Context -> Bool
818+isWithin desiredNode context =
819+ case context of
820+ InDef _ _ _ -> False
821+ InNode actualNode _ _ _ -> desiredNode == actualNode
822+
823+
813824
814825-- EXPR REPORTS
815826
@@ -823,8 +834,8 @@ toExprReport source context expr startRow startCol =
823834 Case _ _ _ ->
824835 error "TODO Case"
825836
826− If _ _ _ ->
827− error "TODO If"
837+ If if_ row col ->
838+ toIfReport source context if_ row col
828839
829840 List list row col ->
830841 toListReport source context list row col
@@ -906,6 +917,10 @@ toExprReport source context expr startRow startCol =
906917 InNode NParens r c _ -> (r, c, "some parentheses")
907918 InNode NList r c _ -> (r, c, "a list")
908919 InNode NFunc r c _ -> (r, c, "an anonymous function")
920+ InNode NCond r c _ -> (r, c, "an `if` expression")
921+ InNode NThen r c _ -> (r, c, "an `if` expression")
922+ InNode NElse r c _ -> (r, c, "an `if` expression")
923+ -- TODO check if this is actually the best way to get error messages here
909924
910925 surroundings = A.Region (A.Position contextRow contextCol) (A.Position row col)
911926 region = toRegion row col
@@ -1347,7 +1362,7 @@ toOperatorReport source context operator row col =
13471362 D.reflow "Maybe you want == instead? To check if two values are equal?"
13481363 ,
13491364 D.toSimpleNote $
1350− if error "TODO is within record?" then
1365+ if isWithin NRecord context then
13511366 "Records look like { x = 3, y = 4 } with the equals sign right\
13521367 \ after the field name. So maybe you forgot a comma?"
13531368 else
@@ -1391,6 +1406,173 @@ toOperatorReport source context operator row col =
13911406
13921407
13931408
1409+-- IF
1410+
1411+
1412+toIfReport :: Code.Source -> Context -> If -> Row -> Col -> Report.Report
1413+toIfReport source context if_ startRow startCol =
1414+ case if_ of
1415+ IfSpace space row col ->
1416+ toSpaceReport source space row col
1417+
1418+ IfThen row col ->
1419+ let
1420+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1421+ region = toRegion row col
1422+ in
1423+ Report.Report "UNFINISHED IF" region [] $
1424+ Report.toCodeSnippet source surroundings (Just region)
1425+ (
1426+ D.reflow $
1427+ "I was expecting to see more of this `if` expression, but I got stuck here:"
1428+ ,
1429+ D.fillSep $
1430+ ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1431+ ]
1432+ )
1433+
1434+ IfElse row col ->
1435+ let
1436+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1437+ region = toRegion row col
1438+ in
1439+ Report.Report "UNFINISHED IF" region [] $
1440+ Report.toCodeSnippet source surroundings (Just region)
1441+ (
1442+ D.reflow $
1443+ "I was expecting to see more of this `if` expression, but I got stuck here:"
1444+ ,
1445+ D.fillSep $
1446+ ["I","was","expecting","to","see","the",D.green "else","keyword","next."
1447+ ]
1448+ )
1449+
1450+ IfElseBranchStart row col ->
1451+ let
1452+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1453+ region = toRegion row col
1454+ in
1455+ Report.Report "UNFINISHED IF" region [] $
1456+ Report.toCodeSnippet source surroundings (Just region)
1457+ (
1458+ D.reflow $
1459+ "I just saw the start of an `else` branch, but then I got stuck here:"
1460+ ,
1461+ D.reflow $
1462+ "I was expecting to see an expression next. Maybe it is not filled in yet?"
1463+ )
1464+
1465+ IfCondition expr row col ->
1466+ toExprReport source (InNode NCond startRow startCol context) expr row col
1467+
1468+ IfThenBranch expr row col ->
1469+ toExprReport source (InNode NThen startRow startCol context) expr row col
1470+
1471+ IfElseBranch expr row col ->
1472+ toExprReport source (InNode NElse startRow startCol context) expr row col
1473+
1474+ IfIndentCondition row col ->
1475+ let
1476+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1477+ region = toRegion row col
1478+ in
1479+ Report.Report "UNFINISHED IF" region [] $
1480+ Report.toCodeSnippet source surroundings (Just region)
1481+ (
1482+ D.reflow $
1483+ "I was expecting to see more of this `if` expression, but I got stuck here:"
1484+ ,
1485+ D.stack
1486+ [ D.fillSep $
1487+ ["I","was","expecting","to","see","an","expression","like",D.dullyellow "x < 0"
1488+ ,"that","evaluates","to","True","or","False."
1489+ ]
1490+ , D.toSimpleNote $
1491+ "I can be confused by indentation. Maybe something is not indented enough?"
1492+ ]
1493+ )
1494+
1495+ IfIndentThen row col ->
1496+ let
1497+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1498+ region = toRegion row col
1499+ in
1500+ Report.Report "UNFINISHED IF" region [] $
1501+ Report.toCodeSnippet source surroundings (Just region)
1502+ (
1503+ D.reflow $
1504+ "I was expecting to see more of this `if` expression, but I got stuck here:"
1505+ ,
1506+ D.stack
1507+ [ D.fillSep $
1508+ ["I","was","expecting","to","see","the",D.green "then","keyword","next."
1509+ ]
1510+ , D.toSimpleNote $
1511+ "I can be confused by indentation. Maybe something is not indented enough?"
1512+ ]
1513+ )
1514+
1515+ IfIndentThenBranch row col ->
1516+ let
1517+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1518+ region = toRegion row col
1519+ in
1520+ Report.Report "UNFINISHED IF" region [] $
1521+ Report.toCodeSnippet source surroundings (Just region)
1522+ (
1523+ D.reflow $
1524+ "I got stuck after the start of this `then` branch:"
1525+ ,
1526+ D.stack
1527+ [ D.reflow $
1528+ "I was expecting to see an expression next. Maybe it is not filled in yet?"
1529+ , D.toSimpleNote $
1530+ "I can be confused by indentation, so if the `then` branch is already\
1531+ \ present, it may not be indented enough for me to recognize it."
1532+ ]
1533+ )
1534+
1535+ IfIndentElseBranch row col ->
1536+ let
1537+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1538+ region = toRegion row col
1539+ in
1540+ Report.Report "UNFINISHED IF" region [] $
1541+ Report.toCodeSnippet source surroundings (Just region)
1542+ (
1543+ D.reflow $
1544+ "I got stuck after the start of this `else` branch:"
1545+ ,
1546+ D.stack
1547+ [ D.reflow $
1548+ "I was expecting to see an expression next. Maybe it is not filled in yet?"
1549+ , D.toSimpleNote $
1550+ "I can be confused by indentation, so if the `else` branch is already\
1551+ \ present, it may not be indented enough for me to recognize it."
1552+ ]
1553+ )
1554+
1555+ IfIndentElse row col ->
1556+ let
1557+ surroundings = A.Region (A.Position startRow startCol) (A.Position row col)
1558+ region = toRegion row col
1559+ in
1560+ Report.Report "UNFINISHED IF" region [] $
1561+ Report.toCodeSnippet source surroundings (Just region)
1562+ (
1563+ D.reflow $
1564+ "I was expecting to see an `else` branch after this:"
1565+ ,
1566+ D.stack
1567+ [ D.reflow $
1568+ "I know what to do when the condition is `True`, but not when it is `False`."
1569+ , D.fillSep
1570+ ["Add","an",D.green "else","branch","to","handle","that","scenario!"]
1571+ ]
1572+ )
1573+
1574+
1575+
13941576-- RECORD
13951577
13961578
@@ -1469,7 +1651,7 @@ toRecordReport source context record startRow startCol =
14691651 addNoteForRecordError $
14701652 D.fillSep $
14711653 ["I","just","saw","a","field","name,","so","I","was","expecting","to","see"
1472− ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign?"
1654+ ,"an","equals","sign","next.","So","try","putting","an",D.green "=","sign","here?"
14731655 ]
14741656 )
14751657