JDK 17 jdk.internal.le.jmod - Internal Line Editing Module

JDK 17 jdk.internal.le.jmod is the JMOD file for JDK 17 Internal Line Editing module.

JDK 17 Internal Line Editing module compiled class files are stored in \fyicenter\jdk-17.0.5\jmods\jdk.internal.le.jmod.

JDK 17 Internal Line Editing module compiled class files are also linked and stored in the \fyicenter\jdk-17.0.5\lib\modules JImage file.

JDK 17 Internal Line Editing module source code files are stored in \fyicenter\jdk-17.0.5\lib\src.zip\jdk.internal.le.

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

✍: FYIcenter

jdk/internal/org/jline/reader/impl/DefaultParser.java

/*
 * Copyright (c) 2002-2020, the original author or authors.
 *
 * This software is distributable under the BSD license. See the terms of the
 * BSD license in the documentation provided with this software.
 *
 * https://opensource.org/licenses/BSD-3-Clause
 */
package jdk.internal.org.jline.reader.impl;

import java.util.*;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import jdk.internal.org.jline.reader.CompletingParsedLine;
import jdk.internal.org.jline.reader.EOFError;
import jdk.internal.org.jline.reader.ParsedLine;
import jdk.internal.org.jline.reader.Parser;

public class DefaultParser implements Parser {

    public enum Bracket {
        ROUND,   // ()
        CURLY,   // {}
        SQUARE,  // []
        ANGLE    // <>
    }

    private char[] quoteChars = {'\'', '"'};

    private char[] escapeChars = {'\\'};

    private boolean eofOnUnclosedQuote;

    private boolean eofOnEscapedNewLine;

    private char[] openingBrackets = null;

    private char[] closingBrackets = null;

    private String regexVariable = "[a-zA-Z_]+[a-zA-Z0-9_-]*((\\.|\\['|\\[\"|\\[)[a-zA-Z0-9_-]*(|']|\"]|]))?";
    private String regexCommand = "[:]?[a-zA-Z]+[a-zA-Z0-9_-]*";
    private int commandGroup = 4;

    //
    // Chainable setters
    //

    public DefaultParser quoteChars(final char[] chars) {
        this.quoteChars = chars;
        return this;
    }

    public DefaultParser escapeChars(final char[] chars) {
        this.escapeChars = chars;
        return this;
    }

    public DefaultParser eofOnUnclosedQuote(boolean eofOnUnclosedQuote) {
        this.eofOnUnclosedQuote = eofOnUnclosedQuote;
        return this;
    }

    public DefaultParser eofOnUnclosedBracket(Bracket... brackets) {
        setEofOnUnclosedBracket(brackets);
        return this;
    }

    public DefaultParser eofOnEscapedNewLine(boolean eofOnEscapedNewLine) {
        this.eofOnEscapedNewLine = eofOnEscapedNewLine;
        return this;
    }

    public DefaultParser regexVariable(String regexVariable) {
        this.regexVariable = regexVariable;
        return this;
    }

    public DefaultParser regexCommand(String regexCommand) {
        this.regexCommand = regexCommand;
        return this;
    }

    public DefaultParser commandGroup(int commandGroup) {
        this.commandGroup = commandGroup;
        return this;
    }

    //
    // Java bean getters and setters
    //

    public void setQuoteChars(final char[] chars) {
        this.quoteChars = chars;
    }

    public char[] getQuoteChars() {
        return this.quoteChars;
    }

    public void setEscapeChars(final char[] chars) {
        this.escapeChars = chars;
    }

    public char[] getEscapeChars() {
        return this.escapeChars;
    }

    public void setEofOnUnclosedQuote(boolean eofOnUnclosedQuote) {
        this.eofOnUnclosedQuote = eofOnUnclosedQuote;
    }

    public boolean isEofOnUnclosedQuote() {
        return eofOnUnclosedQuote;
    }

    public void setEofOnEscapedNewLine(boolean eofOnEscapedNewLine) {
        this.eofOnEscapedNewLine = eofOnEscapedNewLine;
    }

    public boolean isEofOnEscapedNewLine() {
        return eofOnEscapedNewLine;
    }

    public void setEofOnUnclosedBracket(Bracket... brackets) {
        if (brackets == null) {
            openingBrackets = null;
            closingBrackets = null;
        } else {
            Set<Bracket> bs = new HashSet<>(Arrays.asList(brackets));
            openingBrackets = new char[bs.size()];
            closingBrackets = new char[bs.size()];
            int i = 0;
            for (Bracket b : bs) {
                switch (b) {
                case ROUND:
                    openingBrackets[i] = '(';
                    closingBrackets[i] = ')';
                    break;
                case CURLY:
                    openingBrackets[i] = '{';
                    closingBrackets[i] = '}';
                    break;
                case SQUARE:
                    openingBrackets[i] = '[';
                    closingBrackets[i] = ']';
                    break;
                case ANGLE:
                    openingBrackets[i] = '<';
                    closingBrackets[i] = '>';
                    break;
                }
                i++;
            }
        }
    }

    public void setRegexVariable(String regexVariable) {
        this.regexVariable = regexVariable;
    }

    public void setRegexCommand(String regexCommand) {
        this.regexCommand = regexCommand;
    }

    public void setCommandGroup(int commandGroup) {
        this.commandGroup = commandGroup;
    }

    @Override
    public boolean validCommandName(String name) {
        return name != null && name.matches(regexCommand);
    }

    @Override
    public boolean validVariableName(String name) {
        return name != null && regexVariable != null && name.matches(regexVariable);
    }


    @Override
    public String getCommand(final String line) {
        String out = "";
        boolean checkCommandOnly = regexVariable == null;
        if (!checkCommandOnly) {
            Pattern patternCommand = Pattern.compile("^\\s*" + regexVariable + "=(" + regexCommand + ")(\\s+|$)");
            Matcher matcher = patternCommand.matcher(line);
            if (matcher.find()) {
                out = matcher.group(commandGroup);
            } else {
                checkCommandOnly = true;
            }
        }
        if (checkCommandOnly) {
            out = line.trim().split("\\s+")[0];
            if (!out.matches(regexCommand)) {
                out = "";
            }
        }
        return out;
    }

    @Override
    public String getVariable(final String line) {
        String out = null;
        if (regexVariable != null) {
            Pattern patternCommand = Pattern.compile("^\\s*(" + regexVariable + ")\\s*=[^=~].*");
            Matcher matcher = patternCommand.matcher(line);
            if (matcher.find()) {
                out = matcher.group(1);
            }
        }
        return out;
    }

    public ParsedLine parse(final String line, final int cursor, ParseContext context) {
        List<String> words = new LinkedList<>();
        StringBuilder current = new StringBuilder();
        int wordCursor = -1;
        int wordIndex = -1;
        int quoteStart = -1;
        int rawWordCursor = -1;
        int rawWordLength = -1;
        int rawWordStart = 0;
        BracketChecker bracketChecker = new BracketChecker(cursor);
        boolean quotedWord = false;

        for (int i = 0; (line != null) && (i < line.length()); i++) {
            // once we reach the cursor, set the
            // position of the selected index
            if (i == cursor) {
                wordIndex = words.size();
                // the position in the current argument is just the
                // length of the current argument
                wordCursor = current.length();
                rawWordCursor = i - rawWordStart;
            }

            if (quoteStart < 0 && isQuoteChar(line, i)) {
                // Start a quote block
                quoteStart = i;
                if (current.length()==0) {
                    quotedWord = true;
                    if (context == ParseContext.SPLIT_LINE) {
                        current.append(line.charAt(i));
                    }
                } else {
                    current.append(line.charAt(i));
                }
            } else if (quoteStart >= 0 && line.charAt(quoteStart) == line.charAt(i) && !isEscaped(line, i)) {
                // End quote block
                if (!quotedWord || context == ParseContext.SPLIT_LINE) {
                    current.append(line.charAt(i));
                } else if (rawWordCursor >= 0 && rawWordLength < 0) {
                    rawWordLength = i - rawWordStart + 1;
                }
                quoteStart = -1;
                quotedWord = false;
            } else if (quoteStart < 0 && isDelimiter(line, i)) {
                // Delimiter
                if (current.length() > 0) {
                    words.add(current.toString());
                    current.setLength(0); // reset the arg
                    if (rawWordCursor >= 0 && rawWordLength < 0) {
                        rawWordLength = i - rawWordStart;
                    }
                }
                rawWordStart = i + 1;
            } else {
                if (!isEscapeChar(line, i)) {
                    current.append(line.charAt(i));
                    if (quoteStart < 0) {
                        bracketChecker.check(line, i);
                    }
                } else if (context == ParseContext.SPLIT_LINE) {
                    current.append(line.charAt(i));
                }
            }
        }

        if (current.length() > 0 || cursor == line.length()) {
            words.add(current.toString());
            if (rawWordCursor >= 0 && rawWordLength < 0) {
                rawWordLength = line.length() - rawWordStart;
            }
        }

        if (cursor == line.length()) {
            wordIndex = words.size() - 1;
            wordCursor = words.get(words.size() - 1).length();
            rawWordCursor = cursor - rawWordStart;
            rawWordLength = rawWordCursor;
        }

        if (context != ParseContext.COMPLETE && context != ParseContext.SPLIT_LINE) {
            if (eofOnEscapedNewLine && isEscapeChar(line, line.length() - 1)) {
                throw new EOFError(-1, -1, "Escaped new line", "newline");
            }
            if (eofOnUnclosedQuote && quoteStart >= 0) {
                throw new EOFError(-1, -1, "Missing closing quote", line.charAt(quoteStart) == '\''
                        ? "quote" : "dquote");
            }
            if (bracketChecker.isClosingBracketMissing() || bracketChecker.isOpeningBracketMissing()) {
                String message = null;
                String missing = null;
                if (bracketChecker.isClosingBracketMissing()) {
                    message = "Missing closing brackets";
                    missing = "add: " + bracketChecker.getMissingClosingBrackets();
                } else {
                    message = "Missing opening bracket";
                    missing = "missing: " + bracketChecker.getMissingOpeningBracket();
                }
                throw new EOFError(-1, -1, message, missing,
                        bracketChecker.getOpenBrackets(), bracketChecker.getNextClosingBracket());
            }
        }

        String openingQuote = quotedWord ? line.substring(quoteStart, quoteStart + 1) : null;
        return new ArgumentList(line, words, wordIndex, wordCursor, cursor, openingQuote, rawWordCursor, rawWordLength);
    }

    /**
     * Returns true if the specified character is a whitespace parameter. Check to ensure that the character is not
     * escaped by any of {@link #getQuoteChars}, and is not escaped by any of the {@link #getEscapeChars}, and
     * returns true from {@link #isDelimiterChar}.
     *
     * @param buffer    The complete command buffer
     * @param pos       The index of the character in the buffer
     * @return          True if the character should be a delimiter
     */
    public boolean isDelimiter(final CharSequence buffer, final int pos) {
        return !isQuoted(buffer, pos) && !isEscaped(buffer, pos) && isDelimiterChar(buffer, pos);
    }

    public boolean isQuoted(final CharSequence buffer, final int pos) {
        return false;
    }

    public boolean isQuoteChar(final CharSequence buffer, final int pos) {
        if (pos < 0) {
            return false;
        }
        if (quoteChars != null) {
            for (char e : quoteChars) {
                if (e == buffer.charAt(pos)) {
                    return !isEscaped(buffer, pos);
                }
            }
        }
        return false;
    }

    @Override
    public boolean isEscapeChar(char ch) {
        if (escapeChars != null) {
            for (char e : escapeChars) {
                if (e == ch) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Check if this character is a valid escape char (i.e. one that has not been escaped)
     *
     * @param buffer
     *          the buffer to check in
     * @param pos
     *          the position of the character to check
     * @return true if the character at the specified position in the given buffer is an escape
     *         character and the character immediately preceding it is not an escape character.
     */
    public boolean isEscapeChar(final CharSequence buffer, final int pos) {
        if (pos < 0) {
            return false;
        }
        char ch = buffer.charAt(pos);
        return isEscapeChar(ch) && !isEscaped(buffer, pos);
    }

    /**
     * Check if a character is escaped (i.e. if the previous character is an escape)
     *
     * @param buffer
     *          the buffer to check in
     * @param pos
     *          the position of the character to check
     * @return true if the character at the specified position in the given buffer is an escape
     *         character and the character immediately preceding it is an escape character.
     */
    public boolean isEscaped(final CharSequence buffer, final int pos) {
        if (pos <= 0) {
            return false;
        }
        return isEscapeChar(buffer, pos - 1);
    }

    /**
     * Returns true if the character at the specified position if a delimiter. This method will only be called if
     * the character is not enclosed in any of the {@link #getQuoteChars}, and is not escaped by any of the
     * {@link #getEscapeChars}. To perform escaping manually, override {@link #isDelimiter} instead.
     *
     * @param buffer
     *          the buffer to check in
     * @param pos
     *          the position of the character to check
     * @return true if the character at the specified position in the given buffer is a delimiter.
     */
    public boolean isDelimiterChar(CharSequence buffer, int pos) {
        return Character.isWhitespace(buffer.charAt(pos));
    }

    private boolean isRawEscapeChar(char key) {
        if (escapeChars != null) {
            for (char e : escapeChars) {
                if (e == key) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isRawQuoteChar(char key) {
        if (quoteChars != null) {
            for (char e : quoteChars) {
                if (e == key) {
                    return true;
                }
            }
        }
        return false;
    }

    private class BracketChecker {
        private int missingOpeningBracket = -1;
        private List<Integer> nested = new ArrayList<>();
        private int openBrackets = 0;
        private int cursor;
        private String nextClosingBracket;

        public BracketChecker(int cursor) {
            this.cursor = cursor;
        }

        public void check(final CharSequence buffer, final int pos) {
            if (openingBrackets == null || pos < 0) {
                return;
            }
            int bid = bracketId(openingBrackets, buffer, pos);
            if (bid >= 0) {
                nested.add(bid);
            } else {
                bid = bracketId(closingBrackets, buffer, pos);
                if (bid >= 0) {
                    if (!nested.isEmpty() && bid == nested.get(nested.size()-1)) {
                        nested.remove(nested.size()-1);
                    } else {
                        missingOpeningBracket = bid;
                    }
                }
            }
            if (cursor > pos) {
                openBrackets = nested.size();
                if (nested.size() > 0) {
                    nextClosingBracket = String.valueOf(closingBrackets[nested.get(nested.size() - 1)]);
                }
            }
        }

        public boolean isOpeningBracketMissing() {
            return missingOpeningBracket != -1;
        }

        public String getMissingOpeningBracket() {
            if (!isOpeningBracketMissing()) {
                return null;
            }
            return Character.toString(openingBrackets[missingOpeningBracket]);
        }

        public boolean isClosingBracketMissing() {
            return !nested.isEmpty();
        }

        public String getMissingClosingBrackets() {
            if (!isClosingBracketMissing()) {
                return null;
            }
            StringBuilder out = new StringBuilder();
            for (int i = nested.size() - 1; i > -1; i--) {
                out.append(closingBrackets[nested.get(i)]);
            }
            return out.toString();
        }

        public int getOpenBrackets() {
            return openBrackets;
        }

        public String getNextClosingBracket() {
            return nested.size() == 2 ? nextClosingBracket : null;
        }

        private int bracketId(final char[] brackets, final CharSequence buffer, final int pos) {
            for (int i=0; i < brackets.length; i++) {
                if (buffer.charAt(pos) == brackets[i]) {
                    return i;
                }
            }
            return -1;
        }
    }

    /**
     * The result of a delimited buffer.
     *
     * @author <a href="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
     */
    public class ArgumentList implements ParsedLine, CompletingParsedLine
    {
        private final String line;

        private final List<String> words;

        private final int wordIndex;

        private final int wordCursor;

        private final int cursor;

        private final String openingQuote;

        private final int rawWordCursor;

        private final int rawWordLength;

        @Deprecated
        public ArgumentList(final String line, final List<String> words,
                            final int wordIndex, final int wordCursor,
                            final int cursor) {
            this(line, words, wordIndex, wordCursor, cursor,
                    null, wordCursor, words.get(wordIndex).length());
        }

        /**
         *
         * @param line the command line being edited
         * @param words the list of words
         * @param wordIndex the index of the current word in the list of words
         * @param wordCursor the cursor position within the current word
         * @param cursor the cursor position within the line
         * @param openingQuote the opening quote (usually '\"' or '\'') or null
         * @param rawWordCursor the cursor position inside the raw word (i.e. including quotes and escape characters)
         * @param rawWordLength the raw word length, including quotes and escape characters
         */
        public ArgumentList(final String line, final List<String> words,
                            final int wordIndex, final int wordCursor,
                            final int cursor, final String openingQuote,
                            final int rawWordCursor, final int rawWordLength) {
            this.line = line;
            this.words = Collections.unmodifiableList(Objects.requireNonNull(words));
            this.wordIndex = wordIndex;
            this.wordCursor = wordCursor;
            this.cursor = cursor;
            this.openingQuote = openingQuote;
            this.rawWordCursor = rawWordCursor;
            this.rawWordLength = rawWordLength;
        }

        public int wordIndex() {
            return this.wordIndex;
        }

        public String word() {
            // TODO: word() should always be contained in words()
            if ((wordIndex < 0) || (wordIndex >= words.size())) {
                return "";
            }
            return words.get(wordIndex);
        }

        public int wordCursor() {
            return this.wordCursor;
        }

        public List<String> words() {
            return this.words;
        }

        public int cursor() {
            return this.cursor;
        }

        public String line() {
            return line;
        }

        public CharSequence escape(CharSequence candidate, boolean complete) {
            StringBuilder sb = new StringBuilder(candidate);
            Predicate<Integer> needToBeEscaped;
            String quote = openingQuote;
            boolean middleQuotes = false;
            if (openingQuote==null) {
                for (int i=0; i < sb.length(); i++) {
                    if (isQuoteChar(sb, i)) {
                        middleQuotes = true;
                        break;
                    }
                }
            }
            if (escapeChars != null) {
                if (escapeChars.length > 0) {
                    // Completion is protected by an opening quote:
                    // Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does.
                    // Also, close the quote at the end
                    if (openingQuote != null) {
                        needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote);
                    }
                    // Completion is protected by middle quotes:
                    // Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does.
                    else if (middleQuotes) {
                        needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i));
                    }
                    // No quote protection, need to escape everything: delimiter chars (spaces), quote chars
                    // and escapes themselves
                    else {
                        needToBeEscaped = i -> isDelimiterChar(sb, i) || isRawEscapeChar(sb.charAt(i))
                                || isRawQuoteChar(sb.charAt(i));
                    }
                    for (int i = 0; i < sb.length(); i++) {
                        if (needToBeEscaped.test(i)) {
                            sb.insert(i++, escapeChars[0]);
                        }
                    }
                }
            } else if (openingQuote == null && !middleQuotes) {
                for (int i = 0; i < sb.length(); i++) {
                    if (isDelimiterChar(sb, i)) {
                        quote = "'";
                        break;
                    }
                }
            }
            if (quote != null) {
                sb.insert(0, quote);
                if (complete) {
                    sb.append(quote);
                }
            }
            return sb;
        }

        @Override
        public int rawWordCursor() {
            return rawWordCursor;
        }

        @Override
        public int rawWordLength() {
            return rawWordLength;
        }
    }

}

jdk/internal/org/jline/reader/impl/DefaultParser.java

 

Or download all of them as a single archive file:

File name: jdk.internal.le-17.0.5-src.zip
File size: 231458 bytes
Release date: 2022-09-13
Download 

 

JDK 17 jdk.internal.opt.jmod - Internal Opt Module

JDK 17 jdk.internal.jvmstat.jmod - Internal JVM Stat Module

JDK 17 JMod/Module Files

⇑⇑ FAQ for JDK (Java Development Kit) 17

2023-08-25, 3965👍, 0💬