authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-05-22 16:21:49+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
logaa545dbd1e7a8b1179f8e4714324a242cde4d41f
tree744379e069c21b6e9c47bf67be841c2e69afef23
parentcf685c1132113b867f1476f4cd9d7a47d96a4782

autodoc: improve frontend rendering


2 files changed, 326 insertions(+), 406 deletions(-)

lib/docs/main.js+307-400
...@@ -32,6 +32,13 @@...@@ -32,6 +32,13 @@
32 } TypeKind32 } TypeKind
33*/33*/
3434
35/**
36 * @typedef {{
37 typeRef: Expr?,
38 expr: Expr,
39 }} WalkResult
40*/
41
35/**42/**
36 * @typedef {{43 * @typedef {{
37 void: {},44 void: {},
...@@ -40,20 +47,20 @@...@@ -40,20 +47,20 @@
40 type: number,47 type: number,
41 comptimeExpr: number,48 comptimeExpr: number,
42 call: number,49 call: number,
43 int: { typeRef: WalkResult; value: number },50 int: number,
44 float: { typeRef: WalkResult; value: number },51 float: number,
45 bool: boolean,52 bool: boolean,
46 undefined: WalkResult,53 undefined: WalkResult,
47 null: WalkResult,54 null: WalkResult,
48 typeOf: WalkResult,55 typeOf: WalkResult,
49 compileError: string,56 compileError: string
50 string: string,57 string: string,
51 struct: Struct,58 struct: Expr[],
52 refPath: WalkResult[],59 refPath: Expr[],
53 declRef: number,60 declRef: number,
54 array: ZigArray,61 array: ZigArray,
55 enumLiteral: string,62 enumLiteral: string,
56 }} WalkResult63 }} Expr
57*/64*/
5865
59/**66/**
...@@ -128,7 +135,7 @@...@@ -128,7 +135,7 @@
128* @typedef {{135* @typedef {{
129 kind: number,136 kind: number,
130 name: string,137 name: string,
131 child: WalkResult138 child: Expr,
132}} OptionalType139}} OptionalType
133*/140*/
134141
...@@ -148,9 +155,9 @@...@@ -148,9 +155,9 @@
148155
149/**156/**
150 * @typedef {{157 * @typedef {{
151 func: WalkResult,158 func: Expr,
152 args: WalkResult[],159 args: Expr[],
153 ret: WalkResult,160 ret: Expr,
154 }} Call161 }} Call
155*/162*/
156163
...@@ -188,13 +195,6 @@...@@ -188,13 +195,6 @@
188 }} Package195 }} Package
189*/196*/
190197
191/**
192 * @typedef {{
193 typeRef: WalkResult,
194 fieldVals: WalkResult[],
195 }} Struct
196*/
197
198/**198/**
199 * @typedef {{199 * @typedef {{
200 typeRef: WalkResult,200 typeRef: WalkResult,
...@@ -391,13 +391,13 @@ var zigAnalysis;...@@ -391,13 +391,13 @@ var zigAnalysis;
391 return isType(x) && typeKindIsContainer(/** @type {Type} */(x).kind) ;391 return isType(x) && typeKindIsContainer(/** @type {Type} */(x).kind) ;
392 }392 }
393393
394 /** @param {WalkResult} wr */394 /** @param {Expr} expr */
395 function typeShorthandName(wr) {395 function typeShorthandName(expr) {
396 let resolvedWr = resolveValue(wr);396 let resolvedExpr = resolveValue({expr: expr});
397 if (!("type" in resolvedWr)) {397 if (!("type" in resolvedExpr)) {
398 return null;398 return null;
399 }399 }
400 let type = /** @type {Type} */(zigAnalysis.types[resolvedWr.type]);400 let type = /** @type {Type} */(zigAnalysis.types[resolvedExpr.type]);
401401
402 outer: for (let i = 0; i < 10000; i += 1) {402 outer: for (let i = 0; i < 10000; i += 1) {
403 switch (type.kind) {403 switch (type.kind) {
...@@ -472,16 +472,24 @@ var zigAnalysis;...@@ -472,16 +472,24 @@ var zigAnalysis;
472 while(i < 1000) {472 while(i < 1000) {
473 i += 1;473 i += 1;
474474
475 if ("refPath" in value) {475 if ("refPath" in value.expr) {
476 value = value.refPath[value.refPath.length -1];476 value = {expr: value.expr.refPath[value.expr.refPath.length -1]};
477 continue;477 continue;
478 }478 }
479479
480 if ("declRef" in value) {480 if ("declRef" in value.expr) {
481 value = zigAnalysis.decls[value.declRef].value;481 value = zigAnalysis.decls[value.expr.declRef].value;
482 continue;482 continue;
483 }483 }
484484
485// if ("as" in value.expr) {
486// value = {
487// typeRef: zigAnalysis.exprs[value.expr.as.typeRefArg],
488// expr: zigAnalysis.exprs[value.expr.as.exprArg],
489// };
490// continue;
491// }
492
485 return value;493 return value;
486494
487 }495 }
...@@ -493,89 +501,89 @@ var zigAnalysis;...@@ -493,89 +501,89 @@ var zigAnalysis;
493 * @param {Decl} decl501 * @param {Decl} decl
494 * @return {WalkResult}502 * @return {WalkResult}
495 */503 */
496 function typeOfDecl(decl){504// function typeOfDecl(decl){
497 return decl.value.typeRef;505// return decl.value.typeRef;
498506//
499 let i = 0;507// let i = 0;
500 while(i < 1000) {508// while(i < 1000) {
501 i += 1;509// i += 1;
502 console.assert(isDecl(decl));510// console.assert(isDecl(decl));
503 if ("type" in decl.value) {511// if ("type" in decl.value) {
504 return /** @type {WalkResult} */({ type: typeTypeId });512// return /** @type {WalkResult} */({ type: typeTypeId });
505 }
506
507// if ("string" in decl.value) {
508// return /** @type {WalkResult} */({ type: {
509// kind: typeKinds.Pointer,
510// size: pointerSizeEnum.One,
511// child: });
512// }513// }
513514//
514 if ("refPath" in decl.value) {515//// if ("string" in decl.value) {
515 decl = /** @type {Decl} */({516//// return /** @type {WalkResult} */({ type: {
516 value: decl.value.refPath[decl.value.refPath.length -1]517//// kind: typeKinds.Pointer,
517 });518//// size: pointerSizeEnum.One,
518 continue;519//// child: });
519 }520//// }
520521//
521 if ("declRef" in decl.value) {522// if ("refPath" in decl.value) {
522 decl = zigAnalysis.decls[decl.value.declRef];523// decl = /** @type {Decl} */({
523 continue;524// value: decl.value.refPath[decl.value.refPath.length -1]
524 }525// });
525526// continue;
526 if ("int" in decl.value) {527// }
527 return decl.value.int.typeRef;528//
528 }529// if ("declRef" in decl.value) {
529530// decl = zigAnalysis.decls[decl.value.declRef];
530 if ("float" in decl.value) {531// continue;
531 return decl.value.float.typeRef;532// }
532 }533//
533534// if ("int" in decl.value) {
534 if ("array" in decl.value) {535// return decl.value.int.typeRef;
535 return decl.value.array.typeRef;536// }
536 }537//
537538// if ("float" in decl.value) {
538 if ("struct" in decl.value) {539// return decl.value.float.typeRef;
539 return decl.value.struct.typeRef;540// }
540 }541//
541542// if ("array" in decl.value) {
542 if ("comptimeExpr" in decl.value) {543// return decl.value.array.typeRef;
543 const cte = zigAnalysis.comptimeExprs[decl.value.comptimeExpr];544// }
544 return cte.typeRef;545//
545 }546// if ("struct" in decl.value) {
546547// return decl.value.struct.typeRef;
547 if ("call" in decl.value) {548// }
548 const fn_call = zigAnalysis.calls[decl.value.call];549//
549 let fn_decl = undefined;550// if ("comptimeExpr" in decl.value) {
550 if ("declRef" in fn_call.func) {551// const cte = zigAnalysis.comptimeExprs[decl.value.comptimeExpr];
551 fn_decl = zigAnalysis.decls[fn_call.func.declRef];552// return cte.typeRef;
552 } else if ("refPath" in fn_call.func) {553// }
553 console.assert("declRef" in fn_call.func.refPath[fn_call.func.refPath.length -1]);554//
554 fn_decl = zigAnalysis.decls[fn_call.func.refPath[fn_call.func.refPath.length -1].declRef];555// if ("call" in decl.value) {
555 } else throw {};556// const fn_call = zigAnalysis.calls[decl.value.call];
556557// let fn_decl = undefined;
557 const fn_decl_value = resolveValue(fn_decl.value);558// if ("declRef" in fn_call.func) {
558 console.assert("type" in fn_decl_value); //TODO handle comptimeExpr559// fn_decl = zigAnalysis.decls[fn_call.func.declRef];
559 const fn_type = /** @type {Fn} */(zigAnalysis.types[fn_decl_value.type]);560// } else if ("refPath" in fn_call.func) {
560 console.assert(fn_type.kind === typeKinds.Fn);561// console.assert("declRef" in fn_call.func.refPath[fn_call.func.refPath.length -1]);
561 return fn_type.ret;562// fn_decl = zigAnalysis.decls[fn_call.func.refPath[fn_call.func.refPath.length -1].declRef];
562 }563// } else throw {};
563564//
564 if ("void" in decl.value) {565// const fn_decl_value = resolveValue(fn_decl.value);
565 return /** @type {WalkResult} */({ type: typeTypeId });566// console.assert("type" in fn_decl_value); //TODO handle comptimeExpr
566 }567// const fn_type = /** @type {Fn} */(zigAnalysis.types[fn_decl_value.type]);
567568// console.assert(fn_type.kind === typeKinds.Fn);
568 if ("bool" in decl.value) {569// return fn_type.ret;
569 return /** @type {WalkResult} */({ type: typeKinds.Bool });570// }
570 }571//
571572// if ("void" in decl.value) {
572 console.log("TODO: handle in `typeOfDecl` more cases: ", decl);573// return /** @type {WalkResult} */({ type: typeTypeId });
573 console.assert(false);574// }
574 throw {};575//
575 }576// if ("bool" in decl.value) {
576 console.assert(false);577// return /** @type {WalkResult} */({ type: typeKinds.Bool });
577 return /** @type {WalkResult} */({});578// }
578 }579//
580// console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
581// console.assert(false);
582// throw {};
583// }
584// console.assert(false);
585// return /** @type {WalkResult} */({});
586// }
579587
580 function render() {588 function render() {
581 domStatus.classList.add("hidden");589 domStatus.classList.add("hidden");
...@@ -637,7 +645,7 @@ var zigAnalysis;...@@ -637,7 +645,7 @@ var zigAnalysis;
637 return render404();645 return render404();
638 }646 }
639647
640 let childDeclValue = resolveValue(/** @type {Decl} */(childDecl).value);648 let childDeclValue = resolveValue(/** @type {Decl} */(childDecl).value).expr;
641 if ("type" in childDeclValue) {649 if ("type" in childDeclValue) {
642650
643 const t = zigAnalysis.types[childDeclValue.type];651 const t = zigAnalysis.types[childDeclValue.type];
...@@ -674,7 +682,7 @@ var zigAnalysis;...@@ -674,7 +682,7 @@ var zigAnalysis;
674 }682 }
675683
676 if (lastIsDecl && last.kind === 'const') {684 if (lastIsDecl && last.kind === 'const') {
677 let typeObj = zigAnalysis.types[resolveValue(/** @type {Decl} */(last).value).type];685 let typeObj = zigAnalysis.types[resolveValue(/** @type {Decl} */(last).value).expr.type];
678 if (typeObj && typeObj.kind === typeKinds.Fn) {686 if (typeObj && typeObj.kind === typeKinds.Fn) {
679 return renderFn(/** @type {Decl} */(last));687 return renderFn(/** @type {Decl} */(last));
680 }688 }
...@@ -721,11 +729,22 @@ var zigAnalysis;...@@ -721,11 +729,22 @@ var zigAnalysis;
721729
722 /** @param {Decl} fnDecl */730 /** @param {Decl} fnDecl */
723 function renderFn(fnDecl) {731 function renderFn(fnDecl) {
732 if ("refPath" in fnDecl.value.expr) {
733 let last = fnDecl.value.expr.refPath.length - 1;
734 let lastExpr = fnDecl.value.expr.refPath[last];
735 console.assert("declRef" in lastExpr);
736 fnDecl = zigAnalysis.decls[lastExpr.declRef];
737 }
738
724 let value = resolveValue(fnDecl.value);739 let value = resolveValue(fnDecl.value);
725 console.assert("type" in value);740 console.assert("type" in value.expr);
726 let typeObj = /** @type {Fn} */(zigAnalysis.types[value.type]);741 let typeObj = /** @type {Fn} */(zigAnalysis.types[value.expr.type]);
727742
728 domFnProtoCode.innerHTML = typeValueName(value, true, true, fnDecl);743 domFnProtoCode.innerHTML = exprName(value.expr, {
744 wantHtml: true,
745 wantLink: true,
746 fnDecl,
747 });
729748
730 let docsSource = null;749 let docsSource = null;
731 let srcNode = zigAnalysis.astNodes[fnDecl.src];750 let srcNode = zigAnalysis.astNodes[fnDecl.src];
...@@ -733,23 +752,26 @@ var zigAnalysis;...@@ -733,23 +752,26 @@ var zigAnalysis;
733 docsSource = srcNode.docs;752 docsSource = srcNode.docs;
734 }753 }
735754
736 let retIndex = resolveValue(typeObj.ret).type;
737 renderFnParamDocs(fnDecl, typeObj);755 renderFnParamDocs(fnDecl, typeObj);
738756
739 let errSetTypeIndex = /** @type {number | null} */(null);757 let retExpr = resolveValue({expr:typeObj.ret}).expr;
740 let retType = zigAnalysis.types[retIndex];758 if ("type" in retExpr) {
741 if (retType.kind === typeKinds.ErrorSet) {759 let retIndex = retExpr.type;
742 errSetTypeIndex = retIndex;760 let errSetTypeIndex = /** @type {number | null} */(null);
743 } else if (retType.kind === typeKinds.ErrorUnion) {761 let retType = zigAnalysis.types[retIndex];
744 errSetTypeIndex = /** @type {ErrUnionType} */(retType).err.type;762 if (retType.kind === typeKinds.ErrorSet) {
745 }763 errSetTypeIndex = retIndex;
746 if (errSetTypeIndex != null) {764 } else if (retType.kind === typeKinds.ErrorUnion) {
747 let errSetType = /** @type {ErrSetType} */(zigAnalysis.types[errSetTypeIndex]);765 errSetTypeIndex = /** @type {ErrUnionType} */(retType).err.type;
748 renderErrorSet(errSetType);766 }
767 if (errSetTypeIndex != null) {
768 let errSetType = /** @type {ErrSetType} */(zigAnalysis.types[errSetTypeIndex]);
769 renderErrorSet(errSetType);
770 }
749 }771 }
750772
751 let protoSrcIndex = fnDecl.src;773 let protoSrcIndex = fnDecl.src;
752 if (typeIsGenericFn(value.type)) {774 if (typeIsGenericFn(value.expr.type)) {
753 throw "TODO";775 throw "TODO";
754 // let instantiations = nodesToFnsMap[protoSrcIndex];776 // let instantiations = nodesToFnsMap[protoSrcIndex];
755 // let calls = nodesToCallsMap[protoSrcIndex];777 // let calls = nodesToCallsMap[protoSrcIndex];
...@@ -827,7 +849,7 @@ var zigAnalysis;...@@ -827,7 +849,7 @@ var zigAnalysis;
827 if (isVarArgs && i === typeObj.params.length - 1) {849 if (isVarArgs && i === typeObj.params.length - 1) {
828 html += '...';850 html += '...';
829 } else {851 } else {
830 let name = typeValueName(value, false, false);852 let name = exprName(value, {wantHtml: false, wantLink: false});
831 html += '<span class="tok-kw">' + name + '</span>';853 html += '<span class="tok-kw">' + name + '</span>';
832 }854 }
833855
...@@ -1017,19 +1039,72 @@ var zigAnalysis;...@@ -1017,19 +1039,72 @@ var zigAnalysis;
1017 listDom.removeChild(listDom.lastChild);1039 listDom.removeChild(listDom.lastChild);
1018 }1040 }
1019 }1041 }
1020
1021 /**1042 /**
1022 * @typedef {{1043 * @param {WalkResult} wr,
1023 wantHtml: boolean,1044 * @return {Expr}
1024 }} RenderWrOptions1045 */
1025 * @param {WalkResult} wr,1046 function walkResultTypeRef(wr) {
1026 * @param {RenderWrOptions} opts,1047 if (wr.typeRef) return wr.typeRef;
1027 * @return {string}1048 return walkResultTypeRef(resolveValue(wr));
1049 }
1050 /**
1051 * @typedef {{
1052 wantHtml: boolean,
1053 }} RenderWrOptions
1054 * @param {Expr} expr,
1055 * @param {RenderWrOptions} opts,
1056 * @return {string}
1028 */1057 */
1029
1030 function exprName(expr, opts) {1058 function exprName(expr, opts) {
1031 const activeField = Object.keys(expr)[0];1059 switch (Object.keys(expr)[0]) {
1032 switch (activeField) {1060 default: throw "oh no";
1061 case "array": {
1062 let payloadHtml = ".{";
1063 for (let i = 0; i < expr.array.length; i++) {
1064 if (i != 0) payloadHtml += ", ";
1065 let elem = zigAnalysis.exprs[expr.array[i]];
1066 payloadHtml += exprName(elem);
1067 }
1068 return payloadHtml + "}";
1069 }
1070 case "comptimeExpr": {
1071 return "[ComptimeExpr]";
1072 }
1073 case "call": {
1074 let call = zigAnalysis.calls[expr.call];
1075 let payloadHtml = "";
1076
1077
1078 switch(Object.keys(call.func)[0]){
1079 default: throw "TODO";
1080 case "declRef":
1081 case "refPath": {
1082 payloadHtml += exprName(call.func);
1083 break;
1084 }
1085 }
1086 payloadHtml += "(";
1087
1088 for (let i = 0; i < call.args.length; i++) {
1089 if (i != 0) payloadHtml += ", ";
1090 payloadHtml += exprName(call.args[i]);
1091 }
1092
1093 payloadHtml += ")";
1094 return payloadHtml;
1095 }
1096 case "as": {
1097 const typeRefArg = zigAnalysis.exprs[expr.as.typeRefArg];
1098 const exprArg = zigAnalysis.exprs[expr.as.exprArg];
1099 return "@as(" + exprName(typeRefArg, opts) +
1100 ", " + exprName(exprArg, opts) + ")";
1101 }
1102 case "declRef": {
1103 return zigAnalysis.decls[expr.declRef].name;
1104 }
1105 case "refPath": {
1106 return expr.refPath.map(x => exprName(x, opts)).join(".");
1107 }
1033 case "int": {1108 case "int": {
1034 return "" + expr.int;1109 return "" + expr.int;
1035 }1110 }
...@@ -1047,8 +1122,12 @@ var zigAnalysis;...@@ -1047,8 +1122,12 @@ var zigAnalysis;
10471122
1048 case "type": {1123 case "type": {
1049 let name = "";1124 let name = "";
1050 const typeObj = zigAnalysis.types[expr.type];1125
1126 let typeObj = expr.type;
1127 if (typeof typeObj === 'number') typeObj = zigAnalysis.types[typeObj];
1128
1051 switch (typeObj.kind) {1129 switch (typeObj.kind) {
1130 default: throw "TODO";
1052 case typeKinds.Array:1131 case typeKinds.Array:
1053 {1132 {
1054 let arrayObj = /** @type {ArrayType} */(typeObj);1133 let arrayObj = /** @type {ArrayType} */(typeObj);
...@@ -1064,8 +1143,7 @@ var zigAnalysis;...@@ -1064,8 +1143,7 @@ var zigAnalysis;
1064 return name;1143 return name;
1065 }1144 }
1066 case typeKinds.Optional:1145 case typeKinds.Optional:
10671146 return "?" + exprName(/**@type {OptionalType} */(typeObj).child, opts);
1068 return "?" + typeValueName(/**@type {OptionalType} */(typeObj).child, wantHtml, wantSubLink, fnDecl, linkFnNameDecl);
1069 case typeKinds.Pointer:1147 case typeKinds.Pointer:
1070 {1148 {
1071 let ptrObj = /** @type {PointerType} */(typeObj);1149 let ptrObj = /** @type {PointerType} */(typeObj);
...@@ -1135,7 +1213,7 @@ var zigAnalysis;...@@ -1135,7 +1213,7 @@ var zigAnalysis;
1135 {1213 {
1136 let floatObj = /** @type {NumberType} */ (typeObj);1214 let floatObj = /** @type {NumberType} */ (typeObj);
11371215
1138 if (wantHtml) {1216 if (opts.wantHtml) {
1139 return '<span class="tok-type">' + floatObj.name + '</span>';1217 return '<span class="tok-type">' + floatObj.name + '</span>';
1140 } else {1218 } else {
1141 return floatObj.name;1219 return floatObj.name;
...@@ -1152,43 +1230,43 @@ var zigAnalysis;...@@ -1152,43 +1230,43 @@ var zigAnalysis;
1152 }1230 }
1153 }1231 }
1154 case typeKinds.ComptimeInt:1232 case typeKinds.ComptimeInt:
1155 if (wantHtml) {1233 if (opts.wantHtml) {
1156 return '<span class="tok-type">comptime_int</span>';1234 return '<span class="tok-type">comptime_int</span>';
1157 } else {1235 } else {
1158 return "comptime_int";1236 return "comptime_int";
1159 }1237 }
1160 case typeKinds.ComptimeFloat:1238 case typeKinds.ComptimeFloat:
1161 if (wantHtml) {1239 if (opts.wantHtml) {
1162 return '<span class="tok-type">comptime_float</span>';1240 return '<span class="tok-type">comptime_float</span>';
1163 } else {1241 } else {
1164 return "comptime_float";1242 return "comptime_float";
1165 }1243 }
1166 case typeKinds.Type:1244 case typeKinds.Type:
1167 if (wantHtml) {1245 if (opts.wantHtml) {
1168 return '<span class="tok-type">type</span>';1246 return '<span class="tok-type">type</span>';
1169 } else {1247 } else {
1170 return "type";1248 return "type";
1171 }1249 }
1172 case typeKinds.Bool:1250 case typeKinds.Bool:
1173 if (wantHtml) {1251 if (opts.wantHtml) {
1174 return '<span class="tok-type">bool</span>';1252 return '<span class="tok-type">bool</span>';
1175 } else {1253 } else {
1176 return "bool";1254 return "bool";
1177 }1255 }
1178 case typeKinds.Void:1256 case typeKinds.Void:
1179 if (wantHtml) {1257 if (opts.wantHtml) {
1180 return '<span class="tok-type">void</span>';1258 return '<span class="tok-type">void</span>';
1181 } else {1259 } else {
1182 return "void";1260 return "void";
1183 }1261 }
1184 case typeKinds.EnumLiteral:1262 case typeKinds.EnumLiteral:
1185 if (wantHtml) {1263 if (opts.wantHtml) {
1186 return '<span class="tok-type">(enum literal)</span>';1264 return '<span class="tok-type">(enum literal)</span>';
1187 } else {1265 } else {
1188 return "(enum literal)";1266 return "(enum literal)";
1189 }1267 }
1190 case typeKinds.NoReturn:1268 case typeKinds.NoReturn:
1191 if (wantHtml) {1269 if (opts.wantHtml) {
1192 return '<span class="tok-type">noreturn</span>';1270 return '<span class="tok-type">noreturn</span>';
1193 } else {1271 } else {
1194 return "noreturn";1272 return "noreturn";
...@@ -1230,20 +1308,20 @@ var zigAnalysis;...@@ -1230,20 +1308,20 @@ var zigAnalysis;
1230 {1308 {
1231 let fnObj = /** @type {Fn} */(typeObj);1309 let fnObj = /** @type {Fn} */(typeObj);
1232 let payloadHtml = "";1310 let payloadHtml = "";
1233 if (wantHtml) {1311 if (opts.wantHtml) {
1234 payloadHtml += '<span class="tok-kw">fn</span>';1312 payloadHtml += '<span class="tok-kw">fn</span>';
1235 if (fnDecl != null) {1313 if (opts.fnDecl) {
1236 payloadHtml += ' <span class="tok-fn">';1314 payloadHtml += ' <span class="tok-fn">';
1237 if (linkFnNameDecl != null) {1315 if (opts.linkFnNameDecl) {
1238 payloadHtml += '<a href="' + linkFnNameDecl + '">' +1316 payloadHtml += '<a href="' + opts.linkFnNameDecl + '">' +
1239 escapeHtml(fnDecl.name) + '</a>';1317 escapeHtml(opts.fnDecl.name) + '</a>';
1240 } else {1318 } else {
1241 payloadHtml += escapeHtml(fnDecl.name);1319 payloadHtml += escapeHtml(opts.fnDecl.name);
1242 }1320 }
1243 payloadHtml += '</span>';1321 payloadHtml += '</span>';
1244 }1322 }
1245 } else {1323 } else {
1246 payloadHtml += 'fn'1324 payloadHtml += 'fn ';
1247 }1325 }
1248 payloadHtml += '(';1326 payloadHtml += '(';
1249 if (fnObj.params) {1327 if (fnObj.params) {
...@@ -1259,7 +1337,7 @@ var zigAnalysis;...@@ -1259,7 +1337,7 @@ var zigAnalysis;
1259 }1337 }
12601338
1261 let value = fnObj.params[i];1339 let value = fnObj.params[i];
1262 let paramValue = resolveValue(value);1340 let paramValue = resolveValue({expr: value});
12631341
1264 if (fields != null) {1342 if (fields != null) {
1265 let paramNode = zigAnalysis.astNodes[fields[i]];1343 let paramNode = zigAnalysis.astNodes[fields[i]];
...@@ -1270,7 +1348,7 @@ var zigAnalysis;...@@ -1270,7 +1348,7 @@ var zigAnalysis;
1270 }1348 }
12711349
1272 if (paramNode.noalias) {1350 if (paramNode.noalias) {
1273 if (wantHtml) {1351 if (opts.wantHtml) {
1274 payloadHtml += '<span class="tok-kw">noalias</span> ';1352 payloadHtml += '<span class="tok-kw">noalias</span> ';
1275 } else {1353 } else {
1276 payloadHtml += 'noalias ';1354 payloadHtml += 'noalias ';
...@@ -1278,7 +1356,7 @@ var zigAnalysis;...@@ -1278,7 +1356,7 @@ var zigAnalysis;
1278 }1356 }
12791357
1280 if (paramNode.comptime) {1358 if (paramNode.comptime) {
1281 if (wantHtml) {1359 if (opts.wantHtml) {
1282 payloadHtml += '<span class="tok-kw">comptime</span> ';1360 payloadHtml += '<span class="tok-kw">comptime</span> ';
1283 } else {1361 } else {
1284 payloadHtml += 'comptime ';1362 payloadHtml += 'comptime ';
...@@ -1297,35 +1375,48 @@ var zigAnalysis;...@@ -1297,35 +1375,48 @@ var zigAnalysis;
1297 if (isVarArgs && i === fnObj.params.length - 1) {1375 if (isVarArgs && i === fnObj.params.length - 1) {
1298 payloadHtml += '...';1376 payloadHtml += '...';
1299 } else if ("refPath" in value) {1377 } else if ("refPath" in value) {
1300 payloadHtml += '<a href="">';1378 if (opts.wantHtml) {
1301 payloadHtml += '<span class="tok-kw" style="color:lightblue;">[Ref Path]</span>';1379 payloadHtml += '<a href="">';
1302 payloadHtml += '</a>';1380 payloadHtml +=
1381 '<span class="tok-kw" style="color:lightblue;">'
1382 + exprName(value, opts) + '</span>';
1383 payloadHtml += '</a>';
1384 } else {
1385 payloadHtml += exprName(value, opts);
1386 }
13031387
1304 } else if ("type" in value) {1388 } else if ("type" in value) {
1305 let name = typeValueName(value, false, false, fnDecl, linkFnNameDecl);1389 let name = exprName(value, {
1390 wantHtml: false,
1391 wantLink: false,
1392 fnDecl: opts.fnDecl,
1393 linkFnNameDecl: opts.linkFnNameDecl,
1394 });
1306 payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';1395 payloadHtml += '<span class="tok-kw">' + escapeHtml(name) + '</span>';
1307 } else if ("comptimeExpr" in value) {1396 } else if ("comptimeExpr" in value) {
1308 payloadHtml += '<span class="tok-kw">[ComptimeExpr]</span>';1397 if (opts.wantHtml) {
1309 } else if (wantHtml) {1398 payloadHtml += '<span class="tok-kw">[ComptimeExpr]</span>';
1310 payloadHtml += '<span class="tok-kw">var</span>';1399 } else {
1400 payloadHtml += "[ComptimeExpr]";
1401 }
1402 } else if (opts.wantHtml) {
1403 payloadHtml += '<span class="tok-kw">anytype</span>';
1311 } else {1404 } else {
1312 payloadHtml += 'var';1405 payloadHtml += 'anytype';
1313 }1406 }
1314 }1407 }
1315 }1408 }
13161409
1317 payloadHtml += ') ';1410 payloadHtml += ') ';
1318 if (fnObj.ret != null) {1411 if (fnObj.ret != null) {
1319 payloadHtml += typeValueName(fnObj.ret, wantHtml, wantSubLink, fnDecl);1412 payloadHtml += exprName(fnObj.ret, opts);
1320 } else if (wantHtml) {1413 } else if (opts.wantHtml) {
1321 payloadHtml += '<span class="tok-kw">anytype</span>';1414 payloadHtml += '<span class="tok-kw">anytype</span>';
1322 } else {1415 } else {
1323 payloadHtml += 'anytype';1416 payloadHtml += 'anytype';
1324 }1417 }
1325 return payloadHtml;1418 return payloadHtml;
1326 }1419 }
1327 default:
1328 throw "TODO";
1329 // if (wantHtml) {1420 // if (wantHtml) {
1330 // return escapeHtml(typeObj.name);1421 // return escapeHtml(typeObj.name);
1331 // } else {1422 // } else {
...@@ -1334,104 +1425,16 @@ var zigAnalysis;...@@ -1334,104 +1425,16 @@ var zigAnalysis;
1334 }1425 }
1335 }1426 }
13361427
1337 default: throw "oh no";
1338 }1428 }
1339 }1429 }
13401430
13411431
1342 /**1432 /**
1343 * @param {WalkResult} typeValue,1433 * @param {Expr} typeRef
1344 * @param {boolean} wantHtml,
1345 * @param {boolean} wantLink,
1346 * @param {Decl | null} [fnDecl],
1347 * @param {string} [linkFnNameDecl],
1348 * @return {string}
1349 */
1350 function typeValueName(typeValue, wantHtml, wantLink, fnDecl, linkFnNameDecl) {
1351
1352 if ("int" in typeValue) {
1353 return "" + typeValue.int.value;
1354 }
1355 if ("call" in typeValue) {
1356 let result = "";
1357 let call = zigAnalysis.calls[typeValue.call];
1358 let functionName = typeValueName(call.func, wantHtml, wantLink, fnDecl, linkFnNameDecl);
1359 result += functionName + "(";
1360 for (let j = 0; j < call.args.length; j += 1) {
1361 result += typeValueName(call.args[j], wantHtml, wantLink, fnDecl, linkFnNameDecl);
1362 if (j != call.args.length -1) result += ",";
1363 }
1364
1365 return result + ")";
1366 }
1367 if ("comptimeExpr" in typeValue) {
1368 return "[ComptimeExpr]";
1369 }
1370 if ("refPath" in typeValue) {
1371 let result = "";
1372 for (let j = 0; j < typeValue.refPath.length; j++) {
1373
1374 let name = "[RefPath]";
1375 if (wantHtml) {
1376 //result += '<a href="'+navLinkDecl(decl.name)+'">';
1377 result += '<a href="">';
1378 result += '<span class="tok-kw" style="color:lightblue;">' +
1379 name + '</span>';
1380 result += '</a>';
1381 } else {
1382 result += name;
1383 }
1384
1385 if (j != 0) result += ".";
1386 }
1387
1388 return result;
1389 }
1390
1391 if ("declRef" in typeValue) {
1392 return zigAnalysis.decls[typeValue.declRef].name;
1393 }
1394
1395 if ("string" in typeValue) {
1396 return typeValue.string + " (string)";
1397 }
1398
1399 if ("anytype" in typeValue) {
1400 return "anytype";
1401 }
1402
1403 if ("this" in typeValue) {
1404 return "this";
1405 }
1406
1407 console.assert("type" in typeValue)
1408 let typeIndex = typeValue.type;
1409 let typeObj = zigAnalysis.types[typeIndex];
1410 if (wantLink) {
1411 let declIndex = getCanonTypeDecl(typeIndex);
1412 let declPath = getCanonDeclPath(declIndex);
1413 if (declPath == null) {
1414 return typeName(typeObj, wantHtml, wantLink, fnDecl, linkFnNameDecl);
1415 }
1416 let name = (wantLink && declCanRepresentTypeKind(typeObj.kind)) ?
1417 declPath.declNames[declPath.declNames.length - 1] :
1418 typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl);
1419 if (wantLink && wantHtml) {
1420 return '<a href="' + navLink(declPath.pkgNames, declPath.declNames) + '">' + name + '</a>';
1421 } else {
1422 return name;
1423 }
1424 } else {
1425 return typeName(typeObj, wantHtml, false, fnDecl, linkFnNameDecl);
1426 }
1427 }
1428
1429 /**
1430 * @param {WalkResult} typeRef
1431 * @param {string} paramName1434 * @param {string} paramName
1432 */1435 */
1433 function shouldSkipParamName(typeRef, paramName) {1436 function shouldSkipParamName(typeRef, paramName) {
1434 let resolvedTypeRef = resolveValue(typeRef);1437 let resolvedTypeRef = resolveValue({expr: typeRef});
1435 if ("type" in resolvedTypeRef) {1438 if ("type" in resolvedTypeRef) {
1436 let typeObj = zigAnalysis.types[resolvedTypeRef.type];1439 let typeObj = zigAnalysis.types[resolvedTypeRef.type];
1437 if (typeObj.kind === typeKinds.Pointer){1440 if (typeObj.kind === typeKinds.Pointer){
...@@ -1450,69 +1453,13 @@ var zigAnalysis;...@@ -1450,69 +1453,13 @@ var zigAnalysis;
1450 return (typeObj.size == null) ? pointerSizeEnum.One : typeObj.size;1453 return (typeObj.size == null) ? pointerSizeEnum.One : typeObj.size;
1451 }1454 }
14521455
1453 // function getCallHtml(fnDecl, callIndex) {
1454 // let callObj = zigAnalysis.calls[callIndex];
1455
1456 // // TODO make these links work
1457 // //let html = '<a href="' + navLinkCall(callObj) + '">' + escapeHtml(fnDecl.name) + '</a>(';
1458 // let html = escapeHtml(fnDecl.name) + '(';
1459 // for (let arg_i = 0; arg_i < callObj.args.length; arg_i += 1) {
1460 // if (arg_i !== 0) html += ', ';
1461 // let argObj = callObj.args[arg_i];
1462 // html += getValueText(argObj, argObj.value, true, true);
1463 // }
1464 // html += ')';
1465 // return html;
1466 // }
1467
1468 // /**
1469 // * @param {WalkResult} typeRef
1470 // * @param {any} value
1471 // * @param {boolean} wantHtml
1472 // * @param {boolean} wantLink
1473 // */
1474 // function getValueText(typeRef, value, wantHtml, wantLink) {
1475 // let resolvedTypeRef = resolveValue(typeRef);
1476 // if ("comptimeExpr" in resolvedTypeRef) {
1477 // return "[ComptimeExpr]";
1478 // }
1479 // console.assert("type" in resolvedTypeRef);
1480 // let typeObj = zigAnalysis.types[typeRef.type];
1481 // switch (typeObj.kind) {
1482 // case typeKinds.Type:
1483 // return typeValueName(value, wantHtml, wantLink);
1484 // case typeKinds.Fn:
1485 // let fnObj = zigAnalysis.fns[value];
1486 // return typeName(fnObj, wantHtml, wantLink);
1487 // case typeKinds.Int:
1488 // if (wantHtml) {
1489 // return '<span class="tok-number">' + value + '</span>';
1490 // } else {
1491 // return value + "";
1492 // }
1493 // default:
1494 // console.trace("TODO implement getValueText for this type:", zigAnalysis.typeKinds[typeObj.kind]);
1495 // }
1496 // }
1497
1498 /**
1499 * @param {Type} typeObj,
1500 * @param {boolean} wantHtml,
1501 * @param {boolean} wantSubLink,
1502 * @param {Decl | null} [fnDecl],
1503 * @param {string} [linkFnNameDecl],
1504 * @return {string}
1505 */
1506 function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) {
1507 }
1508
1509 /** @param {Type} typeObj */1456 /** @param {Type} typeObj */
1510 function renderType(typeObj) {1457 function renderType(typeObj) {
1511 let name;1458 let name;
1512 if (rootIsStd && typeObj === zigAnalysis.types[zigAnalysis.packages[zigAnalysis.rootPkg].main]) {1459 if (rootIsStd && typeObj === zigAnalysis.types[zigAnalysis.packages[zigAnalysis.rootPkg].main]) {
1513 name = "std";1460 name = "std";
1514 } else {1461 } else {
1515 name = typeName(typeObj, false, false);1462 name = exprName({type:typeObj}, false, false);
1516 }1463 }
1517 if (name != null && name != "") {1464 if (name != null && name != "") {
1518 domHdrName.innerText = name + " (" + zigAnalysis.typeKinds[typeObj.kind] + ")";1465 domHdrName.innerText = name + " (" + zigAnalysis.typeKinds[typeObj.kind] + ")";
...@@ -1626,54 +1573,14 @@ var zigAnalysis;...@@ -1626,54 +1573,14 @@ var zigAnalysis;
1626// }1573// }
16271574
16281575
1629 // function mergeDecls(declObj, nextDeclIndex, firstTypeObj, typeObj) {
1630 // let nextDeclObj = zigAnalysis.decls[nextDeclIndex];
1631 // if (declObj.type != null && nextDeclObj.type != null && declObj.type !== nextDeclObj.type) {
1632 // if (typeof(declObj.type) !== 'object') {
1633 // let prevType = declObj.type;
1634 // declObj.type = {};
1635 // declObj.type[prevType] = firstTypeObj;
1636 // declObj.value = null;
1637 // }
1638 // declObj.type[nextDeclObj.type] = typeObj;
1639 // } else if (declObj.type == null && nextDeclObj != null) {
1640 // declObj.type = nextDeclObj.type;
1641 // }
1642 // if (declObj.value != null && nextDeclObj.value != null && declObj.value !== nextDeclObj.value) {
1643 // if (typeof(declObj.value) !== 'object') {
1644 // let prevValue = declObj.value;
1645 // declObj.value = {};
1646 // declObj.value[prevValue] = firstTypeObj;
1647 // }
1648 // declObj.value[nextDeclObj.value] = typeObj;
1649 // } else if (declObj.value == null && nextDeclObj.value != null) {
1650 // declObj.value = nextDeclObj.value;
1651 // }
1652 // }
16531576
1654 /** @param {Decl} decl */1577 /** @param {Decl} decl */
1655 function renderValue(decl) {1578 function renderValue(decl) {
16561579 let resolvedValue = resolveValue(decl.value)
1657 let declTypeRef = decl.value.typeRef;
1658 let declValueText = exprName(decl.value.expr);
1659// switch(Object.keys(decl.value)[0]) {
1660// case "int":
1661// declValueText += /** @type {{int: {value: number}}} */(decl.value).int.value;
1662// break;
1663// case "float":
1664// declValueText += /** @type {{float: {value: number}}} */(decl.value).float.value;
1665// break;
1666// case "comptimeExpr":
1667// declValueText += "[ComptimeExpr]";
1668// break;
1669// default:
1670// console.log("TODO: renderValue for ", Object.keys(decl.value)[0]);
1671// declValueText += "#TODO#";
1672// }
16731580
1674 domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' +1581 domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' +
1675 escapeHtml(decl.name) + ': ' + exprName(declTypeRef, {wantHtml: true}) +1582 escapeHtml(decl.name) + ': ' + exprName(resolvedValue.typeRef, {wantHtml: true, wantLink:true}) +
1676 " = " + declValueText;1583 " = " + exprName(decl.value.expr, {wantHtml: true, wantLink:true}) + ";";
16771584
1678 let docs = zigAnalysis.astNodes[decl.src].docs;1585 let docs = zigAnalysis.astNodes[decl.src].docs;
1679 if (docs != null) {1586 if (docs != null) {
...@@ -1729,43 +1636,36 @@ var zigAnalysis;...@@ -1729,43 +1636,36 @@ var zigAnalysis;
1729 }1636 }
17301637
1731 if (decl.kind === 'const') {1638 if (decl.kind === 'const') {
1732 if ("call" in declValue) {1639 if ("type" in declValue.expr) {
1733 let c = zigAnalysis.calls[declValue.call];1640 // We have the actual type expression at hand.
1734 console.assert("comptimeExpr" in c.ret);1641 const typeExpr = zigAnalysis.types[declValue.expr.type];
1735 let fDecl = resolveValue(c.func);1642 if (typeExpr.kind == typeKinds.Fn) {
1736 if ("type" in fDecl) {1643 const funcRetExpr = resolveValue({
1737 console.assert("type" in fDecl);1644 expr: /** @type {Fn} */(typeExpr).ret
1738 let fType = /** @type {Fn} */(zigAnalysis.types[fDecl.type]);1645 });
1739 console.assert("type" in fType.ret);1646 if ("type" in funcRetExpr && funcRetExpr.type != typeTypeId) {
1740 if (fType.ret.type === typeTypeId) {1647 if (typeIsErrSet(declValue.expr.type)) {
1741 typesList.push(decl);1648 errSetsList.push(decl);
1742 } else {1649 } else if (typeIsStructWithNoFields(declValue.expr.type)) {
1743 valsList.push(decl);1650 namespacesList.push(decl);
1744 }1651 } else {
1745 } else {1652 typesList.push(decl);
1746 valsList.push(decl);1653 }
1747 }
1748 } else if (!("type" in declValue)){
1749 valsList.push(decl);
1750 } else {
1751 let value = zigAnalysis.types[declValue.type];
1752 let kind = value.kind;
1753 if (kind === typeKinds.Fn) {
1754 // TODO: handle CTE return types when we know their type.
1755 const resVal = resolveValue(/** @type {Fn} */(value).ret);
1756 if ("type" in resVal && resVal.type == typeTypeId) {
1757 typesList.push(decl);
1758 } else {1654 } else {
1759 fnsList.push(decl);1655 fnsList.push(decl);
1760 }1656 }
17611657 } else {
1762 } else if (typeIsErrSet(declValue.type)) {
1763 errSetsList.push(decl);
1764 } else if (typeIsStructWithNoFields(declValue.type)) {
1765 namespacesList.push(decl);
1766 } else {
1767 typesList.push(decl);1658 typesList.push(decl);
1768 }1659 }
1660 } else if ("typeRef" in declValue) {
1661 if ("type" in declValue.typeRef && declValue.typeRef == typeTypeId) {
1662 // We don't know what the type expression is, but we know it's a type.
1663 typesList.push(decl);
1664 } else {
1665 valsList.push(decl);
1666 }
1667 } else {
1668 valsList.push(decl);
1769 }1669 }
1770 }1670 }
1771 }1671 }
...@@ -1859,9 +1759,14 @@ var zigAnalysis;...@@ -1859,9 +1759,14 @@ var zigAnalysis;
1859 let tdDesc = trDom.children[1];1759 let tdDesc = trDom.children[1];
18601760
1861 let declType = resolveValue(decl.value);1761 let declType = resolveValue(decl.value);
1862 console.assert("type" in declType);1762 console.assert("type" in declType.expr);
18631763
1864 tdFnCode.innerHTML = typeValueName(declType, true, true, decl, navLinkDecl(decl.name));1764 tdFnCode.innerHTML = exprName(declType.expr,{
1765 wantHtml: true,
1766 wantLink: true,
1767 fnDecl: decl,
1768 linkFnNameDecl: navLinkDecl(decl.name),
1769 });
18651770
1866 let docs = zigAnalysis.astNodes[decl.src].docs;1771 let docs = zigAnalysis.astNodes[decl.src].docs;
1867 if (docs != null) {1772 if (docs != null) {
...@@ -1874,7 +1779,7 @@ var zigAnalysis;...@@ -1874,7 +1779,7 @@ var zigAnalysis;
1874 }1779 }
18751780
1876 let containerNode = zigAnalysis.astNodes[container.src];1781 let containerNode = zigAnalysis.astNodes[container.src];
1877 if (containerNode.fields) {1782 if (containerNode.fields && containerNode.fields.length > 0) {
1878 resizeDomList(domListFields, containerNode.fields.length, '<div></div>');1783 resizeDomList(domListFields, containerNode.fields.length, '<div></div>');
18791784
1880 for (let i = 0; i < containerNode.fields.length; i += 1) {1785 for (let i = 0; i < containerNode.fields.length; i += 1) {
...@@ -1887,11 +1792,11 @@ var zigAnalysis;...@@ -1887,11 +1792,11 @@ var zigAnalysis;
1887 if (container.kind === typeKinds.Enum) {1792 if (container.kind === typeKinds.Enum) {
1888 html += ' = <span class="tok-number">' + fieldName + '</span>';1793 html += ' = <span class="tok-number">' + fieldName + '</span>';
1889 } else {1794 } else {
1890 let fieldTypeWr = container.fields[i];1795 let fieldTypeExpr = container.fields[i];
1891 html += ": ";1796 html += ": ";
1892 let name = typeValueName(fieldTypeWr, false, false);1797 let name = exprName(fieldTypeExpr, false, false);
1893 html += '<span class="tok-kw">'+ name +'</span>';1798 html += '<span class="tok-kw">'+ name +'</span>';
1894 let tsn = typeShorthandName(fieldTypeWr);1799 let tsn = typeShorthandName(fieldTypeExpr);
1895 if (tsn) {1800 if (tsn) {
1896 html += '<span> ('+ tsn +')</span>';1801 html += '<span> ('+ tsn +')</span>';
18971802
...@@ -1951,7 +1856,8 @@ var zigAnalysis;...@@ -1951,7 +1856,8 @@ var zigAnalysis;
1951 tdNameA.setAttribute('href', navLinkDecl(decl.name));1856 tdNameA.setAttribute('href', navLinkDecl(decl.name));
1952 tdNameA.textContent = decl.name;1857 tdNameA.textContent = decl.name;
19531858
1954 tdType.innerHTML = typeValueName(typeOfDecl(decl), true, true);1859 tdType.innerHTML = exprName(walkResultTypeRef(decl.value),
1860 {wantHtml:true, wantLink:true});
19551861
1956 let docs = zigAnalysis.astNodes[decl.src].docs;1862 let docs = zigAnalysis.astNodes[decl.src].docs;
1957 if (docs != null) {1863 if (docs != null) {
...@@ -1978,7 +1884,8 @@ var zigAnalysis;...@@ -1978,7 +1884,8 @@ var zigAnalysis;
1978 tdNameA.setAttribute('href', navLinkDecl(decl.name));1884 tdNameA.setAttribute('href', navLinkDecl(decl.name));
1979 tdNameA.textContent = decl.name;1885 tdNameA.textContent = decl.name;
19801886
1981 tdType.innerHTML = typeValueName(typeOfDecl(decl), true, true);1887 tdType.innerHTML = exprName(walkResultTypeRef(decl.value),
1888 {wantHtml:true, wantLink:true});
19821889
1983 let docs = zigAnalysis.astNodes[decl.src].docs;1890 let docs = zigAnalysis.astNodes[decl.src].docs;
1984 if (docs != null) {1891 if (docs != null) {
src/Autodoc.zig+19-6
...@@ -542,13 +542,14 @@ const DocData = struct {...@@ -542,13 +542,14 @@ const DocData = struct {
542 call: usize, // index in `calls`542 call: usize, // index in `calls`
543 enumLiteral: []const u8, // direct value543 enumLiteral: []const u8, // direct value
544 typeOf: usize, // index in `exprs`544 typeOf: usize, // index in `exprs`
545 as: struct {545 as: As,
546 typeRefArg: ?usize, // index in `exprs`
547 exprArg: usize, // index in `exprs`
548 },
549 sizeOf: usize, // index in `exprs`546 sizeOf: usize, // index in `exprs`
550 compileError: []const u8,547 compileError: []const u8,
551 string: []const u8, // direct value548 string: []const u8, // direct value
549 const As = struct {
550 typeRefArg: ?usize, // index in `exprs`
551 exprArg: usize, // index in `exprs`
552 };
552 const FieldRef = struct {553 const FieldRef = struct {
553 type: usize, // index in `types`554 type: usize, // index in `types`
554 index: usize, // index in type.fields555 index: usize, // index in type.fields
...@@ -592,12 +593,16 @@ const DocData = struct {...@@ -592,12 +593,16 @@ const DocData = struct {
592 , .{v});593 , .{v});
593 },594 },
594 .sizeOf => |v| try std.json.stringify(v, options, w),595 .sizeOf => |v| try std.json.stringify(v, options, w),
595 .as => |v| try std.json.stringify(v, options, w),
596 .fieldRef => |v| try std.json.stringify(596 .fieldRef => |v| try std.json.stringify(
597 struct { fieldRef: FieldRef }{ .fieldRef = v },597 struct { fieldRef: FieldRef }{ .fieldRef = v },
598 options,598 options,
599 w,599 w,
600 ),600 ),
601 .as => |v| try std.json.stringify(
602 struct { as: As }{ .as = v },
603 options,
604 w,
605 ),
601 .@"struct" => |v| try std.json.stringify(606 .@"struct" => |v| try std.json.stringify(
602 struct { @"struct": []FieldVal }{ .@"struct" = v },607 struct { @"struct": []FieldVal }{ .@"struct" = v },
603 options,608 options,
...@@ -774,7 +779,12 @@ fn walkInstruction(...@@ -774,7 +779,12 @@ fn walkInstruction(
774 );779 );
775780
776 return DocData.WalkResult{781 return DocData.WalkResult{
777 .expr = .{ .compileError = operand.expr.string },782 .expr = .{
783 .compileError = switch (operand.expr) {
784 .string => |s| s,
785 else => "TODO: non-string @compileError arguments",
786 },
787 },
778 };788 };
779 },789 },
780 .enum_literal => {790 .enum_literal => {
...@@ -1010,6 +1020,9 @@ fn walkInstruction(...@@ -1010,6 +1020,9 @@ fn walkInstruction(
1010 .decl_val, .decl_ref => {1020 .decl_val, .decl_ref => {
1011 const str_tok = data[inst_index].str_tok;1021 const str_tok = data[inst_index].str_tok;
1012 const decls_slot_index = parent_scope.resolveDeclName(str_tok.start);1022 const decls_slot_index = parent_scope.resolveDeclName(str_tok.start);
1023 // While it would make sense to grab the original decl's typeRef info,
1024 // that decl might not have been analyzed yet! The frontend will have
1025 // to navigate through all declRefs to find the underlying type.
1013 return DocData.WalkResult{ .expr = .{ .declRef = decls_slot_index } };1026 return DocData.WalkResult{ .expr = .{ .declRef = decls_slot_index } };
1014 },1027 },
1015 .field_val, .field_call_bind, .field_ptr, .field_type => {1028 .field_val, .field_call_bind, .field_ptr, .field_type => {