Skylark Documentation: Add a one-page overview of all Skylark modules and globals.

--
PiperOrigin-RevId: 149286951
MOS_MIGRATED_REVID=149286951
diff --git a/site/_layouts/documentation.html b/site/_layouts/documentation.html
index f623326..a2db1de 100644
--- a/site/_layouts/documentation.html
+++ b/site/_layouts/documentation.html
@@ -93,16 +93,7 @@
               <li><a href="{{ page.version_prefix }}/docs/skylark/aspects.html">Aspects</a></li>
               <li><a href="{{ page.version_prefix }}/docs/skylark/repository_rules.html">Repository rules</a></li>
               <li><a href="{{ page.version_prefix }}/docs/rule-challenges.html">Challenges of writing rules</a></li>
-              <li>
-                <a class="sidebar-nav-heading" data-toggle="collapse"
-                    href="#skylark-lib-menu" aria-expanded="false"
-                    aria-controls="skylark-lib-menu">
-                  Reference <span class="caret"></span>
-                </a>
-                <ul class="collapse sidebar-nav sidebar-submenu" id="skylark-lib-menu">
-                {% include skylark-nav.html %}
-                </ul>
-              </li>
+              <li><a href="{{ page.version_prefix }}/docs/skylark-overview.html">Reference</a></li>
               <li><a href="{{ page.version_prefix }}/docs/skylark/cookbook.html">Examples</a></li>
               <li><a href="{{ page.version_prefix }}/docs/skylark/deploying.html">Packaging rules</a></li>
               <li><a href="https://skydoc.bazel.build" target="_blank">Documenting rules</a></li>
diff --git a/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java b/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java
index 5209d4f..3e8b511 100644
--- a/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java
+++ b/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java
@@ -18,7 +18,6 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.devtools.build.lib.util.FileType;
 import com.google.devtools.build.lib.util.FileTypeSet;
-import java.util.Map;
 import java.util.regex.Pattern;
 
 /**
@@ -43,6 +42,8 @@
       "com/google/devtools/build/docgen/templates/skylark-nav.vm";
   public static final String SKYLARK_MODULE_CATEGORY_TEMPLATE =
       "com/google/devtools/build/docgen/templates/skylark-category.vm";
+  public static final String SKYLARK_OVERVIEW_TEMPLATE =
+      "com/google/devtools/build/docgen/templates/skylark-overview.vm";
 
   public static final String VAR_LEFT_PANEL = "LEFT_PANEL";
 
@@ -154,7 +155,7 @@
   /** e.g. "[DEPRECATED]" in &lt;!-- #BLAZE_RULE(...).ATTRIBUTE(...)[DEPRECATED] --&gt; */
   public static final Pattern BLAZE_RULE_FLAGS = Pattern.compile("^.*\\[(.*)\\].*$");
 
-  public static final Map<String, Integer> ATTRIBUTE_ORDERING = ImmutableMap
+  public static final ImmutableMap<String, Integer> ATTRIBUTE_ORDERING = ImmutableMap
       .<String, Integer>builder()
       .put("name", -99)
       .put("deps", -98)
diff --git a/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationProcessor.java b/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationProcessor.java
index a275b54..f0f2976 100644
--- a/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationProcessor.java
+++ b/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationProcessor.java
@@ -13,22 +13,28 @@
 // limitations under the License.
 package com.google.devtools.build.docgen;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.docgen.skylark.SkylarkBuiltinMethodDoc;
 import com.google.devtools.build.docgen.skylark.SkylarkJavaMethodDoc;
+import com.google.devtools.build.docgen.skylark.SkylarkMethodDoc;
 import com.google.devtools.build.docgen.skylark.SkylarkModuleDoc;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
 import com.google.devtools.build.lib.util.Classpath.ClassPathException;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-/**
- * A class to assemble documentation for Skylark.
- */
+/** A class to assemble documentation for Skylark. */
 public final class SkylarkDocumentationProcessor {
+
+  private static final ImmutableList<SkylarkModuleCategory> GLOBAL_CATEGORIES =
+      ImmutableList.<SkylarkModuleCategory>of(
+          SkylarkModuleCategory.NONE, SkylarkModuleCategory.TOP_LEVEL_TYPE);
+
   private SkylarkDocumentationProcessor() {}
 
   /** Generates the Skylark documentation to the given output directory. */
@@ -58,6 +64,50 @@
     writeCategoryPage(SkylarkModuleCategory.BUILTIN, outputDir, modulesByCategory);
     writeCategoryPage(SkylarkModuleCategory.PROVIDER, outputDir, modulesByCategory);
     writeNavPage(outputDir, modulesByCategory.get(SkylarkModuleCategory.TOP_LEVEL_TYPE));
+
+    // In the code, there are two SkylarkModuleCategory instances that have no heading:
+    // TOP_LEVEL_TYPE and NONE.
+
+    // TOP_LEVEL_TYPE also contains the "global" module.
+    // We remove both categories and the "global" module from the map and display them manually:
+    // - Methods in the "global" module are displayed under "Global Methods and Constants".
+    // - Modules in both categories are displayed under "Global Modules" (except for the global
+    // module itself).
+    List<String> globalFunctions = new ArrayList<>();
+    SkylarkModuleDoc globalModule = findGlobalModule(modulesByCategory);
+    for (SkylarkMethodDoc method : globalModule.getMethods()) {
+      if (method.documented()) {
+        globalFunctions.add(method.getName());
+      }
+    }
+
+    List<String> globalModules = new ArrayList<>();
+    for (SkylarkModuleCategory globalCategory : GLOBAL_CATEGORIES) {
+      List<SkylarkModuleDoc> allGlobalModules = modulesByCategory.remove(globalCategory);
+      for (SkylarkModuleDoc module : allGlobalModules) {
+        if (!module.getName().equals(globalModule.getName())) {
+          globalModules.add(module.getName());
+        }
+      }
+    }
+
+    Collections.sort(globalModules);
+    writeOverviewPage(
+        outputDir, globalModule.getName(), globalFunctions, globalModules, modulesByCategory);
+  }
+
+  private static SkylarkModuleDoc findGlobalModule(
+      Map<SkylarkModuleCategory, List<SkylarkModuleDoc>> modulesByCategory) {
+    List<SkylarkModuleDoc> topLevelModules =
+        modulesByCategory.get(SkylarkModuleCategory.TOP_LEVEL_TYPE);
+    String globalModuleName = SkylarkDocumentationCollector.getTopLevelModule().name();
+    for (SkylarkModuleDoc module : topLevelModules) {
+      if (module.getName().equals(globalModuleName)) {
+        return module;
+      }
+    }
+
+    throw new IllegalStateException("No globals module in the top level category.");
   }
 
   private static void writePage(String outputDir, SkylarkModuleDoc module) throws IOException {
@@ -87,6 +137,22 @@
     page.write(navFile);
   }
 
+  private static void writeOverviewPage(
+      String outputDir,
+      String globalModuleName,
+      List<String> globalFunctions,
+      List<String> globalModules,
+      Map<SkylarkModuleCategory, List<SkylarkModuleDoc>> modulesPerCategory)
+      throws IOException {
+    File skylarkDocPath = new File(outputDir + "/skylark-overview.html");
+    Page page = TemplateEngine.newPage(DocgenConsts.SKYLARK_OVERVIEW_TEMPLATE);
+    page.add("global_name", globalModuleName);
+    page.add("global_functions", globalFunctions);
+    page.add("global_modules", globalModules);
+    page.add("modules", modulesPerCategory);
+    page.write(skylarkDocPath);
+  }
+
   /**
    * Returns the API doc for the specified Skylark object in a command line printable format,
    * params[0] identifies either a module or a top-level object, the optional params[1] identifies a
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm b/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm
index 4d09589..51594c2 100644
--- a/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm
+++ b/src/main/java/com/google/devtools/build/docgen/templates/skylark-nav.vm
@@ -2,3 +2,4 @@
 <li><a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-builtin.html">Builtin Types and Modules</a></li>
 <li><a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-configuration-fragment.html">Configuration fragments</a></li>
 <li><a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-provider.html">Providers</a></li>
+<li><a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-overview.html">One-Page Overview</a></li>
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/skylark-overview.vm b/src/main/java/com/google/devtools/build/docgen/templates/skylark-overview.vm
new file mode 100644
index 0000000..675d266
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/docgen/templates/skylark-overview.vm
@@ -0,0 +1,66 @@
+
+  <a href="{{ page.version_prefix }}/docs/skylark/lib/${global_name}.html">Global Functions & Constants</a>
+
+
+</h2>
+<div class="toc">
+  <ul>
+
+#foreach ($name in $global_functions)
+
+    <li>
+
+
+      <a href="{{ page.version_prefix }}/docs/skylark/lib/${global_name}.html#${name}">${name}</a>
+
+
+    </li>
+
+#end
+
+  </ul>
+</div>
+<h2>
+  Global Modules
+</h2>
+<div class="toc">
+  <ul>
+
+#foreach ($name in $global_modules)
+
+    <li>
+
+
+      <a href="{{ page.version_prefix }}/docs/skylark/lib/${name}.html">${name}</a>
+
+
+    </li>
+
+#end
+
+  </ul>
+</div>
+#foreach ($entry in $modules.entrySet())
+<h2>
+
+
+  <a href="{{ page.version_prefix }}/docs/skylark/lib/skylark-${entry.key.templateIdentifier}.html">${entry.key.title}</a>
+
+
+</h2>
+<div class="toc">
+  <ul>
+  #foreach ($module in $entry.value)
+
+    <li>
+
+
+      <a href="{{ page.version_prefix }}/docs/skylark/lib/${module.name}.html">${module.title}</a>
+
+
+    </li>
+
+  #end
+  </ul>
+</div>
+#end