Commit 18f6ef613c

Loris Cro <kappaloris@gmail.com>
2023-01-08 16:25:14
autodoc: improve linking of decl references
there are still some bugs to solve when a decl is re-exported but straight-forward cases are handled correctly
1 parent 87b2234
Changed files (1)
lib
docs
lib/docs/main.js
@@ -93,8 +93,7 @@ var zigAnalysis;
     // empty array means refers to the package itself
     declNames: [],
     // these will be all types, except the last one may be a type or a decl
-    declObjs: [],
-
+    declObjs: [],    
     // (a, b, c, d) comptime call; result is the value the docs refer to
     callName: null,
   };
@@ -451,6 +450,8 @@ var zigAnalysis;
       curNav.declObjs.push(currentType);
     }
     
+    
+    
     window.x = currentType;
 
     renderNav();
@@ -819,6 +820,27 @@ var zigAnalysis;
     return navLink(curNav.pkgNames, curNav.declNames.concat([childName]));
   }
 
+  function findDeclNavLink(declName) {
+    if (curNav.declObjs.length == 0) return null;
+    const curFile = getAstNode(curNav.declObjs[curNav.declObjs.length-1].src).file;
+    
+    for (let i = curNav.declObjs.length -1; i >= 0; i--) {
+      const curDecl = curNav.declObjs[i];
+      const curDeclName = curNav.declNames[i-1];
+      if (curDeclName == declName) {
+        const declPath = curNav.declNames.slice(0,i);
+        return navLink(curNav.pkgNames, declPath);
+      } 
+
+      if (findSubDecl(curDecl, declName) != null) { 
+        const declPath = curNav.declNames.slice(0,i).concat([declName]);
+        return navLink(curNav.pkgNames, declPath);
+      }
+    }
+
+    //throw("could not resolve links for '" + declName + "'");
+  }
+
   //
   //  function navLinkCall(callObj) {
   //      let declNamesCopy = curNav.declNames.concat([]);
@@ -879,7 +901,7 @@ var zigAnalysis;
         return "false";
       }
       case "&": {
-        return "&" + exprName(zigAnalysis.exprs[expr["&"]]);
+        return "&" + exprName(zigAnalysis.exprs[expr["&"]], opts);
       }
       case "compileError": {
         let compileError = expr.compileError;
@@ -896,18 +918,18 @@ var zigAnalysis;
         let payloadHtml = "";
         const lhsExpr = zigAnalysis.exprs[expr.slice.lhs];
         const startExpr = zigAnalysis.exprs[expr.slice.start];
-        let decl = exprName(lhsExpr);
-        let start = exprName(startExpr);
+        let decl = exprName(lhsExpr, opts);
+        let start = exprName(startExpr, opts);
         let end = "";
         let sentinel = "";
         if (expr.slice["end"]) {
           const endExpr = zigAnalysis.exprs[expr.slice.end];
-          let end_ = exprName(endExpr);
+          let end_ = exprName(endExpr, opts);
           end += end_;
         }
         if (expr.slice["sentinel"]) {
           const sentinelExpr = zigAnalysis.exprs[expr.slice.sentinel];
-          let sentinel_ = exprName(sentinelExpr);
+          let sentinel_ = exprName(sentinelExpr, opts);
           sentinel += " :" + sentinel_;
         }
         payloadHtml += decl + "[" + start + ".." + end + sentinel + "]";
@@ -915,7 +937,7 @@ var zigAnalysis;
       }
       case "sliceIndex": {
         const sliceIndex = zigAnalysis.exprs[expr.sliceIndex];
-        return exprName(sliceIndex, opts);
+        return exprName(sliceIndex, opts, opts);
       }
       case "cmpxchg": {
         const typeIndex = zigAnalysis.exprs[expr.cmpxchg.type];
@@ -1019,19 +1041,6 @@ var zigAnalysis;
         const switchIndex = zigAnalysis.exprs[expr.switchIndex];
         return exprName(switchIndex, opts);
       }
-      case "refPath": {
-        let name = exprName(expr.refPath[0]);
-        for (let i = 1; i < expr.refPath.length; i++) {
-          let component = undefined;
-          if ("string" in expr.refPath[i]) {
-            component = expr.refPath[i].string;
-          } else {
-            component = exprName(expr.refPath[i]);
-          }
-          name += "." + component;
-        }
-        return name;
-      }
       case "fieldRef": {
         const enumObj = exprName({ type: expr.fieldRef.type }, opts);
         const field =
@@ -1581,10 +1590,46 @@ var zigAnalysis;
         return exprName(exprArg, opts);
       }
       case "declRef": {
-        return getDecl(expr.declRef).name;
+        const name = getDecl(expr.declRef).name;
+      
+        if (opts.wantHtml) {
+          let payloadHtml = "";
+          if (opts.wantLink) {
+            payloadHtml += '<a href="'+ findDeclNavLink(name) +'">';          
+          }
+          payloadHtml +=
+            '<span class="tok-kw" style="color:lightblue;">' +
+              name +
+            "</span>";
+          if (opts.wantLink) payloadHtml += "</a>";
+          return payloadHtml;
+        } else {
+          return name;
+        }
       }
       case "refPath": {
-        return expr.refPath.map((x) => exprName(x, opts)).join(".");
+        let firstComponent = expr.refPath[0];
+        let name = exprName(firstComponent, opts);
+        let url = undefined;
+        if (opts.wantLink && "declRef" in firstComponent) {
+          url = findDeclNavLink(getDecl(firstComponent.declRef).name);
+        }
+        for (let i = 1; i < expr.refPath.length; i++) {
+          let component = undefined;
+          if ("string" in expr.refPath[i]) {
+            component = expr.refPath[i].string;
+          } else {
+            component = exprName(expr.refPath[i], {...opts, wantLink: false});
+            if (opts.wantLink && "declRef" in expr.refPath[i]) {
+              url += "." + getDecl(expr.refPath[i].declRef).name;
+              component = '<a href="'+ url +'">' +
+                component +
+              "</a>";            
+            }
+          }
+          name += "." + component;
+        }
+        return name;
       }
       case "int": {
         return "" + expr.int;
@@ -1929,78 +1974,20 @@ var zigAnalysis;
                 if (isVarArgs && i === fnObj.params.length - 1) {
                   payloadHtml += "...";
                 } else if ("alignOf" in value) {
-                  if (opts.wantHtml) {
-                    payloadHtml += '<a href="">';
-                    payloadHtml +=
-                      '<span class="tok-kw" style="color:lightblue;">' +
-                      exprName(value, opts) +
-                      "</span>";
-                    payloadHtml += "</a>";
-                  } else {
-                    payloadHtml += exprName(value, opts);
-                  }
+                  payloadHtml += exprName(value, opts);
                 } else if ("typeOf" in value) {
-                  if (opts.wantHtml) {
-                    payloadHtml += '<a href="">';
-                    payloadHtml +=
-                      '<span class="tok-kw" style="color:lightblue;">' +
-                      exprName(value, opts) +
-                      "</span>";
-                    payloadHtml += "</a>";
-                  } else {
-                    payloadHtml += exprName(value, opts);
-                  }
+                  payloadHtml += exprName(value, opts);
                 } else if ("typeOf_peer" in value) {
-                  if (opts.wantHtml) {
-                    payloadHtml += '<a href="">';
-                    payloadHtml +=
-                      '<span class="tok-kw" style="color:lightblue;">' +
-                      exprName(value, opts) +
-                      "</span>";
-                    payloadHtml += "</a>";
-                  } else {
                     payloadHtml += exprName(value, opts);
-                  }
                 } else if ("declRef" in value) {
-                  if (opts.wantHtml) {
-                    payloadHtml += '<a href="">';
-                    payloadHtml +=
-                      '<span class="tok-kw" style="color:lightblue;">' +
-                      exprName(value, opts) +
-                      "</span>";
-                    payloadHtml += "</a>";
-                  } else {
                     payloadHtml += exprName(value, opts);
-                  }
                 } else if ("call" in value) {
-                  if (opts.wantHtml) {
-                    payloadHtml += '<a href="">';
-                    payloadHtml +=
-                      '<span class="tok-kw" style="color:lightblue;">' +
-                      exprName(value, opts) +
-                      "</span>";
-                    payloadHtml += "</a>";
-                  } else {
                     payloadHtml += exprName(value, opts);
-                  }
                 } else if ("refPath" in value) {
-                  if (opts.wantHtml) {
-                    payloadHtml += '<a href="">';
-                    payloadHtml +=
-                      '<span class="tok-kw" style="color:lightblue;">' +
-                      exprName(value, opts) +
-                      "</span>";
-                    payloadHtml += "</a>";
-                  } else {
                     payloadHtml += exprName(value, opts);
-                  }
                 } else if ("type" in value) {
-                  let name = exprName(value, {
-                    ...opts,
-                    wantHtml: false,
-                    wantLink: false,
-                  });
-                  payloadHtml += '<span class="tok-kw">' + name + "</span>";
+                  payloadHtml += exprName(value, opts);
+                  //payloadHtml += '<span class="tok-kw">' + name + "</span>";
                 } else if ("binOpIndex" in value) {
                   payloadHtml += exprName(value, opts);
                 } else if ("comptimeExpr" in value) {
@@ -2405,11 +2392,10 @@ var zigAnalysis;
     }
 
     if (typesList.length !== 0) {
-      window.x = typesList;
       resizeDomList(
         domListTypes,
         typesList.length,
-        '<li><a href="#"></a></li>'
+        '<li><a href=""></a></li>'
       );
       for (let i = 0; i < typesList.length; i += 1) {
         let liDom = domListTypes.children[i];
@@ -2511,8 +2497,7 @@ var zigAnalysis;
         } else {
           let fieldTypeExpr = container.fields[i];
           html += ": ";
-          let name = exprName(fieldTypeExpr, false, false);
-          html += '<span class="tok-kw">' + name + "</span>";
+          html += exprName(fieldTypeExpr, {wantHtml:true, wantLink:true});
           let tsn = typeShorthandName(fieldTypeExpr);
           if (tsn) {
             html += "<span> (" + tsn + ")</span>";
@@ -2746,13 +2731,15 @@ var zigAnalysis;
     }
   }
 
-  function findSubDecl(parentType, childName) {
+  function findSubDecl(parentTypeOrDecl, childName) {
+    let parentType = parentTypeOrDecl;
     {
-      // Generic functions
+      // Generic functions / resorlving decls
       if ("value" in parentType) {
         const rv = resolveValue(parentType.value);
         if ("type" in rv.expr) {
           const t = getType(rv.expr.type);
+          parentType = t;
           if (t.kind == typeKinds.Fn && t.generic_ret != null) {
             let resolvedGenericRet = resolveValue({ expr: t.generic_ret });