Example usage for org.eclipse.jdt.internal.compiler.parser ScannerHelper OBVIOUS_IDENT_CHAR_NATURES

List of usage examples for org.eclipse.jdt.internal.compiler.parser ScannerHelper OBVIOUS_IDENT_CHAR_NATURES

Introduction

In this page you can find the example usage for org.eclipse.jdt.internal.compiler.parser ScannerHelper OBVIOUS_IDENT_CHAR_NATURES.

Prototype

null OBVIOUS_IDENT_CHAR_NATURES

To view the source code for org.eclipse.jdt.internal.compiler.parser ScannerHelper OBVIOUS_IDENT_CHAR_NATURES.

Click Source Link

Usage

From source file:com.codenvy.ide.ext.java.server.internal.core.search.StringOperation.java

License:Open Source License

/**
 * Answers all the regions in a given name matching a given camel case pattern.
 * </p><p>/*from  w  ww  .  j a va  2s.  co m*/
 * Each of these regions is made of its starting index and its length in the given
 * name. They are all concatenated in a single array of <code>int</code>
 * which therefore always has an even length.
 * </p><p>
 * Note that each region is disjointed from the following one.<br>
 * E.g. if the regions are <code>{ start1, length1, start2, length2 }</code>,
 * then <code>start1+length1</code> will always be smaller than
 * <code>start2</code>.
 * </p><p>
 * <pre>
 * Examples:
 * <ol><li>  pattern = "NPE"
 *  name = NullPointerException / NoPermissionException
 *  result:  { 0, 1, 4, 1, 11, 1 } / { 0, 1, 2, 1, 12, 1 } </li>
 * <li>  pattern = "NuPoEx"
 *  name = NullPointerException
 *  result:  { 0, 2, 4, 2, 11, 2 }</li>
 * <li>  pattern = "IPL3"
 *  name = "IPerspectiveListener3"
 *  result:  { 0, 2, 12, 1, 20, 1 }</li>
 * <li>  pattern = "HashME"
 *  name = "HashMapEntry"
 *  result:  { 0, 5, 7, 1 }</li>
 * </ol></pre>
 *</p>
 * @see org.eclipse.jdt.core.compiler.CharOperation#camelCaseMatch(char[], int, int, char[], int, int, boolean)
 *    for more details on the camel case behavior
 * @see org.eclipse.jdt.core.compiler.CharOperation#match(char[], char[], boolean) for more details on the
 *    pattern match behavior
 *
 * @param pattern the given pattern
 * @param patternStart the start index of the pattern, inclusive
 * @param patternEnd the end index of the pattern, exclusive
 * @param name the given name
 * @param nameStart the start index of the name, inclusive
 * @param nameEnd the end index of the name, exclusive
 * @param samePartCount flag telling whether the pattern and the name should
 *    have the same count of parts or not.<br>
 *    &nbsp;&nbsp;For example:
 *    <ul>
 *       <li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
 *             but not 'HashMapEntry'</li>
 *       <li>'HMap' type string pattern will still match previous 'HashMap' and
 *             'HtmlMapper' types, but not 'HighMagnitude'</li>
 *    </ul>
 * @return an array of <code>int</code> having two slots per returned
 *    regions (first one is the starting index of the region and the second
 *    one the length of the region).<br>
 *    Note that it may be <code>null</code> if the given name does not match
 *    the pattern
 * @since 3.5
 */
public static final int[] getCamelCaseMatchingRegions(String pattern, int patternStart, int patternEnd,
        String name, int nameStart, int nameEnd, boolean samePartCount) {

    /* !!!!!!!!!! WARNING !!!!!!!!!!
     * The algorithm used in this method has been fully inspired from
     * CharOperation#camelCaseMatch(char[], int, int, char[], int, int, boolean).
     *
     * So, if any change needs to be applied in the algorithm, do NOT forget
     * to backport it in the CharOperation method!
     */

    if (name == null)
        return null; // null name cannot match
    if (pattern == null) {
        // null pattern cannot match any region
        // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=264816
        return EMPTY_REGIONS;
    }
    if (patternEnd < 0)
        patternEnd = pattern.length();
    if (nameEnd < 0)
        nameEnd = name.length();

    if (patternEnd <= patternStart) {
        return nameEnd <= nameStart ? new int[] { patternStart, patternEnd - patternStart } : null;
    }
    if (nameEnd <= nameStart)
        return null;
    // check first pattern char
    if (name.charAt(nameStart) != pattern.charAt(patternStart)) {
        // first char must strictly match (upper/lower)
        return null;
    }

    char patternChar, nameChar;
    int iPattern = patternStart;
    int iName = nameStart;

    // init segments
    int parts = 1;
    for (int i = patternStart + 1; i < patternEnd; i++) {
        final char ch = pattern.charAt(i);
        if (ch < ScannerHelper.MAX_OBVIOUS) {
            if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[ch]
                    & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_DIGIT)) != 0) {
                parts++;
            }
        } else if (Character.isJavaIdentifierPart(ch) && (Character.isUpperCase(ch) || Character.isDigit(ch))) {
            parts++;
        }
    }
    int[] segments = null;
    int count = 0; // count

    // Main loop is on pattern characters
    int segmentStart = iName;
    while (true) {
        iPattern++;
        iName++;

        if (iPattern == patternEnd) { // we have exhausted pattern...
            // it's a match if the name can have additional parts (i.e. uppercase characters) or is also exhausted
            if (!samePartCount || iName == nameEnd) {
                if (segments == null) {
                    segments = new int[2];
                }
                segments[count++] = segmentStart;
                segments[count++] = iName - segmentStart;
                if (count < segments.length) {
                    System.arraycopy(segments, 0, segments = new int[count], 0, count);
                }
                return segments;
            }

            // otherwise it's a match only if the name has no more uppercase characters
            int segmentEnd = iName;
            while (true) {
                if (iName == nameEnd) {
                    // we have exhausted the name, so it's a match
                    if (segments == null) {
                        segments = new int[2];
                    }
                    segments[count++] = segmentStart;
                    segments[count++] = segmentEnd - segmentStart;
                    if (count < segments.length) {
                        System.arraycopy(segments, 0, segments = new int[count], 0, count);
                    }
                    return segments;
                }
                nameChar = name.charAt(iName);
                // test if the name character is uppercase
                if (nameChar < ScannerHelper.MAX_OBVIOUS) {
                    if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar]
                            & ScannerHelper.C_UPPER_LETTER) != 0) {
                        return null;
                    }
                } else if (!Character.isJavaIdentifierPart(nameChar) || Character.isUpperCase(nameChar)) {
                    return null;
                }
                iName++;
            }
        }

        if (iName == nameEnd) {
            // We have exhausted the name (and not the pattern), so it's not a match
            return null;
        }

        // For as long as we're exactly matching, bring it on (even if it's a lower case character)
        if ((patternChar = pattern.charAt(iPattern)) == name.charAt(iName)) {
            continue;
        }
        int segmentEnd = iName;

        // If characters are not equals, then it's not a match if patternChar is lowercase
        if (patternChar < ScannerHelper.MAX_OBVIOUS) {
            if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar]
                    & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_DIGIT)) == 0) {
                return null;
            }
        } else if (Character.isJavaIdentifierPart(patternChar) && !Character.isUpperCase(patternChar)
                && !Character.isDigit(patternChar)) {
            return null;
        }

        // patternChar is uppercase, so let's find the next uppercase in name
        while (true) {
            if (iName == nameEnd) {
                //   We have exhausted name (and not pattern), so it's not a match
                return null;
            }

            nameChar = name.charAt(iName);
            if (nameChar < ScannerHelper.MAX_OBVIOUS) {
                int charNature = ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar];
                if ((charNature & (ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_SPECIAL)) != 0) {
                    // nameChar is lowercase
                    iName++;
                } else if ((charNature & ScannerHelper.C_DIGIT) != 0) {
                    // nameChar is digit => break if the digit is current pattern character otherwise consume it
                    if (patternChar == nameChar)
                        break;
                    iName++;
                    // nameChar is uppercase...
                } else if (patternChar != nameChar) {
                    //.. and it does not match patternChar, so it's not a match
                    return null;
                } else {
                    //.. and it matched patternChar. Back to the big loop
                    break;
                }
            }
            // Same tests for non-obvious characters
            else if (Character.isJavaIdentifierPart(nameChar) && !Character.isUpperCase(nameChar)) {
                iName++;
            } else if (Character.isDigit(nameChar)) {
                if (patternChar == nameChar)
                    break;
                iName++;
            } else if (patternChar != nameChar) {
                return null;
            } else {
                break;
            }
        }
        // At this point, either name has been exhausted, or it is at an uppercase letter.
        // Since pattern is also at an uppercase letter
        if (segments == null) {
            segments = new int[parts * 2];
        }
        segments[count++] = segmentStart;
        segments[count++] = segmentEnd - segmentStart;
        segmentStart = iName;
    }
}

From source file:org.eclipse.jdt.internal.compiler.parser.Parser.java

License:Open Source License

/**
 * Look for a specific tag comment leading a given source range (comment located after any statement in astStack)
 * @param rangeEnd int/*w ww  . jav  a  2  s .  c  om*/
 * @return boolean
 */
public boolean hasLeadingTagComment(char[] commentPrefixTag, int rangeEnd) {
    int iComment = this.scanner.commentPtr;
    if (iComment < 0)
        return false; // no comment available
    int iStatement = this.astLengthPtr;
    if (iStatement < 0 || this.astLengthStack[iStatement] <= 1)
        return false; // no statement available
    // Fallthrough comment must be located after the previous statement
    ASTNode lastNode = this.astStack[this.astPtr];
    int rangeStart = lastNode.sourceEnd;
    previousComment: for (; iComment >= 0; iComment--) {
        int commentStart = this.scanner.commentStarts[iComment];
        if (commentStart < 0)
            commentStart = -commentStart; // line comments have negative start positions
        // ignore comments before start
        if (commentStart < rangeStart)
            return false; // no more comments in range
        // ignore comments after end
        if (commentStart > rangeEnd)
            continue previousComment;
        // found last comment in range - only check the last comment in range
        char[] source = this.scanner.source;
        int charPos = commentStart + 2; // skip // or /*
        // tag can be leaded by optional spaces
        for (; charPos < rangeEnd; charPos++) {
            char c = source[charPos];
            if (c >= ScannerHelper.MAX_OBVIOUS
                    || (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_JLS_SPACE) == 0) {
                break;
            }
        }
        for (int iTag = 0, length = commentPrefixTag.length; iTag < length; iTag++, charPos++) {
            if (charPos >= rangeEnd)
                return false; // comment is too small to host tag
            if (source[charPos] != commentPrefixTag[iTag])
                return false;
        }
        return true;
    }
    return false;
}