authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-05-18 18:55:13+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
logcf685c1132113b867f1476f4cd9d7a47d96a4782
tree2c82093069b8ff86c8835ceb94c6b0d705bc2589
parent0339e1c7d4fc3cc2144f4f5aae335b16fa808531

autodoc: collect type information for some expressions


2 files changed, 691 insertions(+), 625 deletions(-)

lib/docs/main.js+347-300
...@@ -494,6 +494,8 @@ var zigAnalysis;...@@ -494,6 +494,8 @@ var zigAnalysis;
494 * @return {WalkResult}494 * @return {WalkResult}
495 */495 */
496 function typeOfDecl(decl){496 function typeOfDecl(decl){
497 return decl.value.typeRef;
498
497 let i = 0;499 let i = 0;
498 while(i < 1000) {500 while(i < 1000) {
499 i += 1;501 i += 1;
...@@ -502,6 +504,13 @@ var zigAnalysis;...@@ -502,6 +504,13 @@ var zigAnalysis;
502 return /** @type {WalkResult} */({ type: typeTypeId });504 return /** @type {WalkResult} */({ type: typeTypeId });
503 }505 }
504506
507// if ("string" in decl.value) {
508// return /** @type {WalkResult} */({ type: {
509// kind: typeKinds.Pointer,
510// size: pointerSizeEnum.One,
511// child: });
512// }
513
505 if ("refPath" in decl.value) {514 if ("refPath" in decl.value) {
506 decl = /** @type {Decl} */({515 decl = /** @type {Decl} */({
507 value: decl.value.refPath[decl.value.refPath.length -1]516 value: decl.value.refPath[decl.value.refPath.length -1]
...@@ -1009,6 +1018,327 @@ var zigAnalysis;...@@ -1009,6 +1018,327 @@ var zigAnalysis;
1009 }1018 }
1010 }1019 }
10111020
1021 /**
1022 * @typedef {{
1023 wantHtml: boolean,
1024 }} RenderWrOptions
1025 * @param {WalkResult} wr,
1026 * @param {RenderWrOptions} opts,
1027 * @return {string}
1028 */
1029
1030 function exprName(expr, opts) {
1031 const activeField = Object.keys(expr)[0];
1032 switch (activeField) {
1033 case "int": {
1034 return "" + expr.int;
1035 }
1036 case "string": {
1037 return "\"" + escapeHtml(expr.string) + "\"";
1038 }
1039
1040 case "anytype": {
1041 return "anytype";
1042 }
1043
1044 case "this":{
1045 return "this";
1046 }
1047
1048 case "type": {
1049 let name = "";
1050 const typeObj = zigAnalysis.types[expr.type];
1051 switch (typeObj.kind) {
1052 case typeKinds.Array:
1053 {
1054 let arrayObj = /** @type {ArrayType} */(typeObj);
1055 let name = "[";
1056 let lenName = exprName(arrayObj.len, opts);
1057 if (opts.wantHtml) {
1058 name += '<span class="tok-number">' + lenName + '</span>';
1059 } else {
1060 name += lenName;
1061 }
1062 name += "]";
1063 name += exprName(arrayObj.child, opts);
1064 return name;
1065 }
1066 case typeKinds.Optional:
1067
1068 return "?" + typeValueName(/**@type {OptionalType} */(typeObj).child, wantHtml, wantSubLink, fnDecl, linkFnNameDecl);
1069 case typeKinds.Pointer:
1070 {
1071 let ptrObj = /** @type {PointerType} */(typeObj);
1072 let name = "";
1073 switch (ptrObj.size) {
1074 default:
1075 console.log("TODO: implement unhandled pointer size case");
1076 case pointerSizeEnum.One:
1077 name += "*";
1078 break;
1079 case pointerSizeEnum.Many:
1080 name += "[*]";
1081 break;
1082 case pointerSizeEnum.Slice:
1083 name += "[]";
1084 break;
1085 case pointerSizeEnum.C:
1086 name += "[*c]";
1087 break;
1088 }
1089 if (ptrObj['const']) {
1090 if (opts.wantHtml) {
1091 name += '<span class="tok-kw">const</span> ';
1092 } else {
1093 name += "const ";
1094 }
1095 }
1096 if (ptrObj['volatile']) {
1097 if (opts.wantHtml) {
1098 name += '<span class="tok-kw">volatile</span> ';
1099 } else {
1100 name += "volatile ";
1101 }
1102 }
1103 if (ptrObj.align != null) {
1104 if (opts.wantHtml) {
1105 name += '<span class="tok-kw">align</span>(';
1106 } else {
1107 name += "align(";
1108 }
1109 if (opts.wantHtml) {
1110 name += '<span class="tok-number">' + ptrObj.align + '</span>';
1111 } else {
1112 name += ptrObj.align;
1113 }
1114 if (ptrObj.hostIntBytes != null) {
1115 name += ":";
1116 if (opts.wantHtml) {
1117 name += '<span class="tok-number">' + ptrObj.bitOffsetInHost + '</span>';
1118 } else {
1119 name += ptrObj.bitOffsetInHost;
1120 }
1121 name += ":";
1122 if (opts.wantHtml) {
1123 name += '<span class="tok-number">' + ptrObj.hostIntBytes + '</span>';
1124 } else {
1125 name += ptrObj.hostIntBytes;
1126 }
1127 }
1128 name += ") ";
1129 }
1130 //name += typeValueName(ptrObj.child, wantHtml, wantSubLink, null);
1131 name += exprName(ptrObj.child, opts);
1132 return name;
1133 }
1134 case typeKinds.Float:
1135 {
1136 let floatObj = /** @type {NumberType} */ (typeObj);
1137
1138 if (wantHtml) {
1139 return '<span class="tok-type">' + floatObj.name + '</span>';
1140 } else {
1141 return floatObj.name;
1142 }
1143 }
1144 case typeKinds.Int:
1145 {
1146 let intObj = /** @type {NumberType} */(typeObj);
1147 let name = intObj.name;
1148 if (opts.wantHtml) {
1149 return '<span class="tok-type">' + name + '</span>';
1150 } else {
1151 return name;
1152 }
1153 }
1154 case typeKinds.ComptimeInt:
1155 if (wantHtml) {
1156 return '<span class="tok-type">comptime_int</span>';
1157 } else {
1158 return "comptime_int";
1159 }
1160 case typeKinds.ComptimeFloat:
1161 if (wantHtml) {
1162 return '<span class="tok-type">comptime_float</span>';
1163 } else {
1164 return "comptime_float";
1165 }
1166 case typeKinds.Type:
1167 if (wantHtml) {
1168 return '<span class="tok-type">type</span>';
1169 } else {
1170 return "type";
1171 }
1172 case typeKinds.Bool:
1173 if (wantHtml) {
1174 return '<span class="tok-type">bool</span>';
1175 } else {
1176 return "bool";
1177 }
1178 case typeKinds.Void:
1179 if (wantHtml) {
1180 return '<span class="tok-type">void</span>';
1181 } else {
1182 return "void";
1183 }
1184 case typeKinds.EnumLiteral:
1185 if (wantHtml) {
1186 return '<span class="tok-type">(enum literal)</span>';
1187 } else {
1188 return "(enum literal)";
1189 }
1190 case typeKinds.NoReturn:
1191 if (wantHtml) {
1192 return '<span class="tok-type">noreturn</span>';
1193 } else {
1194 return "noreturn";
1195 }
1196 case typeKinds.ErrorSet:
1197 {
1198 let errSetObj = /** @type {ErrSetType} */(typeObj);
1199 if (errSetObj.fields == null) {
1200 if (wantHtml) {
1201 return '<span class="tok-type">anyerror</span>';
1202 } else {
1203 return "anyerror";
1204 }
1205 } else {
1206 throw "TODO";
1207 // if (wantHtml) {
1208 // return escapeHtml(typeObj.name);
1209 // } else {
1210 // return typeObj.name;
1211 // }
1212 }
1213 }
1214 case typeKinds.ErrorUnion:
1215 {
1216 throw "TODO";
1217 // TODO: implement error union printing assuming that both
1218 // payload and error union are walk results!
1219 // let errUnionObj = /** @type {ErrUnionType} */(typeObj);
1220 // let errSetTypeObj = /** @type {ErrSetType} */ (zigAnalysis.types[errUnionObj.err]);
1221 // let payloadHtml = typeValueName(errUnionObj.payload, wantHtml, wantSubLink, null);
1222 // if (fnDecl != null && errSetTypeObj.fn === fnDecl.value.type) {
1223 // // function index parameter supplied and this is the inferred error set of it
1224 // return "!" + payloadHtml;
1225 // } else {
1226 // return typeValueName(errUnionObj.err, wantHtml, wantSubLink, null) + "!" + payloadHtml;
1227 // }
1228 }
1229 case typeKinds.Fn:
1230 {
1231 let fnObj = /** @type {Fn} */(typeObj);
1232 let payloadHtml = "";
1233 if (wantHtml) {
1234 payloadHtml += '<span class="tok-kw">fn</span>';
1235 if (fnDecl != null) {
1236 payloadHtml += ' <span class="tok-fn">';
1237 if (linkFnNameDecl != null) {
1238 payloadHtml += '<a href="' + linkFnNameDecl + '">' +
1239 escapeHtml(fnDecl.name) + '</a>';
1240 } else {
1241 payloadHtml += escapeHtml(fnDecl.name);
1242 }
1243 payloadHtml += '</span>';
1244 }
1245 } else {
1246 payloadHtml += 'fn'
1247 }
1248 payloadHtml += '(';
1249 if (fnObj.params) {
1250 let fields = null;
1251 let isVarArgs = false;
1252 let fnNode = zigAnalysis.astNodes[fnObj.src];
1253 fields = fnNode.fields;
1254 isVarArgs = fnNode.varArgs;
1255
1256 for (let i = 0; i < fnObj.params.length; i += 1) {
1257 if (i != 0) {
1258 payloadHtml += ', ';
1259 }
1260
1261 let value = fnObj.params[i];
1262 let paramValue = resolveValue(value);
1263
1264 if (fields != null) {
1265 let paramNode = zigAnalysis.astNodes[fields[i]];
1266
1267 if (paramNode.varArgs) {
1268 payloadHtml += '...';
1269 continue;
1270 }
1271
1272 if (paramNode.noalias) {
1273 if (wantHtml) {
1274 payloadHtml += '<span class="tok-kw">noalias</span> ';
1275 } else {
1276 payloadHtml += 'noalias ';
1277 }
1278 }
1279
1280 if (paramNode.comptime) {
1281 if (wantHtml) {
1282 payloadHtml += '<span class="tok-kw">comptime</span> ';
1283 } else {
1284 payloadHtml += 'comptime ';
1285 }
1286 }
1287
1288 let paramName = paramNode.name;
1289 if (paramName != null) {
1290 // skip if it matches the type name
1291 if (!shouldSkipParamName(paramValue, paramName)) {
1292 payloadHtml += paramName + ': ';
1293 }
1294 }
1295 }
1296
1297 if (isVarArgs && i === fnObj.params.length - 1) {
1298 payloadHtml += '...';
1299 } else if ("refPath" in value) {
1300 payloadHtml += '<a href="">';
1301 payloadHtml += '<span class="tok-kw" style="color:lightblue;">[Ref Path]</span>';
1302 payloadHtml += '</a>';
1303
1304 } else if ("type" in value) {
1305 let name = typeValueName(value, false, false, fnDecl, linkFnNameDecl);
1306 payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
1307 } else if ("comptimeExpr" in value) {
1308 payloadHtml += '<span class="tok-kw">[ComptimeExpr]</span>';
1309 } else if (wantHtml) {
1310 payloadHtml += '<span class="tok-kw">var</span>';
1311 } else {
1312 payloadHtml += 'var';
1313 }
1314 }
1315 }
1316
1317 payloadHtml += ') ';
1318 if (fnObj.ret != null) {
1319 payloadHtml += typeValueName(fnObj.ret, wantHtml, wantSubLink, fnDecl);
1320 } else if (wantHtml) {
1321 payloadHtml += '<span class="tok-kw">anytype</span>';
1322 } else {
1323 payloadHtml += 'anytype';
1324 }
1325 return payloadHtml;
1326 }
1327 default:
1328 throw "TODO";
1329 // if (wantHtml) {
1330 // return escapeHtml(typeObj.name);
1331 // } else {
1332 // return typeObj.name;
1333 // }
1334 }
1335 }
1336
1337 default: throw "oh no";
1338 }
1339 }
1340
1341
1012 /**1342 /**
1013 * @param {WalkResult} typeValue,1343 * @param {WalkResult} typeValue,
1014 * @param {boolean} wantHtml,1344 * @param {boolean} wantHtml,
...@@ -1174,289 +1504,6 @@ var zigAnalysis;...@@ -1174,289 +1504,6 @@ var zigAnalysis;
1174 * @return {string}1504 * @return {string}
1175 */1505 */
1176 function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) {1506 function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) {
1177 switch (typeObj.kind) {
1178 case typeKinds.Array:
1179 {
1180 let arrayObj = /** @type {ArrayType} */(typeObj);
1181 let name = "[";
1182 let lenName = typeValueName(arrayObj.len, wantHtml, wantSubLink);
1183 if (wantHtml) {
1184 name += '<span class="tok-number">' + lenName + '</span>';
1185 } else {
1186 name += lenName;
1187 }
1188 name += "]";
1189 name += typeValueName(arrayObj.child, wantHtml, wantSubLink, null);
1190 return name;
1191 }
1192 case typeKinds.Optional:
1193
1194 return "?" + typeValueName(/**@type {OptionalType} */(typeObj).child, wantHtml, wantSubLink, fnDecl, linkFnNameDecl);
1195 case typeKinds.Pointer:
1196 {
1197 let ptrObj = /** @type {PointerType} */(typeObj);
1198 let name = "";
1199 switch (ptrObj.size) {
1200 default:
1201 console.log("TODO: implement unhandled pointer size case");
1202 case pointerSizeEnum.One:
1203 name += "*";
1204 break;
1205 case pointerSizeEnum.Many:
1206 name += "[*]";
1207 break;
1208 case pointerSizeEnum.Slice:
1209 name += "[]";
1210 break;
1211 case pointerSizeEnum.C:
1212 name += "[*c]";
1213 break;
1214 }
1215 if (ptrObj['const']) {
1216 if (wantHtml) {
1217 name += '<span class="tok-kw">const</span> ';
1218 } else {
1219 name += "const ";
1220 }
1221 }
1222 if (ptrObj['volatile']) {
1223 if (wantHtml) {
1224 name += '<span class="tok-kw">volatile</span> ';
1225 } else {
1226 name += "volatile ";
1227 }
1228 }
1229 if (ptrObj.align != null) {
1230 if (wantHtml) {
1231 name += '<span class="tok-kw">align</span>(';
1232 } else {
1233 name += "align(";
1234 }
1235 if (wantHtml) {
1236 name += '<span class="tok-number">' + ptrObj.align + '</span>';
1237 } else {
1238 name += ptrObj.align;
1239 }
1240 if (ptrObj.hostIntBytes != null) {
1241 name += ":";
1242 if (wantHtml) {
1243 name += '<span class="tok-number">' + ptrObj.bitOffsetInHost + '</span>';
1244 } else {
1245 name += ptrObj.bitOffsetInHost;
1246 }
1247 name += ":";
1248 if (wantHtml) {
1249 name += '<span class="tok-number">' + ptrObj.hostIntBytes + '</span>';
1250 } else {
1251 name += ptrObj.hostIntBytes;
1252 }
1253 }
1254 name += ") ";
1255 }
1256 name += typeValueName(ptrObj.child, wantHtml, wantSubLink, null);
1257 return name;
1258 }
1259 case typeKinds.Float:
1260 {
1261 let floatObj = /** @type {NumberType} */ (typeObj);
1262
1263 if (wantHtml) {
1264 return '<span class="tok-type">' + floatObj.name + '</span>';
1265 } else {
1266 return floatObj.name;
1267 }
1268 }
1269 case typeKinds.Int:
1270 {
1271 let intObj = /** @type {NumberType} */(typeObj);
1272 let name = intObj.name;
1273 if (wantHtml) {
1274 return '<span class="tok-type">' + name + '</span>';
1275 } else {
1276 return name;
1277 }
1278 }
1279 case typeKinds.ComptimeInt:
1280 if (wantHtml) {
1281 return '<span class="tok-type">comptime_int</span>';
1282 } else {
1283 return "comptime_int";
1284 }
1285 case typeKinds.ComptimeFloat:
1286 if (wantHtml) {
1287 return '<span class="tok-type">comptime_float</span>';
1288 } else {
1289 return "comptime_float";
1290 }
1291 case typeKinds.Type:
1292 if (wantHtml) {
1293 return '<span class="tok-type">type</span>';
1294 } else {
1295 return "type";
1296 }
1297 case typeKinds.Bool:
1298 if (wantHtml) {
1299 return '<span class="tok-type">bool</span>';
1300 } else {
1301 return "bool";
1302 }
1303 case typeKinds.Void:
1304 if (wantHtml) {
1305 return '<span class="tok-type">void</span>';
1306 } else {
1307 return "void";
1308 }
1309 case typeKinds.EnumLiteral:
1310 if (wantHtml) {
1311 return '<span class="tok-type">(enum literal)</span>';
1312 } else {
1313 return "(enum literal)";
1314 }
1315 case typeKinds.NoReturn:
1316 if (wantHtml) {
1317 return '<span class="tok-type">noreturn</span>';
1318 } else {
1319 return "noreturn";
1320 }
1321 case typeKinds.ErrorSet:
1322 {
1323 let errSetObj = /** @type {ErrSetType} */(typeObj);
1324 if (errSetObj.fields == null) {
1325 if (wantHtml) {
1326 return '<span class="tok-type">anyerror</span>';
1327 } else {
1328 return "anyerror";
1329 }
1330 } else {
1331 throw "TODO";
1332 // if (wantHtml) {
1333 // return escapeHtml(typeObj.name);
1334 // } else {
1335 // return typeObj.name;
1336 // }
1337 }
1338 }
1339 case typeKinds.ErrorUnion:
1340 {
1341 throw "TODO";
1342 // TODO: implement error union printing assuming that both
1343 // payload and error union are walk results!
1344 // let errUnionObj = /** @type {ErrUnionType} */(typeObj);
1345 // let errSetTypeObj = /** @type {ErrSetType} */ (zigAnalysis.types[errUnionObj.err]);
1346 // let payloadHtml = typeValueName(errUnionObj.payload, wantHtml, wantSubLink, null);
1347 // if (fnDecl != null && errSetTypeObj.fn === fnDecl.value.type) {
1348 // // function index parameter supplied and this is the inferred error set of it
1349 // return "!" + payloadHtml;
1350 // } else {
1351 // return typeValueName(errUnionObj.err, wantHtml, wantSubLink, null) + "!" + payloadHtml;
1352 // }
1353 }
1354 case typeKinds.Fn:
1355 {
1356 let fnObj = /** @type {Fn} */(typeObj);
1357 let payloadHtml = "";
1358 if (wantHtml) {
1359 payloadHtml += '<span class="tok-kw">fn</span>';
1360 if (fnDecl != null) {
1361 payloadHtml += ' <span class="tok-fn">';
1362 if (linkFnNameDecl != null) {
1363 payloadHtml += '<a href="' + linkFnNameDecl + '">' +
1364 escapeHtml(fnDecl.name) + '</a>';
1365 } else {
1366 payloadHtml += escapeHtml(fnDecl.name);
1367 }
1368 payloadHtml += '</span>';
1369 }
1370 } else {
1371 payloadHtml += 'fn'
1372 }
1373 payloadHtml += '(';
1374 if (fnObj.params) {
1375 let fields = null;
1376 let isVarArgs = false;
1377 let fnNode = zigAnalysis.astNodes[fnObj.src];
1378 fields = fnNode.fields;
1379 isVarArgs = fnNode.varArgs;
1380
1381 for (let i = 0; i < fnObj.params.length; i += 1) {
1382 if (i != 0) {
1383 payloadHtml += ', ';
1384 }
1385
1386 let value = fnObj.params[i];
1387 let paramValue = resolveValue(value);
1388
1389 if (fields != null) {
1390 let paramNode = zigAnalysis.astNodes[fields[i]];
1391
1392 if (paramNode.varArgs) {
1393 payloadHtml += '...';
1394 continue;
1395 }
1396
1397 if (paramNode.noalias) {
1398 if (wantHtml) {
1399 payloadHtml += '<span class="tok-kw">noalias</span> ';
1400 } else {
1401 payloadHtml += 'noalias ';
1402 }
1403 }
1404
1405 if (paramNode.comptime) {
1406 if (wantHtml) {
1407 payloadHtml += '<span class="tok-kw">comptime</span> ';
1408 } else {
1409 payloadHtml += 'comptime ';
1410 }
1411 }
1412
1413 let paramName = paramNode.name;
1414 if (paramName != null) {
1415 // skip if it matches the type name
1416 if (!shouldSkipParamName(paramValue, paramName)) {
1417 payloadHtml += paramName + ': ';
1418 }
1419 }
1420 }
1421
1422 if (isVarArgs && i === fnObj.params.length - 1) {
1423 payloadHtml += '...';
1424 } else if ("refPath" in value) {
1425 payloadHtml += '<a href="">';
1426 payloadHtml += '<span class="tok-kw" style="color:lightblue;">[Ref Path]</span>';
1427 payloadHtml += '</a>';
1428
1429 } else if ("type" in value) {
1430 let name = typeValueName(value, false, false, fnDecl, linkFnNameDecl);
1431 payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
1432 } else if ("comptimeExpr" in value) {
1433 payloadHtml += '<span class="tok-kw">[ComptimeExpr]</span>';
1434 } else if (wantHtml) {
1435 payloadHtml += '<span class="tok-kw">var</span>';
1436 } else {
1437 payloadHtml += 'var';
1438 }
1439 }
1440 }
1441
1442 payloadHtml += ') ';
1443 if (fnObj.ret != null) {
1444 payloadHtml += typeValueName(fnObj.ret, wantHtml, wantSubLink, fnDecl);
1445 } else if (wantHtml) {
1446 payloadHtml += '<span class="tok-kw">anytype</span>';
1447 } else {
1448 payloadHtml += 'anytype';
1449 }
1450 return payloadHtml;
1451 }
1452 default:
1453 throw "TODO";
1454 // if (wantHtml) {
1455 // return escapeHtml(typeObj.name);
1456 // } else {
1457 // return typeObj.name;
1458 // }
1459 }
1460 }1507 }
14611508
1462 /** @param {Type} typeObj */1509 /** @param {Type} typeObj */
...@@ -1607,25 +1654,25 @@ var zigAnalysis;...@@ -1607,25 +1654,25 @@ var zigAnalysis;
1607 /** @param {Decl} decl */1654 /** @param {Decl} decl */
1608 function renderValue(decl) {1655 function renderValue(decl) {
16091656
1610 let declTypeRef = typeOfDecl(decl);1657 let declTypeRef = decl.value.typeRef;
1611 let declValueText = "";1658 let declValueText = exprName(decl.value.expr);
1612 switch(Object.keys(decl.value)[0]) {1659// switch(Object.keys(decl.value)[0]) {
1613 case "int":1660// case "int":
1614 declValueText += /** @type {{int: {value: number}}} */(decl.value).int.value;1661// declValueText += /** @type {{int: {value: number}}} */(decl.value).int.value;
1615 break;1662// break;
1616 case "float":1663// case "float":
1617 declValueText += /** @type {{float: {value: number}}} */(decl.value).float.value;1664// declValueText += /** @type {{float: {value: number}}} */(decl.value).float.value;
1618 break;1665// break;
1619 case "comptimeExpr":1666// case "comptimeExpr":
1620 declValueText += "[ComptimeExpr]";1667// declValueText += "[ComptimeExpr]";
1621 break;1668// break;
1622 default:1669// default:
1623 console.log("TODO: renderValue for ", Object.keys(decl.value)[0]);1670// console.log("TODO: renderValue for ", Object.keys(decl.value)[0]);
1624 declValueText += "#TODO#";1671// declValueText += "#TODO#";
1625 }1672// }
16261673
1627 domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' +1674 domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' +
1628 escapeHtml(decl.name) + ': ' + typeValueName(declTypeRef, true, true) +1675 escapeHtml(decl.name) + ': ' + exprName(declTypeRef, {wantHtml: true}) +
1629 " = " + declValueText;1676 " = " + declValueText;
16301677
1631 let docs = zigAnalysis.astNodes[decl.src].docs;1678 let docs = zigAnalysis.astNodes[decl.src].docs;
src/Autodoc.zig+344-325
...@@ -17,13 +17,14 @@ files: std.AutoHashMapUnmanaged(*File, usize) = .{},...@@ -17,13 +17,14 @@ files: std.AutoHashMapUnmanaged(*File, usize) = .{},
17calls: std.ArrayListUnmanaged(DocData.Call) = .{},17calls: std.ArrayListUnmanaged(DocData.Call) = .{},
18types: std.ArrayListUnmanaged(DocData.Type) = .{},18types: std.ArrayListUnmanaged(DocData.Type) = .{},
19decls: std.ArrayListUnmanaged(DocData.Decl) = .{},19decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
20exprs: std.ArrayListUnmanaged(DocData.Expr) = .{},
20ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},21ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},
21comptime_exprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{},22comptime_exprs: std.ArrayListUnmanaged(DocData.ComptimeExpr) = .{},
2223
23// These fields hold temporary state of the analysis process24// These fields hold temporary state of the analysis process
24// and are mainly used by the decl path resolving algorithm.25// and are mainly used by the decl path resolving algorithm.
25pending_ref_paths: std.AutoHashMapUnmanaged(26pending_ref_paths: std.AutoHashMapUnmanaged(
26 *DocData.WalkResult, // pointer to declpath tail end (ie `&decl_path[decl_path.len - 1]`)27 *DocData.Expr, // pointer to declpath tail end (ie `&decl_path[decl_path.len - 1]`)
27 std.ArrayListUnmanaged(RefPathResumeInfo),28 std.ArrayListUnmanaged(RefPathResumeInfo),
28) = .{},29) = .{},
29ref_paths_pending_on_decls: std.AutoHashMapUnmanaged(30ref_paths_pending_on_decls: std.AutoHashMapUnmanaged(
...@@ -37,7 +38,7 @@ ref_paths_pending_on_types: std.AutoHashMapUnmanaged(...@@ -37,7 +38,7 @@ ref_paths_pending_on_types: std.AutoHashMapUnmanaged(
3738
38const RefPathResumeInfo = struct {39const RefPathResumeInfo = struct {
39 file: *File,40 file: *File,
40 ref_path: []DocData.WalkResult,41 ref_path: []DocData.Expr,
41};42};
4243
43var arena_allocator: std.heap.ArenaAllocator = undefined;44var arena_allocator: std.heap.ArenaAllocator = undefined;
...@@ -80,7 +81,6 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -80,7 +81,6 @@ pub fn generateZirData(self: *Autodoc) !void {
80 .ComptimeExpr = .{ .name = "ComptimeExpr" },81 .ComptimeExpr = .{ .name = "ComptimeExpr" },
81 });82 });
8283
83 var tr = DocData.WalkResult{ .type = @enumToInt(Ref.usize_type) };
84 // this skipts Ref.none but it's ok becuse we replaced it with ComptimeExpr84 // this skipts Ref.none but it's ok becuse we replaced it with ComptimeExpr
85 var i: u32 = 1;85 var i: u32 = 1;
86 while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {86 while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {
...@@ -96,7 +96,6 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -96,7 +96,6 @@ pub fn generateZirData(self: *Autodoc) !void {
96 .Array = .{96 .Array = .{
97 .len = .{97 .len = .{
98 .int = .{98 .int = .{
99 .typeRef = &tr,
100 .value = 1,99 .value = 1,
101 .negated = false,100 .negated = false,
102 },101 },
...@@ -163,7 +162,7 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -163,7 +162,7 @@ pub fn generateZirData(self: *Autodoc) !void {
163 var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index };162 var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index };
164 try self.ast_nodes.append(self.arena, .{ .name = "(root)" });163 try self.ast_nodes.append(self.arena, .{ .name = "(root)" });
165 try self.files.put(self.arena, file, main_type_index);164 try self.files.put(self.arena, file, main_type_index);
166 _ = try self.walkInstruction(file, &root_scope, Zir.main_struct_inst);165 _ = try self.walkInstruction(file, &root_scope, Zir.main_struct_inst, false);
167166
168 if (self.ref_paths_pending_on_decls.count() > 0) {167 if (self.ref_paths_pending_on_decls.count() > 0) {
169 @panic("some decl paths were never fully analized (pending on decls)");168 @panic("some decl paths were never fully analized (pending on decls)");
...@@ -182,6 +181,7 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -182,6 +181,7 @@ pub fn generateZirData(self: *Autodoc) !void {
182 .calls = self.calls.items,181 .calls = self.calls.items,
183 .types = self.types.items,182 .types = self.types.items,
184 .decls = self.decls.items,183 .decls = self.decls.items,
184 .exprs = self.exprs.items,
185 .astNodes = self.ast_nodes.items,185 .astNodes = self.ast_nodes.items,
186 .comptimeExprs = self.comptime_exprs.items,186 .comptimeExprs = self.comptime_exprs.items,
187 };187 };
...@@ -305,11 +305,12 @@ const DocData = struct {...@@ -305,11 +305,12 @@ const DocData = struct {
305 },305 },
306 types: []Type,306 types: []Type,
307 decls: []Decl,307 decls: []Decl,
308 exprs: []Expr,
308 comptimeExprs: []ComptimeExpr,309 comptimeExprs: []ComptimeExpr,
309 const Call = struct {310 const Call = struct {
310 func: WalkResult,311 func: Expr,
311 args: []WalkResult,312 args: []Expr,
312 ret: WalkResult,313 ret: Expr,
313 };314 };
314315
315 /// All the type "families" as described by `std.builtin.TypeId`316 /// All the type "families" as described by `std.builtin.TypeId`
...@@ -340,7 +341,6 @@ const DocData = struct {...@@ -340,7 +341,6 @@ const DocData = struct {
340341
341 const ComptimeExpr = struct {342 const ComptimeExpr = struct {
342 code: []const u8,343 code: []const u8,
343 typeRef: WalkResult,
344 };344 };
345 const Package = struct {345 const Package = struct {
346 name: []const u8 = "root",346 name: []const u8 = "root",
...@@ -356,7 +356,6 @@ const DocData = struct {...@@ -356,7 +356,6 @@ const DocData = struct {
356 kind: []const u8,356 kind: []const u8,
357 isTest: bool,357 isTest: bool,
358 src: usize, // index into astNodes358 src: usize, // index into astNodes
359 // typeRef: TypeRef,
360 value: WalkResult,359 value: WalkResult,
361 // The index in astNodes of the `test declname { }` node360 // The index in astNodes of the `test declname { }` node
362 decltest: ?usize = null,361 decltest: ?usize = null,
...@@ -383,18 +382,18 @@ const DocData = struct {...@@ -383,18 +382,18 @@ const DocData = struct {
383 Float: struct { name: []const u8 },382 Float: struct { name: []const u8 },
384 Pointer: struct {383 Pointer: struct {
385 size: std.builtin.TypeInfo.Pointer.Size,384 size: std.builtin.TypeInfo.Pointer.Size,
386 child: WalkResult,385 child: Expr,
387 },386 },
388 Array: struct {387 Array: struct {
389 len: WalkResult,388 len: Expr,
390 child: WalkResult,389 child: Expr,
391 },390 },
392 Struct: struct {391 Struct: struct {
393 name: []const u8,392 name: []const u8,
394 src: usize, // index into astNodes393 src: usize, // index into astNodes
395 privDecls: []usize = &.{}, // index into decls394 privDecls: []usize = &.{}, // index into decls
396 pubDecls: []usize = &.{}, // index into decls395 pubDecls: []usize = &.{}, // index into decls
397 fields: ?[]WalkResult = null, // (use src->fields to find names)396 fields: ?[]Expr = null, // (use src->fields to find names)
398 },397 },
399 ComptimeExpr: struct { name: []const u8 },398 ComptimeExpr: struct { name: []const u8 },
400 ComptimeFloat: struct { name: []const u8 },399 ComptimeFloat: struct { name: []const u8 },
...@@ -403,7 +402,7 @@ const DocData = struct {...@@ -403,7 +402,7 @@ const DocData = struct {
403 Null: struct { name: []const u8 },402 Null: struct { name: []const u8 },
404 Optional: struct {403 Optional: struct {
405 name: []const u8,404 name: []const u8,
406 child: WalkResult,405 child: Expr,
407 },406 },
408 ErrorUnion: struct { name: []const u8 },407 ErrorUnion: struct { name: []const u8 },
409 ErrorSet: struct {408 ErrorSet: struct {
...@@ -423,13 +422,13 @@ const DocData = struct {...@@ -423,13 +422,13 @@ const DocData = struct {
423 src: usize, // index into astNodes422 src: usize, // index into astNodes
424 privDecls: []usize = &.{}, // index into decls423 privDecls: []usize = &.{}, // index into decls
425 pubDecls: []usize = &.{}, // index into decls424 pubDecls: []usize = &.{}, // index into decls
426 fields: []WalkResult = &.{}, // (use src->fields to find names)425 fields: []Expr = &.{}, // (use src->fields to find names)
427 },426 },
428 Fn: struct {427 Fn: struct {
429 name: []const u8,428 name: []const u8,
430 src: ?usize = null, // index into astNodes429 src: ?usize = null, // index into astNodes
431 ret: WalkResult,430 ret: Expr,
432 params: ?[]WalkResult = null, // (use src->fields to find names)431 params: ?[]Expr = null, // (use src->fields to find names)
433 },432 },
434 BoundFn: struct { name: []const u8 },433 BoundFn: struct { name: []const u8 },
435 Opaque: struct { name: []const u8 },434 Opaque: struct { name: []const u8 },
...@@ -517,75 +516,61 @@ const DocData = struct {...@@ -517,75 +516,61 @@ const DocData = struct {
517 }516 }
518 };517 };
519518
520 /// A WalkResult represents the result of the analysis process done to a519 /// An Expr represents the (untyped) result of analizing instructions.
521 /// declaration. This includes: decls, fields, etc.520 /// The data is normalized, which means that an Expr that results in a
522 ///521 /// type definition will hold an index into `self.types`.
523 /// The data in WalkResult is mostly normalized, which means that a522 pub const Expr = union(enum) {
524 /// WalkResult that results in a type definition will hold an index into
525 /// `self.types`.
526 const WalkResult = union(enum) {
527 comptimeExpr: usize, // index in `comptimeExprs`523 comptimeExpr: usize, // index in `comptimeExprs`
528 void,524 void,
529 @"unreachable",525 @"unreachable",
530 @"null": *WalkResult,526 @"null",
531 @"undefined": *WalkResult,527 @"undefined",
532 @"struct": Struct,528 @"struct": []FieldVal,
533 bool: bool,529 bool: bool,
534 @"anytype",530 @"anytype",
535 type: usize, // index in `types`531 type: usize, // index in `types`
536 this: usize, // index in `types`532 this: usize, // index in `types`
537 declRef: usize, // index in `decls`533 declRef: usize, // index in `decls`
538 fieldRef: FieldRef,534 fieldRef: FieldRef,
539 refPath: []WalkResult,535 refPath: []Expr,
540 int: struct {536 int: struct {
541 typeRef: *WalkResult,
542 value: usize, // direct value537 value: usize, // direct value
543 negated: bool = false,538 negated: bool = false,
544 },539 },
545 float: struct {540 float: f64, // direct value
546 typeRef: *WalkResult,541 array: []usize, // index in `exprs`
547 value: f64, // direct value
548 negated: bool = false,
549 },
550 array: Array,
551 call: usize, // index in `calls`542 call: usize, // index in `calls`
552 enumLiteral: []const u8,543 enumLiteral: []const u8, // direct value
553 typeOf: *WalkResult,544 typeOf: usize, // index in `exprs`
554 sizeOf: *WalkResult,545 as: struct {
546 typeRefArg: ?usize, // index in `exprs`
547 exprArg: usize, // index in `exprs`
548 },
549 sizeOf: usize, // index in `exprs`
555 compileError: []const u8,550 compileError: []const u8,
556 string: []const u8,551 string: []const u8, // direct value
557
558 const FieldRef = struct {552 const FieldRef = struct {
559 type: usize, // index in `types`553 type: usize, // index in `types`
560 index: usize, // index in type.fields554 index: usize, // index in type.fields
561 };555 };
562556
563 const Struct = struct {557 const FieldVal = struct {
564 typeRef: *WalkResult,558 name: []const u8,
565 fieldVals: []FieldVal,559 val: WalkResult,
566
567 const FieldVal = struct {
568 name: []const u8,
569 val: WalkResult,
570 };
571 };
572 const Array = struct {
573 typeRef: *WalkResult,
574 data: []WalkResult,
575 };560 };
576561
577 pub fn jsonStringify(562 pub fn jsonStringify(
578 self: WalkResult,563 self: Expr,
579 options: std.json.StringifyOptions,564 options: std.json.StringifyOptions,
580 w: anytype,565 w: anytype,
581 ) std.os.WriteError!void {566 ) std.os.WriteError!void {
582 switch (self) {567 switch (self) {
583 .void, .@"unreachable", .@"anytype" => {568 .void, .@"unreachable", .@"anytype", .@"null", .@"undefined" => {
584 try w.print(569 try w.print(
585 \\{{ "{s}":{{}} }}570 \\{{ "{s}":{{}} }}
586 , .{@tagName(self)});571 , .{@tagName(self)});
587 },572 },
588 .type, .comptimeExpr, .call, .this, .declRef => |v| {573 .type, .comptimeExpr, .call, .this, .declRef, .typeOf => |v| {
589 try w.print(574 try w.print(
590 \\{{ "{s}":{} }}575 \\{{ "{s}":{} }}
591 , .{ @tagName(self), v });576 , .{ @tagName(self), v });
...@@ -593,43 +578,28 @@ const DocData = struct {...@@ -593,43 +578,28 @@ const DocData = struct {
593 .int => |v| {578 .int => |v| {
594 const neg = if (v.negated) "-" else "";579 const neg = if (v.negated) "-" else "";
595 try w.print(580 try w.print(
596 \\{{ "int": {{ "typeRef":581 \\{{ "int": {s}{} }}
597 , .{});
598 try v.typeRef.jsonStringify(options, w);
599 try w.print(
600 \\, "value": {s}{} }} }}
601 , .{ neg, v.value });582 , .{ neg, v.value });
602 },583 },
603 .float => |v| {584 .float => |v| {
604 const neg = if (v.negated) "-" else "";
605 try w.print(
606 \\{{ "float": {{ "typeRef":
607 , .{});
608 try v.typeRef.jsonStringify(options, w);
609 try w.print(585 try w.print(
610 \\, "value": {s}1 }} }}586 \\{{ "float": {} }}
611 , .{neg});587 , .{v});
612 // TODO: uncomment once float panic is fixed in stdlib
613 // See: https://github.com/ziglang/zig/issues/11283
614 // try w.print(
615 // \\, "value": {s}{e} }} }}
616 // , .{ neg, v.value });
617 },588 },
618 .bool => |v| {589 .bool => |v| {
619 try w.print(590 try w.print(
620 \\{{ "bool":{} }}591 \\{{ "bool":{} }}
621 , .{v});592 , .{v});
622 },593 },
623 .@"undefined" => |v| try std.json.stringify(v, options, w),594 .sizeOf => |v| try std.json.stringify(v, options, w),
624 .@"null" => |v| try std.json.stringify(v, options, w),595 .as => |v| try std.json.stringify(v, options, w),
625 .typeOf, .sizeOf => |v| try std.json.stringify(v, options, w),
626 .fieldRef => |v| try std.json.stringify(596 .fieldRef => |v| try std.json.stringify(
627 struct { fieldRef: FieldRef }{ .fieldRef = v },597 struct { fieldRef: FieldRef }{ .fieldRef = v },
628 options,598 options,
629 w,599 w,
630 ),600 ),
631 .@"struct" => |v| try std.json.stringify(601 .@"struct" => |v| try std.json.stringify(
632 struct { @"struct": Struct }{ .@"struct" = v },602 struct { @"struct": []FieldVal }{ .@"struct" = v },
633 options,603 options,
634 w,604 w,
635 ),605 ),
...@@ -642,7 +612,7 @@ const DocData = struct {...@@ -642,7 +612,7 @@ const DocData = struct {
642 }612 }
643 },613 },
644 .array => |v| try std.json.stringify(614 .array => |v| try std.json.stringify(
645 struct { @"array": Array }{ .@"array" = v },615 struct { @"array": []usize }{ .@"array" = v },
646 options,616 options,
647 w,617 w,
648 ),618 ),
...@@ -677,6 +647,17 @@ const DocData = struct {...@@ -677,6 +647,17 @@ const DocData = struct {
677 }647 }
678 }648 }
679 };649 };
650
651 /// A WalkResult represents the result of the analysis process done to a
652 /// a Zir instruction. Walk results carry type information either inferred
653 /// from the context (eg string literals are pointers to null-terminated
654 /// arrays), or because of @as() instructions.
655 /// Since the type information is only needed in certain contexts, the
656 /// underlying normalized data (Expr) is untyped.
657 const WalkResult = struct {
658 typeRef: ?Expr = null, // index in `exprs`
659 expr: Expr, // index in `exprs`
660 };
680};661};
681662
682/// Called when we need to analyze a Zir instruction.663/// Called when we need to analyze a Zir instruction.
...@@ -692,6 +673,7 @@ fn walkInstruction(...@@ -692,6 +673,7 @@ fn walkInstruction(
692 file: *File,673 file: *File,
693 parent_scope: *Scope,674 parent_scope: *Scope,
694 inst_index: usize,675 inst_index: usize,
676 need_type: bool, // true if the caller needs us to provide also a typeRef
695) error{OutOfMemory}!DocData.WalkResult {677) error{OutOfMemory}!DocData.WalkResult {
696 const tags = file.zir.instructions.items(.tag);678 const tags = file.zir.instructions.items(.tag);
697 const data = file.zir.instructions.items(.data);679 const data = file.zir.instructions.items(.data);
...@@ -711,11 +693,11 @@ fn walkInstruction(...@@ -711,11 +693,11 @@ fn walkInstruction(
711 },693 },
712 .closure_get => {694 .closure_get => {
713 const inst_node = data[inst_index].inst_node;695 const inst_node = data[inst_index].inst_node;
714 return try self.walkInstruction(file, parent_scope, inst_node.inst);696 return try self.walkInstruction(file, parent_scope, inst_node.inst, need_type);
715 },697 },
716 .closure_capture => {698 .closure_capture => {
717 const un_tok = data[inst_index].un_tok;699 const un_tok = data[inst_index].un_tok;
718 return try self.walkRef(file, parent_scope, un_tok.operand);700 return try self.walkRef(file, parent_scope, un_tok.operand, need_type);
719 },701 },
720 .import => {702 .import => {
721 const str_tok = data[inst_index].str_tok;703 const str_tok = data[inst_index].str_tok;
...@@ -726,17 +708,20 @@ fn walkInstruction(...@@ -726,17 +708,20 @@ fn walkInstruction(
726 const cte_slot_index = self.comptime_exprs.items.len;708 const cte_slot_index = self.comptime_exprs.items.len;
727 try self.comptime_exprs.append(self.arena, .{709 try self.comptime_exprs.append(self.arena, .{
728 .code = path,710 .code = path,
729 .typeRef = .{ .type = @enumToInt(DocData.DocTypeKinds.Type) },
730 });711 });
731 return DocData.WalkResult{712 return DocData.WalkResult{
732 .comptimeExpr = cte_slot_index,713 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
714 .expr = .{ .comptimeExpr = cte_slot_index },
733 };715 };
734 }716 }
735717
736 const new_file = self.module.importFile(file, path) catch unreachable;718 const new_file = self.module.importFile(file, path) catch unreachable;
737 const result = try self.files.getOrPut(self.arena, new_file.file);719 const result = try self.files.getOrPut(self.arena, new_file.file);
738 if (result.found_existing) {720 if (result.found_existing) {
739 return DocData.WalkResult{ .type = result.value_ptr.* };721 return DocData.WalkResult{
722 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
723 .expr = .{ .type = result.value_ptr.* },
724 };
740 }725 }
741726
742 result.value_ptr.* = self.types.items.len;727 result.value_ptr.* = self.types.items.len;
...@@ -745,18 +730,38 @@ fn walkInstruction(...@@ -745,18 +730,38 @@ fn walkInstruction(
745 .parent = null,730 .parent = null,
746 .enclosing_type = self.types.items.len,731 .enclosing_type = self.types.items.len,
747 };732 };
748 const new_file_walk_result = self.walkInstruction(733
734 return self.walkInstruction(
749 new_file.file,735 new_file.file,
750 &new_scope,736 &new_scope,
751 Zir.main_struct_inst,737 Zir.main_struct_inst,
738 need_type,
752 );739 );
753
754 return new_file_walk_result;
755 },740 },
756 .str => {741 .str => {
757 const str = data[inst_index].str;742 const str = data[inst_index].str.get(file.zir);
743
744 const tRef: ?DocData.Expr = if (!need_type) null else blk: {
745 const arrTypeId = self.types.items.len;
746 try self.types.append(self.arena, .{
747 .Array = .{
748 .len = .{ .int = .{ .value = str.len } },
749 .child = .{ .type = @enumToInt(Ref.u8_type) },
750 },
751 });
752 const ptrTypeId = self.types.items.len;
753 try self.types.append(self.arena, .{
754 .Pointer = .{
755 .size = .One,
756 .child = .{ .type = arrTypeId },
757 // TODO: add sentinel!
758 },
759 });
760 break :blk .{ .type = ptrTypeId };
761 };
758 return DocData.WalkResult{762 return DocData.WalkResult{
759 .string = str.get(file.zir),763 .typeRef = tRef,
764 .expr = .{ .string = str },
760 };765 };
761 },766 },
762 .compile_error => {767 .compile_error => {
...@@ -765,24 +770,23 @@ fn walkInstruction(...@@ -765,24 +770,23 @@ fn walkInstruction(
765 file,770 file,
766 parent_scope,771 parent_scope,
767 un_node.operand,772 un_node.operand,
773 false,
768 );774 );
769775
770 return DocData.WalkResult{ .compileError = operand.string };776 return DocData.WalkResult{
777 .expr = .{ .compileError = operand.expr.string },
778 };
771 },779 },
772 .enum_literal => {780 .enum_literal => {
773 const str_tok = data[inst_index].str_tok;781 const str_tok = data[inst_index].str_tok;
774 const literal = file.zir.nullTerminatedString(str_tok.start);782 const literal = file.zir.nullTerminatedString(str_tok.start);
775 return DocData.WalkResult{ .enumLiteral = literal };783 return DocData.WalkResult{ .expr = .{ .enumLiteral = literal } };
776 },784 },
777 .int => {785 .int => {
778 const int = data[inst_index].int;786 const int = data[inst_index].int;
779 const t = try self.arena.create(DocData.WalkResult);
780 t.* = .{ .type = @enumToInt(Ref.comptime_int_type) };
781 return DocData.WalkResult{787 return DocData.WalkResult{
782 .int = .{788 .typeRef = .{ .type = @enumToInt(Ref.comptime_int_type) },
783 .typeRef = t,789 .expr = .{ .int = .{ .value = int } },
784 .value = int,
785 },
786 };790 };
787 },791 },
788 .error_union_type => {792 .error_union_type => {
...@@ -790,20 +794,23 @@ fn walkInstruction(...@@ -790,20 +794,23 @@ fn walkInstruction(
790 const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index);794 const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index);
791795
792 // TODO: return the actual error union instread of cheating796 // TODO: return the actual error union instread of cheating
793 return self.walkRef(file, parent_scope, extra.data.rhs);797 return self.walkRef(file, parent_scope, extra.data.rhs, need_type);
794 },798 },
795 .ptr_type_simple => {799 .ptr_type_simple => {
796 const ptr = data[inst_index].ptr_type_simple;800 const ptr = data[inst_index].ptr_type_simple;
797 const type_slot_index = self.types.items.len;801 const type_slot_index = self.types.items.len;
798 const elem_type_ref = try self.walkRef(file, parent_scope, ptr.elem_type);802 const elem_type_ref = try self.walkRef(file, parent_scope, ptr.elem_type, false);
799 try self.types.append(self.arena, .{803 try self.types.append(self.arena, .{
800 .Pointer = .{804 .Pointer = .{
801 .size = ptr.size,805 .size = ptr.size,
802 .child = elem_type_ref,806 .child = elem_type_ref.expr,
803 },807 },
804 });808 });
805809
806 return DocData.WalkResult{ .type = type_slot_index };810 return DocData.WalkResult{
811 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
812 .expr = .{ .type = type_slot_index },
813 };
807 },814 },
808 .ptr_type => {815 .ptr_type => {
809 const ptr = data[inst_index].ptr_type;816 const ptr = data[inst_index].ptr_type;
...@@ -814,74 +821,84 @@ fn walkInstruction(...@@ -814,74 +821,84 @@ fn walkInstruction(
814 file,821 file,
815 parent_scope,822 parent_scope,
816 extra.data.elem_type,823 extra.data.elem_type,
824 false,
817 );825 );
818 try self.types.append(self.arena, .{826 try self.types.append(self.arena, .{
819 .Pointer = .{827 .Pointer = .{
820 .size = ptr.size,828 .size = ptr.size,
821 .child = elem_type_ref,829 .child = elem_type_ref.expr,
822 },830 },
823 });831 });
824832 return DocData.WalkResult{
825 return DocData.WalkResult{ .type = type_slot_index };833 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
834 .expr = .{ .type = type_slot_index },
835 };
826 },836 },
827 .array_type => {837 .array_type => {
828 const bin = data[inst_index].bin;838 const bin = data[inst_index].bin;
829 const len = try self.walkRef(file, parent_scope, bin.lhs);839 const len = try self.walkRef(file, parent_scope, bin.lhs, false);
830 const child = try self.walkRef(file, parent_scope, bin.rhs);840 const child = try self.walkRef(file, parent_scope, bin.rhs, false);
831841
832 const type_slot_index = self.types.items.len;842 const type_slot_index = self.types.items.len;
833 try self.types.append(self.arena, .{843 try self.types.append(self.arena, .{
834 .Array = .{844 .Array = .{
835 .len = len,845 .len = len.expr,
836 .child = child,846 .child = child.expr,
837 },847 },
838 });848 });
839 return DocData.WalkResult{ .type = type_slot_index };849 return DocData.WalkResult{
850 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
851 .expr = .{ .type = type_slot_index },
852 };
840 },853 },
841 .array_init => {854 .array_init => {
842 const pl_node = data[inst_index].pl_node;855 const pl_node = data[inst_index].pl_node;
843 const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);856 const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
844 const operands = file.zir.refSlice(extra.end, extra.data.operands_len);857 const operands = file.zir.refSlice(extra.end, extra.data.operands_len);
845 const array_data = try self.arena.alloc(DocData.WalkResult, operands.len);858 const array_data = try self.arena.alloc(usize, operands.len);
859
860 // TODO: make sure that you want the array to be fully normalized for real
861 // then update this code to conform to your choice.
862
863 var array_type: ?DocData.Expr = null;
846 for (operands) |op, idx| {864 for (operands) |op, idx| {
847 array_data[idx] = try self.walkRef(file, parent_scope, op);865 // we only ask to figure out type info for the first element
848 }866 // as it will be used later on to find out the array type!
867 const wr = try self.walkRef(file, parent_scope, op, idx == 0);
868
869 if (idx == 0) {
870 array_type = wr.typeRef;
871 }
849872
850 const at = try self.arena.create(DocData.WalkResult);873 // We know that Zir wraps every operand in an @as expression
851 at.* = .{ .type = @enumToInt(Ref.usize_type) };874 // so we want to peel it away and only save the target type
875 // once, since we need it later to define the array type.
876 array_data[idx] = wr.expr.as.exprArg;
877 }
852878
853 const type_slot_index = self.types.items.len;879 const type_slot_index = self.types.items.len;
854 try self.types.append(self.arena, .{880 try self.types.append(self.arena, .{
855 .Array = .{881 .Array = .{
856 .len = .{882 .len = .{
857 .int = .{883 .int = .{
858 .typeRef = at,
859 .value = operands.len,884 .value = operands.len,
860 .negated = false,885 .negated = false,
861 },886 },
862 },887 },
863 .child = try self.typeOfWalkResult(array_data[0]),888 .child = array_type.?,
864 },889 },
865 });890 });
866891
867 const t = try self.arena.create(DocData.WalkResult);892 return DocData.WalkResult{
868 t.* = .{ .type = type_slot_index };893 .typeRef = .{ .type = type_slot_index },
869 return DocData.WalkResult{ .array = .{894 .expr = .{ .array = array_data },
870 .typeRef = t,895 };
871 .data = array_data,
872 } };
873 },896 },
874 .float => {897 .float => {
875 const float = data[inst_index].float;898 const float = data[inst_index].float;
876
877 const t = try self.arena.create(DocData.WalkResult);
878 t.* = .{ .type = @enumToInt(Ref.comptime_float_type) };
879
880 return DocData.WalkResult{899 return DocData.WalkResult{
881 .float = .{900 .typeRef = .{ .type = @enumToInt(Ref.comptime_float_type) },
882 .typeRef = t,901 .expr = .{ .float = float },
883 .value = float,
884 },
885 };902 };
886 },903 },
887 .negate => {904 .negate => {
...@@ -890,8 +907,9 @@ fn walkInstruction(...@@ -890,8 +907,9 @@ fn walkInstruction(
890 file,907 file,
891 parent_scope,908 parent_scope,
892 un_node.operand,909 un_node.operand,
910 need_type,
893 );911 );
894 switch (operand) {912 switch (operand.expr) {
895 .int => |*int| int.negated = true,913 .int => |*int| int.negated = true,
896 else => {914 else => {
897 printWithContext(915 printWithContext(
...@@ -906,75 +924,93 @@ fn walkInstruction(...@@ -906,75 +924,93 @@ fn walkInstruction(
906 },924 },
907 .size_of => {925 .size_of => {
908 const un_node = data[inst_index].un_node;926 const un_node = data[inst_index].un_node;
909 var operand = try self.arena.create(DocData.WalkResult);927 const operand = try self.walkRef(
910 operand.* = try self.walkRef(
911 file,928 file,
912 parent_scope,929 parent_scope,
913 un_node.operand,930 un_node.operand,
931 false,
914 );932 );
915 return DocData.WalkResult{ .sizeOf = operand };933 const operand_index = self.exprs.items.len;
934 try self.exprs.append(self.arena, operand.expr);
935 return DocData.WalkResult{
936 .typeRef = .{ .type = @enumToInt(Ref.comptime_int_type) },
937 .expr = .{ .sizeOf = operand_index },
938 };
916 },939 },
917940
918 .typeof => {941 .typeof => {
919 const un_node = data[inst_index].un_node;942 const un_node = data[inst_index].un_node;
920 var operand = try self.arena.create(DocData.WalkResult);943 const operand = try self.walkRef(
921 operand.* = try self.walkRef(
922 file,944 file,
923 parent_scope,945 parent_scope,
924 un_node.operand,946 un_node.operand,
947 need_type,
925 );948 );
926 return DocData.WalkResult{ .typeOf = operand };949 const operand_index = self.exprs.items.len;
950 try self.exprs.append(self.arena, operand.expr);
951
952 return DocData.WalkResult{
953 .typeRef = operand.typeRef,
954 .expr = .{ .typeOf = operand_index },
955 };
927 },956 },
928 .as_node => {957 .as_node => {
929 const pl_node = data[inst_index].pl_node;958 const pl_node = data[inst_index].pl_node;
930 const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);959 const extra = file.zir.extraData(Zir.Inst.As, pl_node.payload_index);
931 const dest_type_walk = try self.walkRef(file, parent_scope, extra.data.dest_type);960 const dest_type_walk = try self.walkRef(
932 const dest_type_ref = dest_type_walk;961 file,
962 parent_scope,
963 extra.data.dest_type,
964 false,
965 );
933966
934 var operand = try self.walkRef(file, parent_scope, extra.data.operand);967 const operand = try self.walkRef(
968 file,
969 parent_scope,
970 extra.data.operand,
971 false,
972 );
973 const operand_idx = self.exprs.items.len;
974 try self.exprs.append(self.arena, operand.expr);
935975
936 switch (operand) {976 const dest_type_idx = self.exprs.items.len;
937 else => printWithContext(977 try self.exprs.append(self.arena, dest_type_walk.expr);
938 file,
939 inst_index,
940 "TODO: handle {s} in `walkInstruction.as_node`",
941 .{@tagName(operand)},
942 ),
943 .declRef, .refPath, .type, .string, .call, .enumLiteral => {},
944 // we don't do anything because up until now,
945 // I've only seen this used as such:
946 // @as(@as(type, Baz), .{})
947 // and we don't want to toss away the
948 // decl_val information (eg by replacing it with
949 // a WalkResult.type).
950 .comptimeExpr => {
951 self.comptime_exprs.items[operand.comptimeExpr].typeRef = dest_type_ref;
952 },
953 .int => operand.int.typeRef.* = dest_type_ref,
954 .@"struct" => operand.@"struct".typeRef.* = dest_type_ref,
955 .@"undefined" => operand.@"undefined".* = dest_type_ref,
956 }
957978
958 return operand;979 // TODO: there's something wrong with how both `as` and `WalkrResult`
980 // try to store type information.
981 return DocData.WalkResult{
982 .typeRef = dest_type_walk.expr,
983 .expr = .{
984 .as = .{
985 .typeRefArg = dest_type_idx,
986 .exprArg = operand_idx,
987 },
988 },
989 };
959 },990 },
960 .optional_type => {991 .optional_type => {
961 const un_node = data[inst_index].un_node;992 const un_node = data[inst_index].un_node;
962 var operand: DocData.WalkResult = try self.walkRef(993 const operand: DocData.WalkResult = try self.walkRef(
963 file,994 file,
964 parent_scope,995 parent_scope,
965 un_node.operand,996 un_node.operand,
997 false,
966 );998 );
967 const type_ref = operand;999
968 const res = DocData.WalkResult{ .type = self.types.items.len };1000 const operand_idx = self.types.items.len;
969 try self.types.append(self.arena, .{1001 try self.types.append(self.arena, .{
970 .Optional = .{ .name = "?TODO", .child = type_ref },1002 .Optional = .{ .name = "?TODO", .child = operand.expr },
971 });1003 });
972 return res;1004
1005 return DocData.WalkResult{
1006 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1007 .expr = .{ .type = operand_idx },
1008 };
973 },1009 },
974 .decl_val, .decl_ref => {1010 .decl_val, .decl_ref => {
975 const str_tok = data[inst_index].str_tok;1011 const str_tok = data[inst_index].str_tok;
976 const decls_slot_index = parent_scope.resolveDeclName(str_tok.start);1012 const decls_slot_index = parent_scope.resolveDeclName(str_tok.start);
977 return DocData.WalkResult{ .declRef = decls_slot_index };1013 return DocData.WalkResult{ .expr = .{ .declRef = decls_slot_index } };
978 },1014 },
979 .field_val, .field_call_bind, .field_ptr, .field_type => {1015 .field_val, .field_call_bind, .field_ptr, .field_type => {
980 // TODO: field type uses Zir.Inst.FieldType, it just happens to have the1016 // TODO: field type uses Zir.Inst.FieldType, it just happens to have the
...@@ -982,7 +1018,7 @@ fn walkInstruction(...@@ -982,7 +1018,7 @@ fn walkInstruction(
982 const pl_node = data[inst_index].pl_node;1018 const pl_node = data[inst_index].pl_node;
983 const extra = file.zir.extraData(Zir.Inst.Field, pl_node.payload_index);1019 const extra = file.zir.extraData(Zir.Inst.Field, pl_node.payload_index);
9841020
985 var path: std.ArrayListUnmanaged(DocData.WalkResult) = .{};1021 var path: std.ArrayListUnmanaged(DocData.Expr) = .{};
986 var lhs = @enumToInt(extra.data.lhs) - Ref.typed_value_map.len; // underflow = need to handle Refs1022 var lhs = @enumToInt(extra.data.lhs) - Ref.typed_value_map.len; // underflow = need to handle Refs
9871023
988 try path.append(self.arena, .{1024 try path.append(self.arena, .{
...@@ -1006,12 +1042,13 @@ fn walkInstruction(...@@ -1006,12 +1042,13 @@ fn walkInstruction(
1006 lhs = @enumToInt(lhs_extra.data.lhs) - Ref.typed_value_map.len; // underflow = need to handle Refs1042 lhs = @enumToInt(lhs_extra.data.lhs) - Ref.typed_value_map.len; // underflow = need to handle Refs
1007 }1043 }
10081044
1009 const wr = try self.walkInstruction(file, parent_scope, lhs);1045 // TODO: double check that we really don't need type info here
1010 try path.append(self.arena, wr);1046 const wr = try self.walkInstruction(file, parent_scope, lhs, false);
1047 try path.append(self.arena, wr.expr);
10111048
1012 // This way the data in `path` has the same ordering that the ref1049 // This way the data in `path` has the same ordering that the ref
1013 // path has in the text: most general component first.1050 // path has in the text: most general component first.
1014 std.mem.reverse(DocData.WalkResult, path.items);1051 std.mem.reverse(DocData.Expr, path.items);
10151052
1016 // Righ now, every element of `path` is a string except its first1053 // Righ now, every element of `path` is a string except its first
1017 // element (at index 0). We're now going to attempt to resolve each1054 // element (at index 0). We're now going to attempt to resolve each
...@@ -1026,7 +1063,7 @@ fn walkInstruction(...@@ -1026,7 +1063,7 @@ fn walkInstruction(
1026 // any value that depends on that will have to become a1063 // any value that depends on that will have to become a
1027 // comptimeExpr.1064 // comptimeExpr.
1028 try self.tryResolveRefPath(file, lhs, path.items);1065 try self.tryResolveRefPath(file, lhs, path.items);
1029 return DocData.WalkResult{ .refPath = path.items };1066 return DocData.WalkResult{ .expr = .{ .refPath = path.items } };
1030 },1067 },
1031 .int_type => {1068 .int_type => {
1032 const int_type = data[inst_index].int_type;1069 const int_type = data[inst_index].int_type;
...@@ -1037,28 +1074,37 @@ fn walkInstruction(...@@ -1037,28 +1074,37 @@ fn walkInstruction(
1037 try self.types.append(self.arena, .{1074 try self.types.append(self.arena, .{
1038 .Int = .{ .name = name },1075 .Int = .{ .name = name },
1039 });1076 });
1040 return DocData.WalkResult{ .type = self.types.items.len - 1 };1077 return DocData.WalkResult{
1078 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1079 .expr = .{ .type = self.types.items.len - 1 },
1080 };
1041 },1081 },
1042 .block => {1082 .block => {
1043 const res = DocData.WalkResult{ .comptimeExpr = self.comptime_exprs.items.len };1083 const res = DocData.WalkResult{ .expr = .{
1084 .comptimeExpr = self.comptime_exprs.items.len,
1085 } };
1044 try self.comptime_exprs.append(self.arena, .{1086 try self.comptime_exprs.append(self.arena, .{
1045 .code = "if(banana) 1 else 0",1087 .code = "if(banana) 1 else 0",
1046 .typeRef = .{ .type = 0 },
1047 });1088 });
1048 return res;1089 return res;
1049 },1090 },
1050 .block_inline => {1091 .block_inline => {
1051 return self.walkRef(file, parent_scope, getBlockInlineBreak(file.zir, inst_index));1092 return self.walkRef(
1093 file,
1094 parent_scope,
1095 getBlockInlineBreak(file.zir, inst_index),
1096 need_type,
1097 );
1052 },1098 },
1053 .struct_init => {1099 .struct_init => {
1054 const pl_node = data[inst_index].pl_node;1100 const pl_node = data[inst_index].pl_node;
1055 const extra = file.zir.extraData(Zir.Inst.StructInit, pl_node.payload_index);1101 const extra = file.zir.extraData(Zir.Inst.StructInit, pl_node.payload_index);
1056 const field_vals = try self.arena.alloc(1102 const field_vals = try self.arena.alloc(
1057 DocData.WalkResult.Struct.FieldVal,1103 DocData.Expr.FieldVal,
1058 extra.data.fields_len,1104 extra.data.fields_len,
1059 );1105 );
10601106
1061 const type_ref = try self.arena.create(DocData.WalkResult);1107 var type_ref: DocData.Expr = undefined;
1062 var idx = extra.end;1108 var idx = extra.end;
1063 for (field_vals) |*fv| {1109 for (field_vals) |*fv| {
1064 const init_extra = file.zir.extraData(Zir.Inst.StructInit.Item, idx);1110 const init_extra = file.zir.extraData(Zir.Inst.StructInit.Item, idx);
...@@ -1079,19 +1125,25 @@ fn walkInstruction(...@@ -1079,19 +1125,25 @@ fn walkInstruction(
1079 file,1125 file,
1080 parent_scope,1126 parent_scope,
1081 field_extra.data.container_type,1127 field_extra.data.container_type,
1128 false,
1082 );1129 );
1083 type_ref.* = wr;1130 type_ref = wr.expr;
1084 }1131 }
1085 break :blk file.zir.nullTerminatedString(field_extra.data.name_start);1132 break :blk file.zir.nullTerminatedString(field_extra.data.name_start);
1086 };1133 };
1087 const value = try self.walkRef(file, parent_scope, init_extra.data.init);1134 const value = try self.walkRef(
1135 file,
1136 parent_scope,
1137 init_extra.data.init,
1138 need_type,
1139 );
1088 fv.* = .{ .name = field_name, .val = value };1140 fv.* = .{ .name = field_name, .val = value };
1089 }1141 }
10901142
1091 return DocData.WalkResult{ .@"struct" = .{1143 return DocData.WalkResult{
1092 .typeRef = type_ref,1144 .typeRef = type_ref,
1093 .fieldVals = field_vals,1145 .expr = .{ .@"struct" = field_vals },
1094 } };1146 };
1095 },1147 },
1096 .error_set_decl => {1148 .error_set_decl => {
1097 const pl_node = data[inst_index].pl_node;1149 const pl_node = data[inst_index].pl_node;
...@@ -1122,7 +1174,10 @@ fn walkInstruction(...@@ -1122,7 +1174,10 @@ fn walkInstruction(
1122 },1174 },
1123 });1175 });
11241176
1125 return DocData.WalkResult{ .type = type_slot_index };1177 return DocData.WalkResult{
1178 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1179 .expr = .{ .type = type_slot_index },
1180 };
1126 },1181 },
1127 .param_anytype => {1182 .param_anytype => {
1128 // Analysis of anytype function params happens in `.func`.1183 // Analysis of anytype function params happens in `.func`.
...@@ -1134,9 +1189,8 @@ fn walkInstruction(...@@ -1134,9 +1189,8 @@ fn walkInstruction(
1134 const cte_slot_index = self.comptime_exprs.items.len;1189 const cte_slot_index = self.comptime_exprs.items.len;
1135 try self.comptime_exprs.append(self.arena, .{1190 try self.comptime_exprs.append(self.arena, .{
1136 .code = name,1191 .code = name,
1137 .typeRef = .{ .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr) },
1138 });1192 });
1139 return DocData.WalkResult{ .comptimeExpr = cte_slot_index };1193 return DocData.WalkResult{ .expr = .{ .comptimeExpr = cte_slot_index } };
1140 },1194 },
1141 .param, .param_comptime => {1195 .param, .param_comptime => {
1142 // See .param_anytype for more information.1196 // See .param_anytype for more information.
...@@ -1146,41 +1200,46 @@ fn walkInstruction(...@@ -1146,41 +1200,46 @@ fn walkInstruction(
1146 const cte_slot_index = self.comptime_exprs.items.len;1200 const cte_slot_index = self.comptime_exprs.items.len;
1147 try self.comptime_exprs.append(self.arena, .{1201 try self.comptime_exprs.append(self.arena, .{
1148 .code = name,1202 .code = name,
1149 .typeRef = .{ .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr) },
1150 });1203 });
1151 return DocData.WalkResult{ .comptimeExpr = cte_slot_index };1204 return DocData.WalkResult{ .expr = .{ .comptimeExpr = cte_slot_index } };
1152 },1205 },
1153 .call => {1206 .call => {
1154 const pl_node = data[inst_index].pl_node;1207 const pl_node = data[inst_index].pl_node;
1155 const extra = file.zir.extraData(Zir.Inst.Call, pl_node.payload_index);1208 const extra = file.zir.extraData(Zir.Inst.Call, pl_node.payload_index);
11561209
1157 const callee = try self.walkRef(file, parent_scope, extra.data.callee);1210 const callee = try self.walkRef(file, parent_scope, extra.data.callee, need_type);
11581211
1159 const args_len = extra.data.flags.args_len;1212 const args_len = extra.data.flags.args_len;
1160 var args = try self.arena.alloc(DocData.WalkResult, args_len);1213 var args = try self.arena.alloc(DocData.Expr, args_len);
1161 const arg_refs = file.zir.refSlice(extra.end, args_len);1214 const arg_refs = file.zir.refSlice(extra.end, args_len);
1162 for (arg_refs) |ref, idx| {1215 for (arg_refs) |ref, idx| {
1163 args[idx] = try self.walkRef(file, parent_scope, ref);1216 // TODO: consider toggling need_type to true if we ever want
1217 // to show discrepancies between the types of provided
1218 // arguments and the types declared in the function
1219 // signature for its parameters.
1220 const wr = try self.walkRef(file, parent_scope, ref, false);
1221 args[idx] = wr.expr;
1164 }1222 }
11651223
1166 // TODO: see if we can ever do something better than just always
1167 // resolve function calls to a comptimeExpr.
1168 const cte_slot_index = self.comptime_exprs.items.len;1224 const cte_slot_index = self.comptime_exprs.items.len;
1169 try self.comptime_exprs.append(self.arena, .{1225 try self.comptime_exprs.append(self.arena, .{
1170 .code = "func call",1226 .code = "func call",
1171 .typeRef = .{
1172 .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr),
1173 }, // TODO: extract return type from callee when available
1174 });1227 });
11751228
1176 const call_slot_index = self.calls.items.len;1229 const call_slot_index = self.calls.items.len;
1177 try self.calls.append(self.arena, .{1230 try self.calls.append(self.arena, .{
1178 .func = callee,1231 .func = callee.expr,
1179 .args = args,1232 .args = args,
1180 .ret = .{ .comptimeExpr = cte_slot_index },1233 .ret = .{ .comptimeExpr = cte_slot_index },
1181 });1234 });
11821235
1183 return DocData.WalkResult{ .call = call_slot_index };1236 return DocData.WalkResult{
1237 .typeRef = if (callee.typeRef) |tr| switch (tr) {
1238 .type => |func_type_idx| self.types.items[func_type_idx].Fn.ret,
1239 else => null,
1240 } else null,
1241 .expr = .{ .call = call_slot_index },
1242 };
1184 },1243 },
1185 .func, .func_inferred => {1244 .func, .func_inferred => {
1186 const type_slot_index = self.types.items.len;1245 const type_slot_index = self.types.items.len;
...@@ -1208,42 +1267,13 @@ fn walkInstruction(...@@ -1208,42 +1267,13 @@ fn walkInstruction(
1208 },1267 },
12091268
1210 .opaque_decl => return self.cteTodo("opaque {...}"),1269 .opaque_decl => return self.cteTodo("opaque {...}"),
1211 // .func => {
1212 // const type_slot_index = self.types.items.len;
1213 // try self.types.append(self.arena, .{ .Unanalyzed = {} });
1214 //
1215 // const result = try self.analyzeFunction(
1216 // file,
1217 // parent_scope,
1218 // inst_index,
1219 // self_ast_node_index,
1220 // type_slot_index,
1221 // );
1222 // if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
1223 // for (paths.items) |resume_info| {
1224 // try self.tryResolveRefPath(
1225 // resume_info.file,
1226 // inst_index,
1227 // resume_info.ref_path,
1228 // );
1229 // }
1230 //
1231 // _ = self.ref_paths_pending_on_types.remove(type_slot_index);
1232 // // TODO: we should deallocate the arraylist that holds all the
1233 // // decl paths. not doing it now since it's arena-allocated
1234 // // anyway, but maybe we should put it elsewhere.
1235 // }
1236 // return result;
1237 // },
1238 .variable => {1270 .variable => {
1239 const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);1271 const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
1240 var extra_index: usize = extended.operand;1272 var extra_index: usize = extended.operand;
1241 if (small.has_lib_name) extra_index += 1;1273 if (small.has_lib_name) extra_index += 1;
1242 if (small.has_align) extra_index += 1;1274 if (small.has_align) extra_index += 1;
12431275
1244 const value: DocData.WalkResult =1276 const value: DocData.WalkResult = if (small.has_init) .{ .expr = .{ .void = {} } } else .{ .expr = .{ .void = {} } };
1245 if (small.has_init)
1246 .{ .void = {} } else .{ .void = {} };
12471277
1248 return value;1278 return value;
1249 },1279 },
...@@ -1322,10 +1352,9 @@ fn walkInstruction(...@@ -1322,10 +1352,9 @@ fn walkInstruction(
1322 extra_index,1352 extra_index,
1323 );1353 );
13241354
1325 // const body = file.zir.extra[extra_index..][0..body_len];
1326 extra_index += body_len;1355 extra_index += body_len;
13271356
1328 var field_type_refs = try std.ArrayListUnmanaged(DocData.WalkResult).initCapacity(1357 var field_type_refs = try std.ArrayListUnmanaged(DocData.Expr).initCapacity(
1329 self.arena,1358 self.arena,
1330 fields_len,1359 fields_len,
1331 );1360 );
...@@ -1369,7 +1398,10 @@ fn walkInstruction(...@@ -1369,7 +1398,10 @@ fn walkInstruction(
1369 // anyway, but maybe we should put it elsewhere.1398 // anyway, but maybe we should put it elsewhere.
1370 }1399 }
13711400
1372 return DocData.WalkResult{ .type = type_slot_index };1401 return DocData.WalkResult{
1402 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1403 .expr = .{ .type = type_slot_index },
1404 };
1373 },1405 },
1374 .enum_decl => {1406 .enum_decl => {
1375 const type_slot_index = self.types.items.len;1407 const type_slot_index = self.types.items.len;
...@@ -1516,8 +1548,10 @@ fn walkInstruction(...@@ -1516,8 +1548,10 @@ fn walkInstruction(
1516 // decl paths. not doing it now since it's arena-allocated1548 // decl paths. not doing it now since it's arena-allocated
1517 // anyway, but maybe we should put it elsewhere.1549 // anyway, but maybe we should put it elsewhere.
1518 }1550 }
15191551 return DocData.WalkResult{
1520 return DocData.WalkResult{ .type = type_slot_index };1552 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1553 .expr = .{ .type = type_slot_index },
1554 };
1521 },1555 },
1522 .struct_decl => {1556 .struct_decl => {
1523 const type_slot_index = self.types.items.len;1557 const type_slot_index = self.types.items.len;
...@@ -1590,7 +1624,7 @@ fn walkInstruction(...@@ -1590,7 +1624,7 @@ fn walkInstruction(
1590 // const body = file.zir.extra[extra_index..][0..body_len];1624 // const body = file.zir.extra[extra_index..][0..body_len];
1591 extra_index += body_len;1625 extra_index += body_len;
15921626
1593 var field_type_refs: std.ArrayListUnmanaged(DocData.WalkResult) = .{};1627 var field_type_refs: std.ArrayListUnmanaged(DocData.Expr) = .{};
1594 var field_name_indexes: std.ArrayListUnmanaged(usize) = .{};1628 var field_name_indexes: std.ArrayListUnmanaged(usize) = .{};
1595 try self.collectStructFieldInfo(1629 try self.collectStructFieldInfo(
1596 file,1630 file,
...@@ -1626,11 +1660,16 @@ fn walkInstruction(...@@ -1626,11 +1660,16 @@ fn walkInstruction(
1626 // decl paths. not doing it now since it's arena-allocated1660 // decl paths. not doing it now since it's arena-allocated
1627 // anyway, but maybe we should put it elsewhere.1661 // anyway, but maybe we should put it elsewhere.
1628 }1662 }
16291663 return DocData.WalkResult{
1630 return DocData.WalkResult{ .type = type_slot_index };1664 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1665 .expr = .{ .type = type_slot_index },
1666 };
1631 },1667 },
1632 .this => {1668 .this => {
1633 return DocData.WalkResult{ .this = parent_scope.enclosing_type };1669 return DocData.WalkResult{
1670 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1671 .expr = .{ .this = parent_scope.enclosing_type },
1672 };
1634 },1673 },
1635 }1674 }
1636 },1675 },
...@@ -1793,7 +1832,7 @@ fn walkDecls(...@@ -1793,7 +1832,7 @@ fn walkDecls(
1793 .name = "test",1832 .name = "test",
1794 .isTest = true,1833 .isTest = true,
1795 .src = ast_node_index,1834 .src = ast_node_index,
1796 .value = .{ .type = 0 },1835 .value = .{ .expr = .{ .type = 0 } },
1797 .kind = "const",1836 .kind = "const",
1798 };1837 };
1799 continue;1838 continue;
...@@ -1827,9 +1866,9 @@ fn walkDecls(...@@ -1827,9 +1866,9 @@ fn walkDecls(
1827 };1866 };
18281867
1829 const walk_result = if (is_test) // TODO: decide if tests should show up at all1868 const walk_result = if (is_test) // TODO: decide if tests should show up at all
1830 DocData.WalkResult{ .void = {} }1869 DocData.WalkResult{ .expr = .{ .void = {} } }
1831 else1870 else
1832 try self.walkInstruction(file, scope, value_index);1871 try self.walkInstruction(file, scope, value_index, true);
18331872
1834 if (is_pub) {1873 if (is_pub) {
1835 try decl_indexes.append(self.arena, decls_slot_index);1874 try decl_indexes.append(self.arena, decls_slot_index);
...@@ -1857,7 +1896,7 @@ fn walkDecls(...@@ -1857,7 +1896,7 @@ fn walkDecls(
1857 .name = name,1896 .name = name,
1858 .isTest = is_test,1897 .isTest = is_test,
1859 .src = ast_node_index,1898 .src = ast_node_index,
1860 // .typeRef = decl_type_ref,1899 //.typeRef = decl_type_ref,
1861 .value = walk_result,1900 .value = walk_result,
1862 .kind = "const", // find where this information can be found1901 .kind = "const", // find where this information can be found
1863 };1902 };
...@@ -1906,7 +1945,7 @@ fn tryResolveRefPath(...@@ -1906,7 +1945,7 @@ fn tryResolveRefPath(
1906 /// File from which the decl path originates.1945 /// File from which the decl path originates.
1907 file: *File,1946 file: *File,
1908 inst_index: usize, // used only for panicWithContext1947 inst_index: usize, // used only for panicWithContext
1909 path: []DocData.WalkResult,1948 path: []DocData.Expr,
1910) error{OutOfMemory}!void {1949) error{OutOfMemory}!void {
1911 var i: usize = 0;1950 var i: usize = 0;
1912 outer: while (i < path.len - 1) : (i += 1) {1951 outer: while (i < path.len - 1) : (i += 1) {
...@@ -1922,7 +1961,7 @@ fn tryResolveRefPath(...@@ -1922,7 +1961,7 @@ fn tryResolveRefPath(
1922 .declRef => |decl_index| {1961 .declRef => |decl_index| {
1923 const decl = self.decls.items[decl_index];1962 const decl = self.decls.items[decl_index];
1924 if (decl._analyzed) {1963 if (decl._analyzed) {
1925 resolved_parent = decl.value;1964 resolved_parent = decl.value.expr;
1926 continue;1965 continue;
1927 }1966 }
19281967
...@@ -2004,7 +2043,7 @@ fn tryResolveRefPath(...@@ -2004,7 +2043,7 @@ fn tryResolveRefPath(
2004 "TODO: handle `{s}`in tryResolveRefPath\nInfo: {}",2043 "TODO: handle `{s}`in tryResolveRefPath\nInfo: {}",
2005 .{ @tagName(resolved_parent), resolved_parent },2044 .{ @tagName(resolved_parent), resolved_parent },
2006 );2045 );
2007 path[i + 1] = try self.cteTodo("match failure");2046 path[i + 1] = (try self.cteTodo("match failure")).expr;
2008 continue :outer;2047 continue :outer;
2009 },2048 },
2010 .comptimeExpr, .call => {2049 .comptimeExpr, .call => {
...@@ -2088,7 +2127,7 @@ fn tryResolveRefPath(...@@ -2088,7 +2127,7 @@ fn tryResolveRefPath(
2088 .{child_string},2127 .{child_string},
2089 );2128 );
20902129
2091 path[i + 1] = try self.cteTodo("match failure");2130 path[i + 1] = (try self.cteTodo("match failure")).expr;
2092 continue :outer;2131 continue :outer;
2093 },2132 },
2094 .Union => |t_union| {2133 .Union => |t_union| {
...@@ -2134,7 +2173,7 @@ fn tryResolveRefPath(...@@ -2134,7 +2173,7 @@ fn tryResolveRefPath(
2134 "failed to match `{s}` in union",2173 "failed to match `{s}` in union",
2135 .{child_string},2174 .{child_string},
2136 );2175 );
2137 path[i + 1] = try self.cteTodo("match failure");2176 path[i + 1] = (try self.cteTodo("match failure")).expr;
2138 continue :outer;2177 continue :outer;
2139 },2178 },
21402179
...@@ -2181,7 +2220,7 @@ fn tryResolveRefPath(...@@ -2181,7 +2220,7 @@ fn tryResolveRefPath(
2181 "failed to match `{s}` in struct",2220 "failed to match `{s}` in struct",
2182 .{child_string},2221 .{child_string},
2183 );2222 );
2184 path[i + 1] = try self.cteTodo("match failure");2223 path[i + 1] = (try self.cteTodo("match failure")).expr;
2185 continue :outer;2224 continue :outer;
2186 },2225 },
2187 },2226 },
...@@ -2214,7 +2253,7 @@ fn analyzeFunction(...@@ -2214,7 +2253,7 @@ fn analyzeFunction(
2214 const fn_info = file.zir.getFnInfo(@intCast(u32, inst_index));2253 const fn_info = file.zir.getFnInfo(@intCast(u32, inst_index));
22152254
2216 try self.ast_nodes.ensureUnusedCapacity(self.arena, fn_info.total_params_len);2255 try self.ast_nodes.ensureUnusedCapacity(self.arena, fn_info.total_params_len);
2217 var param_type_refs = try std.ArrayListUnmanaged(DocData.WalkResult).initCapacity(2256 var param_type_refs = try std.ArrayListUnmanaged(DocData.Expr).initCapacity(
2218 self.arena,2257 self.arena,
2219 fn_info.total_params_len,2258 fn_info.total_params_len,
2220 );2259 );
...@@ -2246,7 +2285,7 @@ fn analyzeFunction(...@@ -2246,7 +2285,7 @@ fn analyzeFunction(
2246 });2285 });
22472286
2248 param_type_refs.appendAssumeCapacity(2287 param_type_refs.appendAssumeCapacity(
2249 DocData.WalkResult{ .@"anytype" = {} },2288 DocData.Expr{ .@"anytype" = {} },
2250 );2289 );
2251 },2290 },
2252 .param, .param_comptime => {2291 .param, .param_comptime => {
...@@ -2267,9 +2306,9 @@ fn analyzeFunction(...@@ -2267,9 +2306,9 @@ fn analyzeFunction(
22672306
2268 const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];2307 const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];
2269 const break_operand = data[break_index].@"break".operand;2308 const break_operand = data[break_index].@"break".operand;
2270 const param_type_ref = try self.walkRef(file, scope, break_operand);2309 const param_type_ref = try self.walkRef(file, scope, break_operand, false);
22712310
2272 param_type_refs.appendAssumeCapacity(param_type_ref);2311 param_type_refs.appendAssumeCapacity(param_type_ref.expr);
2273 },2312 },
2274 }2313 }
2275 }2314 }
...@@ -2278,7 +2317,7 @@ fn analyzeFunction(...@@ -2278,7 +2317,7 @@ fn analyzeFunction(
2278 const ret_type_ref = blk: {2317 const ret_type_ref = blk: {
2279 const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];2318 const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
2280 const break_operand = data[last_instr_index].@"break".operand;2319 const break_operand = data[last_instr_index].@"break".operand;
2281 const wr = try self.walkRef(file, scope, break_operand);2320 const wr = try self.walkRef(file, scope, break_operand, false);
2282 break :blk wr;2321 break :blk wr;
2283 };2322 };
22842323
...@@ -2288,10 +2327,13 @@ fn analyzeFunction(...@@ -2288,10 +2327,13 @@ fn analyzeFunction(
2288 .name = "todo_name func",2327 .name = "todo_name func",
2289 .src = self_ast_node_index,2328 .src = self_ast_node_index,
2290 .params = param_type_refs.items,2329 .params = param_type_refs.items,
2291 .ret = ret_type_ref,2330 .ret = ret_type_ref.expr,
2292 },2331 },
2293 };2332 };
2294 return DocData.WalkResult{ .type = type_slot_index };2333 return DocData.WalkResult{
2334 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
2335 .expr = .{ .type = type_slot_index },
2336 };
2295}2337}
22962338
2297fn collectUnionFieldInfo(2339fn collectUnionFieldInfo(
...@@ -2299,7 +2341,7 @@ fn collectUnionFieldInfo(...@@ -2299,7 +2341,7 @@ fn collectUnionFieldInfo(
2299 file: *File,2341 file: *File,
2300 scope: *Scope,2342 scope: *Scope,
2301 fields_len: usize,2343 fields_len: usize,
2302 field_type_refs: *std.ArrayListUnmanaged(DocData.WalkResult),2344 field_type_refs: *std.ArrayListUnmanaged(DocData.Expr),
2303 field_name_indexes: *std.ArrayListUnmanaged(usize),2345 field_name_indexes: *std.ArrayListUnmanaged(usize),
2304 ei: usize,2346 ei: usize,
2305) !void {2347) !void {
...@@ -2344,8 +2386,8 @@ fn collectUnionFieldInfo(...@@ -2344,8 +2386,8 @@ fn collectUnionFieldInfo(
23442386
2345 // type2387 // type
2346 {2388 {
2347 const walk_result = try self.walkRef(file, scope, field_type);2389 const walk_result = try self.walkRef(file, scope, field_type, false);
2348 try field_type_refs.append(self.arena, walk_result);2390 try field_type_refs.append(self.arena, walk_result.expr);
2349 }2391 }
23502392
2351 // ast node2393 // ast node
...@@ -2368,7 +2410,7 @@ fn collectStructFieldInfo(...@@ -2368,7 +2410,7 @@ fn collectStructFieldInfo(
2368 file: *File,2410 file: *File,
2369 scope: *Scope,2411 scope: *Scope,
2370 fields_len: usize,2412 fields_len: usize,
2371 field_type_refs: *std.ArrayListUnmanaged(DocData.WalkResult),2413 field_type_refs: *std.ArrayListUnmanaged(DocData.Expr),
2372 field_name_indexes: *std.ArrayListUnmanaged(usize),2414 field_name_indexes: *std.ArrayListUnmanaged(usize),
2373 ei: usize,2415 ei: usize,
2374) !void {2416) !void {
...@@ -2410,8 +2452,8 @@ fn collectStructFieldInfo(...@@ -2410,8 +2452,8 @@ fn collectStructFieldInfo(
24102452
2411 // type2453 // type
2412 {2454 {
2413 const walk_result = try self.walkRef(file, scope, field_type);2455 const walk_result = try self.walkRef(file, scope, field_type, false);
2414 try field_type_refs.append(self.arena, walk_result);2456 try field_type_refs.append(self.arena, walk_result.expr);
2415 }2457 }
24162458
2417 // ast node2459 // ast node
...@@ -2436,13 +2478,17 @@ fn walkRef(...@@ -2436,13 +2478,17 @@ fn walkRef(
2436 file: *File,2478 file: *File,
2437 parent_scope: *Scope,2479 parent_scope: *Scope,
2438 ref: Ref,2480 ref: Ref,
2481 need_type: bool, // true when the caller needs also a typeRef for the return value
2439) !DocData.WalkResult {2482) !DocData.WalkResult {
2440 const enum_value = @enumToInt(ref);2483 const enum_value = @enumToInt(ref);
2441 if (enum_value <= @enumToInt(Ref.anyerror_void_error_union_type)) {2484 if (enum_value <= @enumToInt(Ref.anyerror_void_error_union_type)) {
2442 // We can just return a type that indexes into `types` with the2485 // We can just return a type that indexes into `types` with the
2443 // enum value because in the beginning we pre-filled `types` with2486 // enum value because in the beginning we pre-filled `types` with
2444 // the types that are listed in `Ref`.2487 // the types that are listed in `Ref`.
2445 return DocData.WalkResult{ .type = enum_value };2488 return DocData.WalkResult{
2489 .typeRef = .{ .type = @enumToInt(std.builtin.TypeId.Type) },
2490 .expr = .{ .type = enum_value },
2491 };
2446 } else if (enum_value < Ref.typed_value_map.len) {2492 } else if (enum_value < Ref.typed_value_map.len) {
2447 switch (ref) {2493 switch (ref) {
2448 else => {2494 else => {
...@@ -2451,69 +2497,62 @@ fn walkRef(...@@ -2451,69 +2497,62 @@ fn walkRef(
2451 });2497 });
2452 },2498 },
2453 .undef => {2499 .undef => {
2454 var t = try self.arena.create(DocData.WalkResult);2500 return DocData.WalkResult{ .expr = .@"undefined" };
2455 t.* = .void;
2456
2457 return DocData.WalkResult{ .@"undefined" = t };
2458 },2501 },
2459 .zero => {2502 .zero => {
2460 var t = try self.arena.create(DocData.WalkResult);2503 return DocData.WalkResult{
2461 t.* = .{ .type = @enumToInt(Ref.comptime_int_type) };2504 .typeRef = .{ .type = @enumToInt(Ref.comptime_int_type) },
2462 return DocData.WalkResult{ .int = .{2505 .expr = .{ .int = .{ .value = 0 } },
2463 .typeRef = t,2506 };
2464 .value = 0,
2465 } };
2466 },2507 },
2467 .one => {2508 .one => {
2468 var t = try self.arena.create(DocData.WalkResult);2509 return DocData.WalkResult{
2469 t.* = .{ .type = @enumToInt(Ref.comptime_int_type) };2510 .typeRef = .{ .type = @enumToInt(Ref.comptime_int_type) },
2470 return DocData.WalkResult{ .int = .{2511 .expr = .{ .int = .{ .value = 1 } },
2471 .typeRef = t,2512 };
2472 .value = 1,
2473 } };
2474 },2513 },
24752514
2476 .void_value => {2515 .void_value => {
2477 return DocData.WalkResult{ .void = {} };2516 return DocData.WalkResult{
2517 .typeRef = .{ .type = @enumToInt(Ref.void_type) },
2518 .expr = .{ .void = {} },
2519 };
2478 },2520 },
2479 .unreachable_value => {2521 .unreachable_value => {
2480 return DocData.WalkResult{ .@"unreachable" = {} };2522 return DocData.WalkResult{
2523 .typeRef = .{ .type = @enumToInt(Ref.noreturn_type) },
2524 .expr = .{ .@"unreachable" = {} },
2525 };
2481 },2526 },
2482 .null_value => {2527 .null_value => {
2483 var t = try self.arena.create(DocData.WalkResult);2528 return DocData.WalkResult{ .expr = .@"null" };
2484 t.* = .void;
2485 return DocData.WalkResult{ .@"null" = t };
2486 },2529 },
2487 .bool_true => {2530 .bool_true => {
2488 return DocData.WalkResult{ .bool = true };2531 return DocData.WalkResult{
2532 .typeRef = .{ .type = @enumToInt(Ref.bool_type) },
2533 .expr = .{ .bool = true },
2534 };
2489 },2535 },
2490 .bool_false => {2536 .bool_false => {
2491 return DocData.WalkResult{ .bool = false };2537 return DocData.WalkResult{
2538 .typeRef = .{ .type = @enumToInt(Ref.bool_type) },
2539 .expr = .{ .bool = false },
2540 };
2492 },2541 },
2493 .empty_struct => {2542 .empty_struct => {
2494 var t = try self.arena.create(DocData.WalkResult);2543 return DocData.WalkResult{ .expr = .{ .@"struct" = &.{} } };
2495 t.* = .void;
2496
2497 return DocData.WalkResult{ .@"struct" = .{
2498 .typeRef = t,
2499 .fieldVals = &.{},
2500 } };
2501 },2544 },
2502 .zero_usize => {2545 .zero_usize => {
2503 var t = try self.arena.create(DocData.WalkResult);2546 return DocData.WalkResult{
2504 t.* = .{ .type = @enumToInt(Ref.usize_type) };2547 .typeRef = .{ .type = @enumToInt(Ref.usize_type) },
2505 return DocData.WalkResult{ .int = .{2548 .expr = .{ .int = .{ .value = 0 } },
2506 .typeRef = t,2549 };
2507 .value = 0,
2508 } };
2509 },2550 },
2510 .one_usize => {2551 .one_usize => {
2511 var t = try self.arena.create(DocData.WalkResult);2552 return DocData.WalkResult{
2512 t.* = .{ .type = @enumToInt(Ref.usize_type) };2553 .typeRef = .{ .type = @enumToInt(Ref.usize_type) },
2513 return DocData.WalkResult{ .int = .{2554 .expr = .{ .int = .{ .value = 1 } },
2514 .typeRef = t,2555 };
2515 .value = 1,
2516 } };
2517 },2556 },
2518 // TODO: dunno what to do with those2557 // TODO: dunno what to do with those
2519 // .calling_convention_c => {2558 // .calling_convention_c => {
...@@ -2537,29 +2576,10 @@ fn walkRef(...@@ -2537,29 +2576,10 @@ fn walkRef(
2537 }2576 }
2538 } else {2577 } else {
2539 const zir_index = enum_value - Ref.typed_value_map.len;2578 const zir_index = enum_value - Ref.typed_value_map.len;
2540 return self.walkInstruction(file, parent_scope, zir_index);2579 return self.walkInstruction(file, parent_scope, zir_index, need_type);
2541 }2580 }
2542}2581}
25432582
2544/// Given a WalkResult, tries to find its type.
2545/// Used to analyze instructions like `array_init`, which require us to
2546/// inspect its first element to find out the array type.
2547fn typeOfWalkResult(self: *Autodoc, wr: DocData.WalkResult) !DocData.WalkResult {
2548 return switch (wr) {
2549 else => {
2550 std.debug.print(
2551 "TODO: handle `{s}` in typeOfWalkResult\n",
2552 .{@tagName(wr)},
2553 );
2554 return self.cteTodo(@tagName(wr));
2555 },
2556 .type => .{ .type = @enumToInt(DocData.DocTypeKinds.Type) },
2557 .int => |v| v.typeRef.*,
2558 .float => |v| v.typeRef.*,
2559 .array => |v| v.typeRef.*,
2560 };
2561}
2562
2563fn getBlockInlineBreak(zir: Zir, inst_index: usize) Zir.Inst.Ref {2583fn getBlockInlineBreak(zir: Zir, inst_index: usize) Zir.Inst.Ref {
2564 const tags = zir.instructions.items(.tag);2584 const tags = zir.instructions.items(.tag);
2565 const data = zir.instructions.items(.data);2585 const data = zir.instructions.items(.data);
...@@ -2585,7 +2605,6 @@ fn cteTodo(self: *Autodoc, msg: []const u8) error{OutOfMemory}!DocData.WalkResul...@@ -2585,7 +2605,6 @@ fn cteTodo(self: *Autodoc, msg: []const u8) error{OutOfMemory}!DocData.WalkResul
2585 const cte_slot_index = self.comptime_exprs.items.len;2605 const cte_slot_index = self.comptime_exprs.items.len;
2586 try self.comptime_exprs.append(self.arena, .{2606 try self.comptime_exprs.append(self.arena, .{
2587 .code = msg,2607 .code = msg,
2588 .typeRef = .{ .type = @enumToInt(DocData.DocTypeKinds.ComptimeExpr) },
2589 });2608 });
2590 return DocData.WalkResult{ .comptimeExpr = cte_slot_index };2609 return DocData.WalkResult{ .expr = .{ .comptimeExpr = cte_slot_index } };
2591}2610}