@@ -1017,6 +1017,231 @@ end
10171017 end )
10181018 end )
10191019
1020+ describe (" indentation-based missing until/end location guessing" , function ()
1021+ it (" provides a better location on the same indentation level for missing end" , function ()
1022+ assert .same ({line = 11 , offset = 145 , end_offset = 150 , prev_line = 2 , prev_offset = 23 , prev_end_offset = 24 ,
1023+ msg = " expected 'end' (to close 'if' on line 2) near 'whoops' (indentation-based guess)" }, get_error ([[
1024+ local function f()
1025+ if cond then
1026+ do_thing()
1027+
1028+ do_more_things()
1029+
1030+ while true do
1031+ things_keep_happening()
1032+ end
1033+
1034+ whoops()
1035+ end
1036+ ]] ))
1037+
1038+ assert .same ({line = 10 , offset = 131 , end_offset = 136 , prev_line = 7 , prev_offset = 84 , prev_end_offset = 89 ,
1039+ msg = " expected 'until' (to close 'repeat' on line 7) near 'whoops' (indentation-based guess)"
1040+ }, get_error ([[
1041+ local function f()
1042+ if cond then
1043+ do_thing()
1044+
1045+ do_more_things()
1046+
1047+ repeat
1048+ things_keep_happening()
1049+
1050+ whoops()
1051+ end
1052+ ]] ))
1053+ assert .same ({line = 8 , offset = 64 , end_offset = 68 , prev_line = 5 , prev_offset = 41 , prev_end_offset = 48 ,
1054+ msg = " expected 'end' (to close 'function' on line 5) near 'local' (indentation-based guess)"
1055+ }, get_error ([[
1056+ local function f()
1057+ good()
1058+ end
1059+
1060+ local function g()
1061+ bad()
1062+
1063+ local function t()
1064+ irrelevant()
1065+ end
1066+ ]] ))
1067+
1068+ assert .same ({line = 9 , offset = 56 , end_offset = 65 , prev_line = 4 , prev_offset = 15 , prev_end_offset = 16 ,
1069+ msg = " expected 'end' (to close 'do' on line 4) near 'two_things' (indentation-based guess)"
1070+ }, get_error ([[
1071+ do end
1072+ do
1073+ end
1074+ do
1075+ do end
1076+ do
1077+ end
1078+ one_thing()
1079+ two_things()
1080+ ]] ))
1081+
1082+ assert .same ({line = 8 , offset = 91 , end_offset = 92 , prev_line = 3 , prev_offset = 16 , prev_end_offset = 20 ,
1083+ msg = " expected 'end' (to close 'while' on line 3) near 'if' (indentation-based guess)"
1084+ }, get_error ([[
1085+ do
1086+ do
1087+ while cond
1088+ do
1089+ thing = thing
1090+ another = thing
1091+
1092+ if yes then end
1093+ end
1094+ end
1095+ ]] ))
1096+
1097+ assert .same ({line = 6 , offset = 117 , end_offset = 125 , prev_line = 3 , prev_offset = 74 , prev_end_offset = 76 ,
1098+ msg = " expected 'end' (to close 'for' on line 3) near 'something' (indentation-based guess)"
1099+ }, get_error ([[
1100+ function g()
1101+ for i in ipairs("this is not even an error...") do
1102+ for i = 1, 2, 3 do
1103+ thing()
1104+
1105+ something = smth
1106+ end
1107+ ]] ))
1108+ end )
1109+
1110+ it (" provides a better location on a lower indentation level for missing end" , function ()
1111+ assert .same ({line = 5 , offset = 36 , end_offset = 38 , prev_line = 2 , prev_offset = 7 , prev_end_offset = 11 ,
1112+ msg = " expected 'end' (to close 'while' on line 2) near less indented 'end' (indentation-based guess)"
1113+ }, get_error ([[
1114+ do
1115+ while true do
1116+ thing()
1117+
1118+ end
1119+ ]] ))
1120+
1121+ assert .same ({line = 5 , offset = 51 , end_offset = 51 , prev_line = 2 , prev_offset = 7 , prev_end_offset = 11 ,
1122+ msg = " expected 'end' (to close 'while' on line 2) near 'a' (indentation-based guess)"
1123+ }, get_error ([[
1124+ do
1125+ while true do
1126+ thing()
1127+ more()
1128+ a()
1129+ ]] ))
1130+ end )
1131+
1132+ it (" provides a better location for various configurations of if statements" , function ()
1133+ assert .same ({line = 6 , offset = 67 , end_offset = 69 , prev_line = 2 , prev_offset = 7 , prev_end_offset = 8 ,
1134+ msg = " expected 'end' (to close 'if' on line 2) near less indented 'end' (indentation-based guess)"
1135+ }, get_error ([[
1136+ do
1137+ if thing({
1138+ long, long, long, line}) then
1139+ something()
1140+
1141+ end
1142+ ]] ))
1143+
1144+ assert .same ({line = 7 , offset = 66 , end_offset = 66 , prev_line = 4 , prev_offset = 43 , prev_end_offset = 46 ,
1145+ msg = " expected 'end' (to close 'else' on line 4) near 'a' (indentation-based guess)"
1146+ }, get_error ([[
1147+ do
1148+ if cond() then
1149+ something()
1150+ else
1151+ thing()
1152+
1153+ a = b
1154+ end
1155+ ]] ))
1156+
1157+ assert .same ({line = 6 , offset = 66 , end_offset = 68 , prev_line = 4 , prev_offset = 43 , prev_end_offset = 48 ,
1158+ msg = " expected 'end' (to close 'elseif' on line 4) near less indented 'end' (indentation-based guess)"
1159+ }, get_error ([[
1160+ do
1161+ if cond() then
1162+ something()
1163+ elseif something then
1164+
1165+ end
1166+ ]] ))
1167+
1168+ assert .same ({line = 10 , offset = 119 , end_offset = 119 , prev_line = 8 , prev_offset = 99 , prev_end_offset = 104 ,
1169+ msg = " expected 'end' (to close 'elseif' on line 8) near 'e' (indentation-based guess)"
1170+ }, get_error ([[
1171+ do
1172+ if cond() then
1173+ s()
1174+ elseif something then
1175+ b()
1176+ elseif a() then
1177+ c()
1178+ elseif d() then
1179+
1180+ e()
1181+ end
1182+ ]] ))
1183+ end )
1184+
1185+ it (" reports the first guess location outside complete blocks" , function ()
1186+ assert .same ({line = 12 , offset = 92 , end_offset = 98 , prev_line = 10 , prev_offset = 61 , prev_end_offset = 65 ,
1187+ msg = " expected 'end' (to close 'while' on line 10) near 'another' (indentation-based guess)"
1188+ }, get_error ([[
1189+ do
1190+ while true do
1191+ thing()
1192+
1193+ another()
1194+ end
1195+ end
1196+
1197+ do
1198+ while true do
1199+ thing()
1200+ another()
1201+ end
1202+
1203+ do
1204+ while true do
1205+ thing()
1206+ another()
1207+ end
1208+ ]] ))
1209+ end )
1210+
1211+ it (" does not report blocks with different closing token comparing to original error" , function ()
1212+ assert .same ({line = 10 , offset = 87 , end_offset = 91 , prev_line = 8 , prev_offset = 60 , prev_end_offset = 65 ,
1213+ msg = " expected 'until' (to close 'repeat' on line 8) near less indented 'until' (indentation-based guess)"
1214+ }, get_error ([[
1215+ do
1216+ while true do
1217+ thing()
1218+
1219+ a()
1220+
1221+ repeat
1222+ repeat
1223+ thing()
1224+ until cond
1225+ end
1226+ ]] ))
1227+
1228+ assert .same ({line = 8 , offset = 58 , end_offset = 63 , prev_line = 5 , prev_offset = 30 , prev_end_offset = 31 ,
1229+ msg = " expected 'end' (to close 'do' on line 5) near 'thing3' (indentation-based guess)"
1230+ }, get_error ([[
1231+ repeat
1232+ thing1()
1233+
1234+ do
1235+ do
1236+ thing2()
1237+
1238+ thing3()
1239+ end
1240+ until another_thing
1241+ ]] ))
1242+ end )
1243+ end )
1244+
10201245 it (" provides correct location info" , function ()
10211246 assert .same ({
10221247 {tag = " Localrec" , line = 1 , offset = 1 , end_offset = 80 ,
0 commit comments