authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-03-30 19:06:02+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
log72e5b4fb747908d4cf4e5039c671ec729e5b7716
tree71ba0e203877c3c34021ce69a1f0add6b1be3afb
parent64feb222b52ae135c23fec55a2431fd733a6f1e8

autodoc: improve type checking in main.js


1 files changed, 180 insertions(+), 121 deletions(-)

lib/docs/main.js+180-121
......@@ -57,15 +57,19 @@
5757
5858/**
5959 * @typedef {
60 { kind: number } & (
61 | { name: string } // Type, Void, Bool, NoReturn, Int, Float, ComptimeExpr, ComptimeFloat, ComptimeInt, Undefined, Null, ErrorUnion, BoundFn, Opaque, Frame, AnyFrame, Vector, EnumLiteral
62 | { name: string; child: TypeRef } // Optional
63 | { len: WalkResult; child: TypeRef } // Array
64 | { name: string; fields: { name: string; docs: string }[] } // ErrorSet
65 | { size: "One" | "Many" | "Slice" | "C"; child: TypeRef } // Pointer
66 | { name: string; src: number; privDecls: number[]; pubDecls: number[]; fields: WalkResult[] } // Struct, Enum, Union
67 | { name: string; src: number; ret: WalkResult; params: WalkResult[] } // Fn
68 )
60 | { kind: number, name: string; src: number; privDecls: number[]; pubDecls: number[]; fields: WalkResult[] } // Struct, Enum, Union
61 } ContainerType
62*/
63
64/**
65 * @typedef {
66 | { kind: number, name: string } // Type, Void, Bool, NoReturn, Int, Float, ComptimeExpr, ComptimeFloat, ComptimeInt, Undefined, Null, ErrorUnion, BoundFn, Opaque, Frame, AnyFrame, Vector, EnumLiteral
67 | { kind: number, name: string; child: TypeRef } // Optional
68 | { kind: number, len: WalkResult; child: TypeRef } // Array
69 | { kind: number, name: string; fields: { name: string; docs: string }[] } // ErrorSet
70 | { kind: number, size: "One" | "Many" | "Slice" | "C"; child: TypeRef } // Pointer
71 | ContainerType
72 | { kind: number, name: string; src: number; ret: WalkResult; params: WalkResult[] } // Fn
6973 } Type
7074*/
7175
......@@ -156,7 +160,7 @@
156160 errors: {};
157161 astNodes: AstNode[];
158162 calls: Call[];
159 files: Record<string, number>;
163 files: Record<string, string>;
160164 types: Type[];
161165 decls: Decl[];
162166 comptimeExprs: ComptimeExpr[];
......@@ -168,53 +172,57 @@
168172var zigAnalysis;
169173
170174(function() {
171 var domStatus = document.getElementById("status");
172 var domSectNav = document.getElementById("sectNav");
173 var domListNav = document.getElementById("listNav");
174 var domSectMainPkg = document.getElementById("sectMainPkg");
175 var domSectPkgs = document.getElementById("sectPkgs");
176 var domListPkgs = document.getElementById("listPkgs");
177 var domSectTypes = document.getElementById("sectTypes");
178 var domListTypes = document.getElementById("listTypes");
179 var domSectTests = document.getElementById("sectTests");
180 var domListTests = document.getElementById("listTests");
181 var domSectNamespaces = document.getElementById("sectNamespaces");
182 var domListNamespaces = document.getElementById("listNamespaces");
183 var domSectErrSets = document.getElementById("sectErrSets");
184 var domListErrSets = document.getElementById("listErrSets");
185 var domSectFns = document.getElementById("sectFns");
186 var domListFns = document.getElementById("listFns");
187 var domSectFields = document.getElementById("sectFields");
188 var domListFields = document.getElementById("listFields");
189 var domSectGlobalVars = document.getElementById("sectGlobalVars");
190 var domListGlobalVars = document.getElementById("listGlobalVars");
191 var domSectValues = document.getElementById("sectValues");
192 var domListValues = document.getElementById("listValues");
193 var domFnProto = document.getElementById("fnProto");
194 var domFnProtoCode = document.getElementById("fnProtoCode");
195 var domSectParams = document.getElementById("sectParams");
196 var domListParams = document.getElementById("listParams");
197 var domTldDocs = document.getElementById("tldDocs");
198 var domSectFnErrors = document.getElementById("sectFnErrors");
199 var domListFnErrors = document.getElementById("listFnErrors");
200 var domTableFnErrors = document.getElementById("tableFnErrors");
201 var domFnErrorsAnyError = document.getElementById("fnErrorsAnyError");
202 var domFnExamples = document.getElementById("fnExamples");
203 var domListFnExamples = document.getElementById("listFnExamples");
204 var domFnNoExamples = document.getElementById("fnNoExamples");
205 var domDeclNoRef = document.getElementById("declNoRef");
206 var domSearch = document.getElementById("search");
207 var domSectSearchResults = document.getElementById("sectSearchResults");
208 var domListSearchResults = document.getElementById("listSearchResults");
209 var domSectSearchNoResults = document.getElementById("sectSearchNoResults");
210 var domSectInfo = document.getElementById("sectInfo");
211 var domTdTarget = document.getElementById("tdTarget");
212 var domPrivDeclsBox = document.getElementById("privDeclsBox");
213 var domTdZigVer = document.getElementById("tdZigVer");
214 var domHdrName = document.getElementById("hdrName");
215 var domHelpModal = document.getElementById("helpDialog");
216
175 var domStatus = /** @type HTMLElement */(document.getElementById("status"));
176 var domSectNav = /** @type HTMLElement */(document.getElementById("sectNav"));
177 var domListNav = /** @type HTMLElement */(document.getElementById("listNav"));
178 var domSectMainPkg = /** @type HTMLElement */(document.getElementById("sectMainPkg"));
179 var domSectPkgs = /** @type HTMLElement */(document.getElementById("sectPkgs"));
180 var domListPkgs = /** @type HTMLElement */(document.getElementById("listPkgs"));
181 var domSectTypes = /** @type HTMLElement */(document.getElementById("sectTypes"));
182 var domListTypes = /** @type HTMLElement */(document.getElementById("listTypes"));
183 var domSectTests = /** @type HTMLElement */(document.getElementById("sectTests"));
184 var domListTests = /** @type HTMLElement */(document.getElementById("listTests"));
185 var domSectNamespaces = /** @type HTMLElement */(document.getElementById("sectNamespaces"));
186 var domListNamespaces = /** @type HTMLElement */(document.getElementById("listNamespaces"));
187 var domSectErrSets = /** @type HTMLElement */(document.getElementById("sectErrSets"));
188 var domListErrSets = /** @type HTMLElement */(document.getElementById("listErrSets"));
189 var domSectFns = /** @type HTMLElement */(document.getElementById("sectFns"));
190 var domListFns = /** @type HTMLElement */(document.getElementById("listFns"));
191 var domSectFields = /** @type HTMLElement */(document.getElementById("sectFields"));
192 var domListFields = /** @type HTMLElement */(document.getElementById("listFields"));
193 var domSectGlobalVars = /** @type HTMLElement */(document.getElementById("sectGlobalVars"));
194 var domListGlobalVars = /** @type HTMLElement */(document.getElementById("listGlobalVars"));
195 var domSectValues = /** @type HTMLElement */(document.getElementById("sectValues"));
196 var domListValues = /** @type HTMLElement */(document.getElementById("listValues"));
197 var domFnProto = /** @type HTMLElement */(document.getElementById("fnProto"));
198 var domFnProtoCode = /** @type HTMLElement */(document.getElementById("fnProtoCode"));
199 var domSectParams = /** @type HTMLElement */(document.getElementById("sectParams"));
200 var domListParams = /** @type HTMLElement */(document.getElementById("listParams"));
201 var domTldDocs = /** @type HTMLElement */(document.getElementById("tldDocs"));
202 var domSectFnErrors = /** @type HTMLElement */(document.getElementById("sectFnErrors"));
203 var domListFnErrors = /** @type HTMLElement */(document.getElementById("listFnErrors"));
204 var domTableFnErrors =/** @type HTMLElement */(document.getElementById("tableFnErrors"));
205 var domFnErrorsAnyError = /** @type HTMLElement */(document.getElementById("fnErrorsAnyError"));
206 var domFnExamples = /** @type HTMLElement */(document.getElementById("fnExamples"));
207 var domListFnExamples = /** @type HTMLElement */(document.getElementById("listFnExamples"));
208 var domFnNoExamples = /** @type HTMLElement */(document.getElementById("fnNoExamples"));
209 var domDeclNoRef = /** @type HTMLElement */(document.getElementById("declNoRef"));
210 var domSearch = /** @type HTMLInputElement */(document.getElementById("search"));
211 var domSectSearchResults = /** @type HTMLElement */(document.getElementById("sectSearchResults"));
212
213 var domListSearchResults = /** @type HTMLElement */(document.getElementById("listSearchResults"));
214 var domSectSearchNoResults = /** @type HTMLElement */(document.getElementById("sectSearchNoResults"));
215 var domSectInfo = /** @type HTMLElement */(document.getElementById("sectInfo"));
216 var domTdTarget = /** @type HTMLElement */(document.getElementById("tdTarget"));
217 var domPrivDeclsBox = /** @type HTMLElement */(document.getElementById("privDeclsBox"));
218 var domTdZigVer = /** @type HTMLElement */(document.getElementById("tdZigVer"));
219 var domHdrName = /** @type HTMLElement */(document.getElementById("hdrName"));
220 var domHelpModal = /** @type HTMLElement */(document.getElementById("helpDialog"));
221
222 /** @type number | null */
217223 var searchTimer = null;
224
225 /** @type Object<string, string> */
218226 var escapeHtmlReplacements = { "&": "&amp;", '"': "&quot;", "<": "&lt;", ">": "&gt;" };
219227
220228 var typeKinds = indexTypeKinds();
......@@ -298,12 +306,6 @@ var zigAnalysis;
298306 return isType(x) && typeKindIsContainer(x.kind) ;
299307 }
300308
301 function declContainsType(x){
302 console.assert("value" in x);
303
304
305 }
306
307309 function typeShorthandName(type) {
308310 var name = type.name;
309311 if (type.kind === typeKinds.Struct) {
......@@ -1434,6 +1436,10 @@ var zigAnalysis;
14341436 }
14351437
14361438
1439 /**
1440 * @param {number[]} decls
1441 * @param {Decl[]} typesList, namespacesList, errSetsList, fnsList, varsList, valsList, testsList
1442 */
14371443 function categorizeDecls(decls,
14381444 typesList, namespacesList, errSetsList,
14391445 fnsList, varsList, valsList, testsList) {
......@@ -1495,13 +1501,23 @@ var zigAnalysis;
14951501 }
14961502 }
14971503
1504 /**
1505 * @param {ContainerType} container
1506 */
14981507 function renderContainer(container) {
1508 /** @type {Decl[]} */
14991509 var typesList = [];
1510 /** @type {Decl[]} */
15001511 var namespacesList = [];
1512 /** @type {Decl[]} */
15011513 var errSetsList = [];
1514 /** @type {Decl[]} */
15021515 var fnsList = [];
1516 /** @type {Decl[]} */
15031517 var varsList = [];
1518 /** @type {Decl[]} */
15041519 var valsList = [];
1520 /** @type {Decl[]} */
15051521 var testsList = [];
15061522
15071523 categorizeDecls(container.pubDecls,
......@@ -1911,20 +1927,32 @@ var zigAnalysis;
19111927 return canonTypeDecls[index];
19121928 }
19131929
1930 /** @param {string} text */
19141931 function escapeHtml(text) {
19151932 return text.replace(/[&"<>]/g, function (m) {
19161933 return escapeHtmlReplacements[m];
19171934 });
19181935 }
19191936
1937 /** @param {string} docs */
19201938 function shortDescMarkdown(docs) {
19211939 var parts = docs.trim().split("\n");
19221940 var firstLine = parts[0];
19231941 return markdown(firstLine);
19241942 }
19251943
1944 /** @param {string} input */
19261945 function markdown(input) {
19271946 const raw_lines = input.split('\n'); // zig allows no '\r', so we don't need to split on CR
1947 /**
1948 * @type Array<{
1949 * indent: number,
1950 * raw_text: string,
1951 * text: string,
1952 * type: string,
1953 * ordered_number: number,
1954 * }>
1955 */
19281956 const lines = [];
19291957
19301958 // PHASE 1:
......@@ -1941,6 +1969,7 @@ var zigAnalysis;
19411969 raw_text: raw_line,
19421970 text: raw_line.trim(),
19431971 type: "p", // p, h1 … h6, code, ul, ol, blockquote, skip, empty
1972 ordered_number: -1, // NOTE: hack to make the type checker happy
19441973 };
19451974
19461975 if (!is_reading_code) {
......@@ -1977,7 +2006,7 @@ var zigAnalysis;
19772006 line.text = line.text.substr(1);
19782007 }
19792008 else if (line.text.match(/^\d+\..*$/)) { // if line starts with {number}{dot}
1980 const match = line.text.match(/(\d+)\./);
2009 const match = /** @type {RegExpMatchArray} */(line.text.match(/(\d+)\./));
19812010 line.type = "ul";
19822011 line.text = line.text.substr(match[0].length);
19832012 line.ordered_number = Number(match[1].length);
......@@ -2010,7 +2039,10 @@ var zigAnalysis;
20102039 // Render HTML from markdown lines.
20112040 // Look at each line and emit fitting HTML code
20122041
2013 function markdownInlines(innerText, stopChar) {
2042 /**
2043 * @param {string } innerText
2044 */
2045 function markdownInlines(innerText) {
20142046
20152047 // inline types:
20162048 // **{INLINE}** : <strong>
......@@ -2023,6 +2055,8 @@ var zigAnalysis;
20232055 // ![{TEXT}]({URL}) : <img>
20242056 // [[std;format.fmt]] : <a> (inner link)
20252057
2058 /** @typedef {{marker: string, tag: string}} Fmt*/
2059 /** @type {Array<Fmt>} */
20262060 const formats = [
20272061 {
20282062 marker: "**",
......@@ -2042,6 +2076,7 @@ var zigAnalysis;
20422076 }
20432077 ];
20442078
2079 /** @type {Array<Fmt>} */
20452080 const stack = [];
20462081
20472082 var innerHTML = "";
......@@ -2093,7 +2128,7 @@ var zigAnalysis;
20932128 in_code = true;
20942129 } else {
20952130 var any = false;
2096 for (var idx = (stack.length > 0 ? -1 : 0); idx < formats.length; idx++) {
2131 for (let idx = /** @type {number} */(stack.length > 0 ? -1 : 0); idx < formats.length; idx++) {
20972132 const fmt = idx >= 0 ? formats[idx] : stack[stack.length - 1];
20982133 if (innerText.substr(i, fmt.marker.length) == fmt.marker) {
20992134 flushRun();
......@@ -2117,48 +2152,60 @@ var zigAnalysis;
21172152 flushRun();
21182153
21192154 while (stack.length > 0) {
2120 const fmt = stack.pop();
2155 const fmt = /** @type {Fmt} */(stack.pop());
21212156 innerHTML += "</" + fmt.tag + ">";
21222157 }
21232158
21242159 return innerHTML;
21252160 }
21262161
2127 var html = "";
2128 for (var line_no = 0; line_no < lines.length; line_no++) {
2129 const line = lines[line_no];
2130
2131 function previousLineIs(type) {
2132 if (line_no > 0) {
2133 return (lines[line_no - 1].type == type);
2134 } else {
2135 return false;
2136 }
2162 /**
2163 * @param {string} type
2164 * @param {number} line_no
2165 */
2166 function previousLineIs(type, line_no) {
2167 if (line_no > 0) {
2168 return (lines[line_no - 1].type == type);
2169 } else {
2170 return false;
21372171 }
2172 }
21382173
2139 function nextLineIs(type) {
2140 if (line_no < (lines.length - 1)) {
2141 return (lines[line_no + 1].type == type);
2142 } else {
2143 return false;
2144 }
2174 /**
2175 * @param {string} type
2176 * @param {number} line_no
2177 */
2178 function nextLineIs(type, line_no) {
2179 if (line_no < (lines.length - 1)) {
2180 return (lines[line_no + 1].type == type);
2181 } else {
2182 return false;
21452183 }
2184 }
21462185
2147 function getPreviousLineIndent() {
2148 if (line_no > 0) {
2149 return lines[line_no - 1].indent;
2150 } else {
2151 return 0;
2152 }
2186 /** @param {number} line_no */
2187 function getPreviousLineIndent(line_no) {
2188 if (line_no > 0) {
2189 return lines[line_no - 1].indent;
2190 } else {
2191 return 0;
21532192 }
2193 }
21542194
2155 function getNextLineIndent() {
2156 if (line_no < (lines.length - 1)) {
2157 return lines[line_no + 1].indent;
2158 } else {
2159 return 0;
2160 }
2195 /** @param {number} line_no */
2196 function getNextLineIndent(line_no) {
2197 if (line_no < (lines.length - 1)) {
2198 return lines[line_no + 1].indent;
2199 } else {
2200 return 0;
21612201 }
2202 }
2203
2204 var html = "";
2205 for (var line_no = 0; line_no < lines.length; line_no++) {
2206 const line = lines[line_no];
2207
2208
21622209
21632210 switch (line.type) {
21642211 case "h1":
......@@ -2172,33 +2219,33 @@ var zigAnalysis;
21722219
21732220 case "ul":
21742221 case "ol":
2175 if (!previousLineIs("ul") || getPreviousLineIndent() < line.indent) {
2222 if (!previousLineIs("ul", line_no) || getPreviousLineIndent(line_no) < line.indent) {
21762223 html += "<" + line.type + ">\n";
21772224 }
21782225
21792226 html += "<li>" + markdownInlines(line.text) + "</li>\n";
21802227
2181 if (!nextLineIs("ul") || getNextLineIndent() < line.indent) {
2228 if (!nextLineIs("ul", line_no) || getNextLineIndent(line_no) < line.indent) {
21822229 html += "</" + line.type + ">\n";
21832230 }
21842231 break;
21852232
21862233 case "p":
2187 if (!previousLineIs("p")) {
2234 if (!previousLineIs("p", line_no)) {
21882235 html += "<p>\n";
21892236 }
21902237 html += markdownInlines(line.text) + "\n";
2191 if (!nextLineIs("p")) {
2238 if (!nextLineIs("p", line_no)) {
21922239 html += "</p>\n";
21932240 }
21942241 break;
21952242
21962243 case "code":
2197 if (!previousLineIs("code")) {
2244 if (!previousLineIs("code", line_no)) {
21982245 html += "<pre><code>";
21992246 }
22002247 html += escapeHtml(line.text) + "\n";
2201 if (!nextLineIs("code")) {
2248 if (!nextLineIs("code", line_no)) {
22022249 html += "</code></pre>\n";
22032250 }
22042251 break;
......@@ -2219,12 +2266,13 @@ var zigAnalysis;
22192266 }
22202267 if (liDom != null) {
22212268 var aDom = liDom.children[0];
2222 location.href = aDom.getAttribute("href");
2269 location.href = /** @type {string} */(aDom.getAttribute("href"));
22232270 curSearchIndex = -1;
22242271 }
22252272 domSearch.blur();
22262273 }
22272274
2275 /** @param {KeyboardEvent} ev */
22282276 function onSearchKeyDown(ev) {
22292277 switch (getKeyString(ev)) {
22302278 case "Enter":
......@@ -2268,6 +2316,8 @@ var zigAnalysis;
22682316 }
22692317 }
22702318
2319
2320 /** @param {number} dir */
22712321 function moveSearchCursor(dir) {
22722322 if (curSearchIndex < 0 || curSearchIndex >= domListSearchResults.children.length) {
22732323 if (dir > 0) {
......@@ -2287,6 +2337,7 @@ var zigAnalysis;
22872337 renderSearchCursor();
22882338 }
22892339
2340 /** @param {KeyboardEvent} ev */
22902341 function getKeyString(ev) {
22912342 var name;
22922343 var ignoreShift = false;
......@@ -2313,6 +2364,7 @@ var zigAnalysis;
23132364 return name;
23142365 }
23152366
2367 /** @param {KeyboardEvent} ev */
23162368 function onWindowKeyDown(ev) {
23172369 switch (getKeyString(ev)) {
23182370 case "Esc":
......@@ -2451,7 +2503,7 @@ function renderSearch() {
24512503
24522504function renderSearchCursor() {
24532505 for (var i = 0; i < domListSearchResults.children.length; i += 1) {
2454 var liDom = domListSearchResults.children[i];
2506 var liDom = /** @type HTMLElement */(domListSearchResults.children[i]);
24552507 if (curSearchIndex === i) {
24562508 liDom.classList.add("selected");
24572509 } else {
......@@ -2462,35 +2514,42 @@ function renderSearchCursor() {
24622514
24632515
24642516
2465function indexNodesToCalls() {
2466 var map = {};
2467 for (var i = 0; i < zigAnalysis.calls.length; i += 1) {
2468 var call = zigAnalysis.calls[i];
2469 var fn = zigAnalysis.fns[call.fn];
2470 if (map[fn.src] == null) {
2471 map[fn.src] = [i];
2472 } else {
2473 map[fn.src].push(i);
2474 }
2475 }
2476 return map;
2477}
2517// function indexNodesToCalls() {
2518// var map = {};
2519// for (var i = 0; i < zigAnalysis.calls.length; i += 1) {
2520// var call = zigAnalysis.calls[i];
2521// var fn = zigAnalysis.fns[call.fn];
2522// if (map[fn.src] == null) {
2523// map[fn.src] = [i];
2524// } else {
2525// map[fn.src].push(i);
2526// }
2527// }
2528// return map;
2529// }
24782530
2531
2532/**
2533* @param {{ name: string }} a
2534* @param {{ name: string }} b
2535*/
24792536function byNameProperty(a, b) {
24802537 return operatorCompare(a.name, b.name);
24812538}
24822539
2540
2541/**
2542 * @template T
2543 * @param {T} obj
2544 * @returns {T}
2545 */
24832546function clone(obj) {
2484 var res = {};
2547 var res = /** @type T */({});
24852548 for (var key in obj) {
24862549 res[key] = obj[key];
24872550 }
24882551 return res;
24892552}
24902553
2491function firstObjectKey(obj) {
2492 for (var key in obj) {
2493 return key;
2494 }
2495}
2554
24962555})();