Skip to content
Snippets Groups Projects
Select Git revision
  • 78b758f94c4243654ece230c93c65842f738be26
  • master default protected
  • ci
3 results

RagDocBuilder.java

Blame
  • RagDocBuilder.java 6.55 KiB
    /* Copyright (c) 2013-2017, Jesper Öqvist <jesper.oqvist@cs.lth.se>
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice,
     * this list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form must reproduce the above copyright notice,
     * this list of conditions and the following disclaimer in the documentation
     * and/or other materials provided with the distribution.
     *
     * 3. Neither the name of the copyright holder nor the names of its
     * contributors may be used to endorse or promote products derived from this
     * software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     */
    package org.extendj.ragdoc;
    
    import org.extendj.ast.ASTNode;
    import org.extendj.ast.BytecodeReader;
    import org.extendj.ast.CompilationUnit;
    import org.extendj.ast.Frontend;
    import org.extendj.ast.JavaParser;
    import org.extendj.ast.Problem;
    import org.extendj.ast.Program;
    import org.extendj.ast.TypeDecl;
    import se.llbit.json.JsonObject;
    import se.llbit.json.JsonValue;
    import se.llbit.json.PrettyPrinter;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.PrintStream;
    import java.nio.file.Files;
    import java.nio.file.StandardCopyOption;
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * Generate API documentation for a JastAdd project.
     *
     * @author Jesper Öqvist <jesper.oqvist@cs.lth.se>
     */
    public class RagDocBuilder extends Frontend {
      /** Generate pretty-printed JSON if in debug mode, otherwise minified JSON is generated. */
      private static final boolean DEBUG = false;
      private JsonBuilder jsonBuilder;
    
      public static void main(String args[]) {
        RagDocBuilder rd = new RagDocBuilder();
        int result = rd.compile(args);
        if (result != EXIT_SUCCESS) {
          System.exit(result);
        }
      }
    
      /**
       * @return {@code true} if documentation generation succeeds
       */
      public int compile(String[] args) {
        // TODO use command-line arg for ragRoot!
        // TODO add package exclude argument.
        File userDir = new File(System.getProperty("user.dir"));
        if (userDir.isDirectory()) {
          jsonBuilder = new JsonBuilder(userDir);
        } else {
          jsonBuilder = new JsonBuilder(new File("."));
        }
        ASTNode.jsonBuilder = jsonBuilder;
        return run(args, Program.defaultBytecodeReader(), Program.defaultJavaParser());
      }
    
      @Override public int run(String[] args, BytecodeReader reader, JavaParser parser) {
        System.out.println("Analyzing source tree...");
        long start = System.currentTimeMillis();
        int result = super.run(args, reader, parser);
        long time = System.currentTimeMillis() - start;
        System.out.format("Analysis took %fs%n", time / 1000.0);
        try {
          File outputDir;
          if (program.options().hasValueForOption("-d")) {
            outputDir = new File(program.options().getValueForOption("-d"));
          } else {
            outputDir = new File("doc");
          }
          if (!outputDir.isDirectory()) {
            outputDir.mkdir();
          }
          if (!outputDir.isDirectory()) {
            System.err.format("Error: not a valid output directory: '%s'\n", outputDir.getName());
            return EXIT_CONFIG_ERROR;
          }
          System.out.println("Writing package summary.");
          outputJson(outputDir, "packages.json", jsonBuilder.packageIndex());
    
          System.out.println("Writing classes...");
          for (Map.Entry<TypeDecl, JsonObject> entry : jsonBuilder.typemap.entrySet()) {
            TypeDecl type = entry.getKey();
            JsonObject typeJson = entry.getValue();
            JsonBuilder.sortArrayBy(typeJson.get("members").array(), "name");
            String fileName = type.name() + jsonBuilder.typeId(type).substring(1) + ".json";
            outputJson(outputDir, fileName, typeJson);
          }
    
          System.out.println("Writing source files...");
          for (Map.Entry<String, File> entry : jsonBuilder.sourceFiles.entrySet()) {
            File file = entry.getValue();
            String path = entry.getKey();
            path = path.replace('/', '_').replace('\\', '_');
            copyFile(outputDir, path, file);
          }
        } catch (IOException e) {
          e.printStackTrace();
          return EXIT_ERROR;
        }
        return result;
      }
    
      private void copyFile(File outputDir, String path, File file) throws IOException {
        Files.copy(file.toPath(), new File(outputDir, path).toPath(),
            StandardCopyOption.REPLACE_EXISTING);
      }
    
      private void outputJson(File dir, String fileName, JsonValue value) throws IOException {
        File outputFile = new File(dir, fileName);
        PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
        JsonObject data = new JsonObject();
        data.set("data", value);
        if (DEBUG) {
          PrettyPrinter pp = new PrettyPrinter("  ", out);
          data.prettyPrint(pp);
        } else {
          out.print(data.toCompactString());
        }
        out.close();
      }
    
      @Override protected int processCompilationUnit(CompilationUnit unit) {
        if (unit.fromSource()) {
          try {
            Collection<Problem> parseErrors = unit.parseErrors();
            if (!parseErrors.isEmpty()) {
              processErrors(parseErrors, unit);
              return EXIT_ERROR;
            } else {
              jsonBuilder.addCompilationUnit(unit);
            }
          } catch (Throwable t) {
            System.err.println("Errors:");
            System.err.println("Fatal exception while processing " +
                unit.pathName() + ":");
            t.printStackTrace(System.err);
            return EXIT_ERROR;
          }
        }
        return EXIT_SUCCESS;
      }
    
      @Override protected String name() {
        return "RagDoll";
      }
    
      @Override protected String version() {
        return "2.0.0 SNAPSHOT";
      }
    
      @Override protected void initOptions() {
        super.initOptions();
      }
    
    }