JDK 11 jdk.compiler.jmod - Compiler Tool

JDK 11 jdk.compiler.jmod is the JMOD file for JDK 11 Compiler tool, which can be invoked by the "javac" command.

JDK 11 Compiler tool compiled class files are stored in \fyicenter\jdk-11.0.1\jmods\jdk.compiler.jmod.

JDK 11 Compiler tool compiled class files are also linked and stored in the \fyicenter\jdk-11.0.1\lib\modules JImage file.

JDK 11 Compiler source code files are stored in \fyicenter\jdk-11.0.1\lib\src.zip\jdk.compiler.

You can click and view the content of each source code file in the list below.

✍: FYIcenter

jdk/internal/shellsupport/doc/JavadocFormatter.java

/*
 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package jdk.internal.shellsupport.doc;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Stack;

import javax.lang.model.element.Name;
import javax.tools.JavaFileObject.Kind;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

import com.sun.source.doctree.AttributeTree;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.doctree.DocTree;
import com.sun.source.doctree.EndElementTree;
import com.sun.source.doctree.EntityTree;
import com.sun.source.doctree.InlineTagTree;
import com.sun.source.doctree.LinkTree;
import com.sun.source.doctree.LiteralTree;
import com.sun.source.doctree.ParamTree;
import com.sun.source.doctree.ReturnTree;
import com.sun.source.doctree.StartElementTree;
import com.sun.source.doctree.TextTree;
import com.sun.source.doctree.ThrowsTree;
import com.sun.source.util.DocTreeScanner;
import com.sun.source.util.DocTrees;
import com.sun.source.util.JavacTask;
import com.sun.tools.doclint.Entity;
import com.sun.tools.doclint.HtmlTag;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.StringUtils;

/**A javadoc to plain text formatter.
 *
 */
public class JavadocFormatter {

    private static final String CODE_RESET = "\033[0m";
    private static final String CODE_HIGHLIGHT = "\033[1m";
    private static final String CODE_UNDERLINE = "\033[4m";

    private final int lineLimit;
    private final boolean escapeSequencesSupported;

    /** Construct the formatter.
     *
     * @param lineLimit maximum line length
     * @param escapeSequencesSupported whether escape sequences are supported
     */
    public JavadocFormatter(int lineLimit, boolean escapeSequencesSupported) {
        this.lineLimit = lineLimit;
        this.escapeSequencesSupported = escapeSequencesSupported;
    }

    private static final int MAX_LINE_LENGTH = 95;
    private static final int SHORTEST_LINE = 30;
    private static final int INDENT = 4;

    /**Format javadoc to plain text.
     *
     * @param header element caption that should be used
     * @param javadoc to format
     * @return javadoc formatted to plain text
     */
    public String formatJavadoc(String header, String javadoc) {
        try {
            StringBuilder result = new StringBuilder();

            result.append(escape(CODE_HIGHLIGHT)).append(header).append(escape(CODE_RESET)).append("\n");

            if (javadoc == null) {
                return result.toString();
            }

            JavacTask task = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, null, null, null, null, null);
            DocTrees trees = DocTrees.instance(task);
            DocCommentTree docComment = trees.getDocCommentTree(new SimpleJavaFileObject(new URI("mem://doc.html"), Kind.HTML) {
                @Override @DefinedBy(Api.COMPILER)
                public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
                    return "<body>" + javadoc + "</body>";
                }
            });

            new FormatJavadocScanner(result, task).scan(docComment, null);

            addNewLineIfNeeded(result);

            return result.toString();
        } catch (URISyntaxException ex) {
            throw new InternalError("Unexpected exception", ex);
        }
    }

    private class FormatJavadocScanner extends DocTreeScanner<Object, Object> {
        private final StringBuilder result;
        private final JavacTask task;
        private int reflownTo;
        private int indent;
        private int limit = Math.min(lineLimit, MAX_LINE_LENGTH);
        private boolean pre;
        private Map<StartElementTree, Integer> tableColumns;

        public FormatJavadocScanner(StringBuilder result, JavacTask task) {
            this.result = result;
            this.task = task;
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitDocComment(DocCommentTree node, Object p) {
            tableColumns = countTableColumns(node);
            reflownTo = result.length();
            scan(node.getFirstSentence(), p);
            scan(node.getBody(), p);
            reflow(result, reflownTo, indent, limit);
            for (Sections current : docSections.keySet()) {
                boolean seenAny = false;
                for (DocTree t : node.getBlockTags()) {
                    if (current.matches(t)) {
                        if (!seenAny) {
                            seenAny = true;
                            if (result.charAt(result.length() - 1) != '\n')
                                result.append("\n");
                            result.append("\n");
                            result.append(escape(CODE_UNDERLINE))
                                  .append(docSections.get(current))
                                  .append(escape(CODE_RESET))
                                  .append("\n");
                        }

                        scan(t, null);
                    }
                }
            }
            return null;
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitText(TextTree node, Object p) {
            String text = node.getBody();
            if (!pre) {
                text = text.replaceAll("[ \t\r\n]+", " ").trim();
                if (text.isEmpty()) {
                    text = " ";
                }
            } else {
                text = text.replaceAll("\n", "\n" + indentString(indent));
            }
            result.append(text);
            return null;
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitLink(LinkTree node, Object p) {
            if (!node.getLabel().isEmpty()) {
                scan(node.getLabel(), p);
            } else {
                result.append(node.getReference().getSignature());
            }
            return null;
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitParam(ParamTree node, Object p) {
            return formatDef(node.getName().getName(), node.getDescription());
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitThrows(ThrowsTree node, Object p) {
            return formatDef(node.getExceptionName().getSignature(), node.getDescription());
        }

        public Object formatDef(CharSequence name, List<? extends DocTree> description) {
            result.append(name);
            result.append(" - ");
            reflownTo = result.length();
            indent = name.length() + 3;

            if (limit - indent < SHORTEST_LINE) {
                result.append("\n");
                result.append(indentString(INDENT));
                indent = INDENT;
                reflownTo += INDENT;
            }
            try {
                return scan(description, null);
            } finally {
                reflow(result, reflownTo, indent, limit);
                result.append("\n");
            }
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitLiteral(LiteralTree node, Object p) {
            return scan(node.getBody(), p);
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitReturn(ReturnTree node, Object p) {
            reflownTo = result.length();
            try {
                return super.visitReturn(node, p);
            } finally {
                reflow(result, reflownTo, 0, limit);
            }
        }

        Stack<Integer> listStack = new Stack<>();
        Stack<Integer> defStack = new Stack<>();
        Stack<Integer> tableStack = new Stack<>();
        Stack<List<Integer>> cellsStack = new Stack<>();
        Stack<List<Boolean>> headerStack = new Stack<>();

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitStartElement(StartElementTree node, Object p) {
            switch (getHtmlTag(node.getName())) {
                case P:
                    if (lastNode!= null && lastNode.getKind() == DocTree.Kind.START_ELEMENT &&
                        HtmlTag.get(((StartElementTree) lastNode).getName()) == HtmlTag.LI) {
                        //ignore
                        break;
                    }
                    reflowTillNow();
                    addNewLineIfNeeded(result);
                    result.append(indentString(indent));
                    reflownTo = result.length();
                    break;
                case BLOCKQUOTE:
                    reflowTillNow();
                    indent += INDENT;
                    break;
                case PRE:
                    reflowTillNow();
                    pre = true;
                    break;
                case UL:
                    reflowTillNow();
                    listStack.push(-1);
                    indent += INDENT;
                    break;
                case OL:
                    reflowTillNow();
                    listStack.push(1);
                    indent += INDENT;
                    break;
                case DL:
                    reflowTillNow();
                    defStack.push(indent);
                    break;
                case LI:
                    reflowTillNow();
                    if (!listStack.empty()) {
                        addNewLineIfNeeded(result);

                        int top = listStack.pop();

                        if (top == (-1)) {
                            result.append(indentString(indent - 2));
                            result.append("* ");
                        } else {
                            result.append(indentString(indent - 3));
                            result.append("" + top++ + ". ");
                        }

                        listStack.push(top);

                        reflownTo = result.length();
                    }
                    break;
                case DT:
                    reflowTillNow();
                    if (!defStack.isEmpty()) {
                        addNewLineIfNeeded(result);
                        indent = defStack.peek();
                        result.append(escape(CODE_HIGHLIGHT));
                    }
                    break;
                case DD:
                    reflowTillNow();
                    if (!defStack.isEmpty()) {
                        if (indent == defStack.peek()) {
                            result.append(escape(CODE_RESET));
                        }
                        addNewLineIfNeeded(result);
                        indent = defStack.peek() + INDENT;
                        result.append(indentString(indent));
                    }
                    break;
                case H1: case H2: case H3:
                case H4: case H5: case H6:
                    reflowTillNow();
                    addNewLineIfNeeded(result);
                    result.append("\n")
                          .append(escape(CODE_UNDERLINE));
                    reflownTo = result.length();
                    break;
                case TABLE:
                    int columns = tableColumns.get(node);

                    if (columns == 0) {
                        break; //broken input
                    }

                    reflowTillNow();
                    addNewLineIfNeeded(result);
                    reflownTo = result.length();

                    tableStack.push(limit);

                    limit = (limit - 1) / columns - 3;

                    for (int sep = 0; sep < (limit + 3) * columns + 1; sep++) {
                        result.append("-");
                    }

                    result.append("\n");

                    break;
                case TR:
                    if (cellsStack.size() >= tableStack.size()) {
                        //unclosed <tr>:
                        handleEndElement(node.getName());
                    }
                    cellsStack.push(new ArrayList<>());
                    headerStack.push(new ArrayList<>());
                    break;
                case TH:
                case TD:
                    if (cellsStack.isEmpty()) {
                        //broken code
                        break;
                    }
                    reflowTillNow();
                    result.append("\n");
                    reflownTo = result.length();
                    cellsStack.peek().add(result.length());
                    headerStack.peek().add(HtmlTag.get(node.getName()) == HtmlTag.TH);
                    break;
                case IMG:
                    for (DocTree attr : node.getAttributes()) {
                        if (attr.getKind() != DocTree.Kind.ATTRIBUTE) {
                            continue;
                        }
                        AttributeTree at = (AttributeTree) attr;
                        if ("alt".equals(StringUtils.toLowerCase(at.getName().toString()))) {
                            addSpaceIfNeeded(result);
                            scan(at.getValue(), null);
                            addSpaceIfNeeded(result);
                            break;
                        }
                    }
                    break;
                default:
                    addSpaceIfNeeded(result);
                    break;
            }
            return null;
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitEndElement(EndElementTree node, Object p) {
            handleEndElement(node.getName());
            return super.visitEndElement(node, p);
        }

        private void handleEndElement(Name name) {
            switch (getHtmlTag(name)) {
                case BLOCKQUOTE:
                    indent -= INDENT;
                    break;
                case PRE:
                    pre = false;
                    addNewLineIfNeeded(result);
                    reflownTo = result.length();
                    break;
                case UL: case OL:
                    if (listStack.isEmpty()) { //ignore stray closing tag
                        break;
                    }
                    reflowTillNow();
                    listStack.pop();
                    indent -= INDENT;
                    addNewLineIfNeeded(result);
                    break;
                case DL:
                    if (defStack.isEmpty()) {//ignore stray closing tag
                        break;
                    }
                    reflowTillNow();
                    if (indent == defStack.peek()) {
                        result.append(escape(CODE_RESET));
                    }
                    indent = defStack.pop();
                    addNewLineIfNeeded(result);
                    break;
                case H1: case H2: case H3:
                case H4: case H5: case H6:
                    reflowTillNow();
                    result.append(escape(CODE_RESET))
                          .append("\n");
                    reflownTo = result.length();
                    break;
                case TABLE:
                    if (cellsStack.size() >= tableStack.size()) {
                        //unclosed <tr>:
                        handleEndElement(task.getElements().getName("tr"));
                    }

                    if (tableStack.isEmpty()) {
                        break;
                    }

                    limit = tableStack.pop();
                    break;
                case TR:
                    if (cellsStack.isEmpty()) {
                        break;
                    }

                    reflowTillNow();

                    List<Integer> cells = cellsStack.pop();
                    List<Boolean> headerFlags = headerStack.pop();
                    List<String[]> content = new ArrayList<>();
                    int maxLines = 0;

                    result.append("\n");

                    while (!cells.isEmpty()) {
                        int currentCell = cells.remove(cells.size() - 1);
                        String[] lines = result.substring(currentCell, result.length()).split("\n");

                        result.delete(currentCell - 1, result.length());

                        content.add(lines);
                        maxLines = Math.max(maxLines, lines.length);
                    }

                    Collections.reverse(content);

                    for (int line = 0; line < maxLines; line++) {
                        for (int column = 0; column < content.size(); column++) {
                            String[] lines = content.get(column);
                            String currentLine = line < lines.length ? lines[line] : "";
                            result.append("| ");
                            boolean header = headerFlags.get(column);
                            if (header) {
                                result.append(escape(CODE_HIGHLIGHT));
                            }
                            result.append(currentLine);
                            if (header) {
                                result.append(escape(CODE_RESET));
                            }
                            int padding = limit - currentLine.length();
                            if (padding > 0)
                                result.append(indentString(padding));
                            result.append(" ");
                        }
                        result.append("|\n");
                    }

                    for (int sep = 0; sep < (limit + 3) * content.size() + 1; sep++) {
                        result.append("-");
                    }

                    result.append("\n");

                    reflownTo = result.length();
                    break;
                case TD:
                case TH:
                    break;
                default:
                    addSpaceIfNeeded(result);
                    break;
            }
        }

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object visitEntity(EntityTree node, Object p) {
            String name = node.getName().toString();
            int code = -1;
            if (name.startsWith("#")) {
                try {
                    int v = StringUtils.toLowerCase(name).startsWith("#x")
                            ? Integer.parseInt(name.substring(2), 16)
                            : Integer.parseInt(name.substring(1), 10);
                    if (Entity.isValid(v)) {
                        code = v;
                    }
                } catch (NumberFormatException ex) {
                    //ignore
                }
            } else {
                Entity entity = Entity.get(name);
                if (entity != null) {
                    code = entity.code;
                }
            }
            if (code != (-1)) {
                result.appendCodePoint(code);
            } else {
                result.append(node.toString());
            }
            return super.visitEntity(node, p);
        }

        private DocTree lastNode;

        @Override @DefinedBy(Api.COMPILER_TREE)
        public Object scan(DocTree node, Object p) {
            if (node instanceof InlineTagTree) {
                addSpaceIfNeeded(result);
            }
            try {
                return super.scan(node, p);
            } finally {
                if (node instanceof InlineTagTree) {
                    addSpaceIfNeeded(result);
                }
                lastNode = node;
            }
        }

        private void reflowTillNow() {
            while (result.length() > 0 && result.charAt(result.length() - 1) == ' ')
                result.delete(result.length() - 1, result.length());
            reflow(result, reflownTo, indent, limit);
            reflownTo = result.length();
        }
    };

    private String escape(String sequence) {
        return this.escapeSequencesSupported ? sequence : "";
    }

    private static final Map<Sections, String> docSections = new LinkedHashMap<>();

    static {
        ResourceBundle bundle =
                ResourceBundle.getBundle("jdk.internal.shellsupport.doc.resources.javadocformatter");
        docSections.put(Sections.TYPE_PARAMS, bundle.getString("CAP_TypeParameters"));
        docSections.put(Sections.PARAMS, bundle.getString("CAP_Parameters"));
        docSections.put(Sections.RETURNS, bundle.getString("CAP_Returns"));
        docSections.put(Sections.THROWS, bundle.getString("CAP_Thrown_Exceptions"));
    }

    private static String indentString(int indent) {
        char[] content = new char[indent];
        Arrays.fill(content, ' ');
        return new String(content);
    }

    private static void reflow(StringBuilder text, int from, int indent, int limit) {
        int lineStart = from;

        while (lineStart > 0 && text.charAt(lineStart - 1) != '\n') {
            lineStart--;
        }

        int lineChars = from - lineStart;
        int pointer = from;
        int lastSpace = -1;

        while (pointer < text.length()) {
            if (text.charAt(pointer) == ' ')
                lastSpace = pointer;
            if (lineChars >= limit) {
                if (lastSpace != (-1)) {
                    text.setCharAt(lastSpace, '\n');
                    text.insert(lastSpace + 1, indentString(indent));
                    lineChars = indent + pointer - lastSpace - 1;
                    pointer += indent;
                    lastSpace = -1;
                }
            }
            lineChars++;
            pointer++;
        }
    }

    private static void addNewLineIfNeeded(StringBuilder text) {
        if (text.length() > 0 && text.charAt(text.length() - 1) != '\n') {
            text.append("\n");
        }
    }

    private static void addSpaceIfNeeded(StringBuilder text) {
        if (text.length() == 0)
            return ;

        char last = text.charAt(text.length() - 1);

        if (last != ' ' && last != '\n') {
            text.append(" ");
        }
    }

    private static HtmlTag getHtmlTag(Name name) {
        HtmlTag tag = HtmlTag.get(name);

        return tag != null ? tag : HtmlTag.HTML; //using HtmlTag.HTML as default no-op value
    }

    private static Map<StartElementTree, Integer> countTableColumns(DocCommentTree dct) {
        Map<StartElementTree, Integer> result = new IdentityHashMap<>();

        new DocTreeScanner<Void, Void>() {
            private StartElementTree currentTable;
            private int currentMaxColumns;
            private int currentRowColumns;

            @Override @DefinedBy(Api.COMPILER_TREE)
            public Void visitStartElement(StartElementTree node, Void p) {
                switch (getHtmlTag(node.getName())) {
                    case TABLE: currentTable = node; break;
                    case TR:
                        currentMaxColumns = Math.max(currentMaxColumns, currentRowColumns);
                        currentRowColumns = 0;
                        break;
                    case TD:
                    case TH: currentRowColumns++; break;
                }
                return super.visitStartElement(node, p);
            }

            @Override @DefinedBy(Api.COMPILER_TREE)
            public Void visitEndElement(EndElementTree node, Void p) {
                if (HtmlTag.get(node.getName()) == HtmlTag.TABLE) {
                    closeTable();
                }
                return super.visitEndElement(node, p);
            }

            @Override @DefinedBy(Api.COMPILER_TREE)
            public Void visitDocComment(DocCommentTree node, Void p) {
                try {
                    return super.visitDocComment(node, p);
                } finally {
                    closeTable();
                }
            }

            private void closeTable() {
                if (currentTable != null) {
                    result.put(currentTable, Math.max(currentMaxColumns, currentRowColumns));
                    currentTable = null;
                }
            }
        }.scan(dct, null);

        return result;
    }

    private enum Sections {
        TYPE_PARAMS {
            @Override public boolean matches(DocTree t) {
                return t.getKind() == DocTree.Kind.PARAM && ((ParamTree) t).isTypeParameter();
            }
        },
        PARAMS {
            @Override public boolean matches(DocTree t) {
                return t.getKind() == DocTree.Kind.PARAM && !((ParamTree) t).isTypeParameter();
            }
        },
        RETURNS {
            @Override public boolean matches(DocTree t) {
                return t.getKind() == DocTree.Kind.RETURN;
            }
        },
        THROWS {
            @Override public boolean matches(DocTree t) {
                return t.getKind() == DocTree.Kind.THROWS;
            }
        };

        public abstract boolean matches(DocTree t);
    }
}

jdk/internal/shellsupport/doc/JavadocFormatter.java

 

JDK 11 jdk.crypto.cryptoki.jmod - Crypto KI Module

JDK 11 jdk.charsets.jmod - Charsets Module

Download and Use JDK 11

⇑⇑ FAQ for JDK (Java Development Kit)

2020-08-13, 20643👍, 0💬